Author: dylan
Date: 2004-08-22 00:18:11 -0400 (Sun, 22 Aug 2004)
New Revision: 355
Added:
trunk/main/server/lib/SslClient.pm
trunk/main/server/lib/SslServer.pm
trunk/main/server/plain-cert.pem
trunk/main/server/plain-rsa.pem
Modified:
trunk/main/server/lib/Haver/Server/POE.pm
trunk/main/server/lib/Haver/Server/POE/Commands.pm
trunk/main/server/lib/Haver/Server/POE/Connection.pm
trunk/main/server/lib/Haver/Server/POE/Listener.pm
Log:
SSL support added. Currently it's a hack.
But it'll get better.
Modified: trunk/main/server/lib/Haver/Server/POE/Commands.pm
===================================================================
--- trunk/main/server/lib/Haver/Server/POE/Commands.pm 2004-08-21 03:23:54 UTC
(rev 354)
+++ trunk/main/server/lib/Haver/Server/POE/Commands.pm 2004-08-22 04:18:11 UTC
(rev 355)
@@ -27,7 +27,7 @@
use Haver::Preprocessor;
use Digest::SHA1 qw(sha1_base64);
-use Haver::Util::Misc ();
+use Haver::Formats qw( :datetime );
use Haver::Server::Registry qw( $Registry );
@@ -67,11 +67,18 @@
sub cmd_HAVER {
my ($kernel, $heap, $args) = @_[KERNEL, HEAP, ARG0];
my $client = $args->[0];
-
- return if exists $heap->{client};
-
- $heap->{socket}->put(['HAVER',
"Haver::Server::POE/$Haver::Server::POE::VERSION"]);
- $heap->{client} = $client;
+
+ if (exists $heap->{version}) {
+ $kernel->yield('oops', "haver");
+ return;
+ }
+
+ eval {
+ $heap->{client}->put(['HAVER',
+ "Haver::Server::POE/$Haver::Server::POE::VERSION",
+ ]);
+ };
+ $heap->{version} = $client;
$kernel->yield('want', 'IDENT');
}
@@ -80,7 +87,10 @@
my ($id, $ns) = @$args;
$ns ||= 'user';
- return if $heap->{login};
+ if ($heap->{login}) {
+ $kernel->yield('oops', "ident");
+ return;
+ }
if ($ns ne 'user') {
$kernel->yield('fail', 'IDENT', 'unsupported.ns', [$ns]);
@@ -101,11 +111,11 @@
} else {
my $user = new Haver::Server::Object::User(
id => $id,
- wheel => $heap->{socket},
+ wheel => $heap->{client},
sid => $_[SESSION]->ID,
);
$user->set(
- Client => $heap->{client},
+ Client => $heap->{version},
Rank => 0,
Role => 'User',
_info => [qw( Rank Role Client IP Login Idle
)],
@@ -116,7 +126,7 @@
# This really shouldn't ever happen.
my $t = localtime;
$kernel->post('Logger', 'error', "<$t>
Error loading ${id}: $@");
- $kernel->yield('die', 'impossible',
[$t]);
+ $kernel->yield('oops', 'impossible',
[$t]);
return;
}
$kernel->yield('auth', $id, $user);
@@ -136,11 +146,11 @@
if (my $code = delete $heap->{want_data}{code}) {
$code->($kernel, $heap);
} else {
- $kernel->yield('die', 'cant', [$want]);
+ $kernel->yield('oops', 'cant', [$want]);
}
$heap->{want} = undef;
} else {
- $kernel->yield('die', 'cant.insane' => [$want, $heap->{want}]);
+ $kernel->yield('oops', 'cant.insane' => [$want, $heap->{want}]);
}
}
@@ -261,14 +271,14 @@
my $user = check_id($ns, $id, 'LINFO', [$ns, $id], 'id') or
return;
my @keys = @{ $user->get('_info') };
my @out = (@m, 'INFO', $cid, $ns, $id, map { ($_ =>
$user->get($_)) } @keys);
- $heap->{socket}->put([EMAIL PROTECTED]);
+ $heap->{client}->put([EMAIL PROTECTED]);
} else {
foreach my $obj ($chan->contents($ns)) {
my @keys = @{ $obj->get('_info') };
my @out = (@m, 'INFO', $cid, $ns, $obj->id, map { ($_
=> $obj->get($_)) } @keys);
- $heap->{socket}->put([EMAIL PROTECTED]);
+ $heap->{client}->put([EMAIL PROTECTED]);
}
- $heap->{socket}->put(['END', 'INFO']);
+ $heap->{client}->put(['END', 'INFO']);
}
}
@@ -282,6 +292,8 @@
$ns = $cid;
$cid = '&';
$chan = $Registry;
+ } elsif ($cid eq '&') {
+ $chan = $Registry;
} else {
$chan = check_cid($cid, 'LIST') or return;
}
@@ -290,7 +302,7 @@
my @list = ('LIST', $cid, $ns, map { $_->id } $chan->contents($ns));
- $heap->{socket}->put([EMAIL PROTECTED]);
+ $heap->{client}->put([EMAIL PROTECTED]);
}
sub cmd_POKE {
@@ -298,8 +310,8 @@
my ($data) = @$args;
my $now = time;
- my $datetime = Haver::Util::Misc::format_datetime($now);
- $heap->{socket}->put(['OUCH', $datetime, $data ? $data : () ]);
+ my $datetime = format_datetime($now);
+ $heap->{client}->put(['OUCH', $datetime, $data ? $data : () ]);
}
Modified: trunk/main/server/lib/Haver/Server/POE/Connection.pm
===================================================================
--- trunk/main/server/lib/Haver/Server/POE/Connection.pm 2004-08-21
03:23:54 UTC (rev 354)
+++ trunk/main/server/lib/Haver/Server/POE/Connection.pm 2004-08-22
04:18:11 UTC (rev 355)
@@ -32,6 +32,8 @@
use Haver::Protocol;
use Haver::Server::POE::Commands;
use Haver::Server::Registry qw( $Registry );
+use Haver::Formats qw( :duration );
+
use Scalar::Util ();
use Digest::SHA1 qw( sha1_base64 );
our $RELOAD = 1;
@@ -62,10 +64,11 @@
cleanup => 'on_cleanup',
'shutdown' => 'on_shutdown',
'fail' => 'on_fail',
- 'die' => 'on_die',
+ 'oops' => 'on_oops',
'accept' => 'on_accept',
auth => 'on_auth',
unknown_cmd => 'on_unknown_cmd',
+ close => 'on_close',
},
$commands => $commands->commands,
],
@@ -83,8 +86,9 @@
$kernel->post('Logger', 'note', "Connection from ${address}:$port");
- binmode $socket, ":utf8";
- my $sock = new POE::Wheel::ReadWrite(
+ ## breaks ssl.
+ #binmode $socket, ":utf8";
+ my $client = new POE::Wheel::ReadWrite(
Handle => $socket,
Driver => new POE::Driver::SysRW,
Filter => new POE::Filter::Haver,
@@ -104,7 +108,8 @@
address => $address,
port => $port,
timer => $timer,
- socket => $sock,
+ client => $client,
+ sock => $socket,
shutdown => 0,
plonk => 0,
want => undef,
@@ -170,7 +175,7 @@
$want = 1;
$heap->{want} = undef;
} else {
- $kernel->yield('die', 'WANT', [$heap->{want}, $cmd]);
+ $kernel->yield('oops', 'WANT', [$heap->{want}, $cmd]);
return;
}
}
@@ -179,7 +184,7 @@
$heap->{scope} = {};
$kernel->yield("cmd_$cmd", $args);
} else {
- $heap->{socket} = undef;
+ $heap->{client} = undef;
$kernel->yield('cleanup', 'SPEEDY');
}
}
@@ -188,33 +193,49 @@
my ($kernel, $heap) = @_[KERNEL, HEAP];
if ($heap->{shutdown}) {
- $heap->{socket} = undef;
+ $kernel->yield('close');
}
}
+
+
sub socket_error {
my ($kernel, $heap, $operation, $errnum, $errstr) = @_[KERNEL, HEAP,
ARG0..ARG3];
$kernel->post('Logger', 'error',
"Socket generated $operation error ${errnum}: $errstr");
- $heap->{socket} = undef;
+
+ $kernel->yield('close');
$kernel->yield('cleanup', 'DISCON');
}
+sub on_close {
+ my ($kernel, $heap) = @_[KERNEL, HEAP];
+ $kernel->post('Logger', 'note', "Closing client connection: "
+ . fileno($heap->{client}[0]));
+ $kernel->post('Logger', 'note', "Socket: $heap->{sock}");
+
+ my $sock = delete $heap->{sock};
+ #close $sock;
+ #untie $sock;
+ $heap->{client} = undef;
+ #close $sock if $t;
+ #untie *$sock;
+}
+
sub on_unknown_cmd {
my ($kernel, $heap, $event, $args) = @_[KERNEL, HEAP, ARG0, ARG1];
-
- $heap->{socket}->put(['WARN', 'unknown.command', $event]);
+ $heap->{client}->put(['FAIL', $event, 'unknown.command']);
}
sub on_shutdown {
my ($kernel, $heap, $session, @args) = @_[KERNEL, HEAP, SESSION, ARG0
.. $#_];
return if $heap->{shutdown};
- eval { $heap->{socket}->put(['BYE', @args]) };
+ eval { $heap->{client}->put(['BYE', @args]) };
$heap->{shutdown} = 1;
$kernel->yield('cleanup', @args);
}
@@ -226,7 +247,7 @@
#$want = uc $want;
$kernel->post('Logger', 'note', "Want: $want");
- unless ($heap->{socket}) {
+ unless ($heap->{client}) {
my ($file, $line) = @_[CALLER_FILE,CALLER_LINE];
$kernel->post('Logger', 'error', "on_want called with undefined
socket at $file line $line!");
return;
@@ -238,7 +259,7 @@
}
my @args = $opts{args} ? @{$opts{args}} : ();
- $heap->{socket}->put(['WANT', $want, @args]);
+ $heap->{client}->put(['WANT', $want, @args]);
}
sub on_cleanup {
@@ -263,6 +284,7 @@
push(@users, $chan->list_ids('user'));
}
my %users = map { ($_ => $_) } @users;
+ delete $users{$uid};
my $msg = ['QUIT', $uid, @args];
$kernel->post('Broadcaster', 'send', [ keys %users ],
$msg);
}
@@ -274,7 +296,7 @@
}
}
-sub on_die {
+sub on_oops {
my ($kernel, $heap, $err, $data) = @_[KERNEL, HEAP, ARG0 .. $#_];
if (not defined $data) {
@@ -285,8 +307,8 @@
$data = [$data];
}
- eval { $heap->{socket}->put(['DIE', $err, @$data]) };
- $kernel->yield('shutdown', 'DIE');
+ eval { $heap->{client}->put(['OOPS', $err, @$data]) };
+ $kernel->yield('shutdown', 'OOPS');
}
sub on_fail {
my ($kernel, $heap, $cmd, $err, $data) = @_[KERNEL, HEAP, ARG0 .. $#_];
@@ -300,7 +322,7 @@
}
$kernel->post('Logger', 'fail', "failing $heap->{uid} with $cmd -
$err");
- eval { $heap->{socket}->put(['FAIL', $cmd, $err, @$data]) };
+ eval { $heap->{client}->put(['FAIL', $cmd, $err, @$data]) };
}
sub on_accept {
@@ -317,25 +339,25 @@
$user->set(
IP => $addr,
Login => sub {
- time - $login_time;
+ format_duration(time - $login_time);
},
_last => time,
Idle => sub {
my ($u) = @_;
- time - $u->get('_last');
+ format_duration(time - $u->get('_last'));
},
'.IP' => $heap->{address},
);
delete $heap->{want_data};
$heap->{login} = 1;
- $heap->{socket}->put(['ACCEPT', $uid]);
+ $heap->{client}->put(['ACCEPT', $uid]);
}
sub on_auth {
my ($kernel, $heap, $uid, $user) = @_[KERNEL, HEAP, ARG0, ARG1];
$kernel->yield('want', 'AUTH',
- args => ['pass,fake'],
+ args => ['PASS', 'FAKE'],
uid => $uid,
user => $user,
);
Modified: trunk/main/server/lib/Haver/Server/POE/Listener.pm
===================================================================
--- trunk/main/server/lib/Haver/Server/POE/Listener.pm 2004-08-21 03:23:54 UTC
(rev 354)
+++ trunk/main/server/lib/Haver/Server/POE/Listener.pm 2004-08-22 04:18:11 UTC
(rev 355)
@@ -65,7 +65,7 @@
return unless $ifaces;
foreach my $i (@$ifaces) {
- $kernel->yield('listen', $i->{host}, $i->{port});
+ $kernel->yield('listen', $i);
}
}
@@ -90,27 +90,56 @@
}
sub listen {
- my ($kernel, $heap, $host, $port) = @_[KERNEL, HEAP, ARG0, ARG1];
- $kernel->post('Logger', 'note', "Listening on port $port.");
+ my ($kernel, $heap, $iface) = @_[KERNEL, HEAP, ARG0, ARG1];
+ my $s = '';
+ if ($iface->{ssl}) {
+ $s = ' (ssl!)';
+ }
+
+ $kernel->post('Logger', 'note', "Listening on port $iface->{port}.$s");
+
my $wheel = POE::Wheel::SocketFactory->new(
- BindPort => $port,
+ BindPort => $iface->{port},
Reuse => 1,
SuccessEvent => 'socket_birth',
FailureEvent => 'socket_fail',
);
$heap->{conn}{$wheel->ID} = {
wheel => $wheel,
- host => $host,
- port => $port,
+ host => $iface->{host},
+ port => $iface->{port},
+ ssl => $iface->{ssl},
};
}
sub socket_birth {
- my ($kernel, $heap, $socket, $address, $port) = @_[KERNEL, HEAP, ARG0,
ARG1, ARG2];
+ my ($kernel, $heap, $socket, $address, $port, $wid) =
+ @_[KERNEL, HEAP, ARG0, ARG1, ARG2, ARG3];
+
+
+ if ($heap->{conn}{$wid}{ssl}) {
+ # DEBUG: "Doing ssl";
+ # BEGIN MAKE SSL
+ use Symbol qw(gensym);
+ use SslServer;
+
+ my $old_socket = $socket;
+ $socket = gensym();
+ tie( *$socket,
+ "SslServer",
+ $old_socket,
+ "./plain-rsa.pem",
+ "./plain-cert.pem",
+ ) or die $!;
+ # CEASE MAKE SSL
+ print "Filenos: ", $old_socket, ", ", tied(*$socket), "\n";
+ $socket = \*$socket;
+ }
+
Haver::Server::POE::Connection->create(
sock => $socket,
address => $address,
Modified: trunk/main/server/lib/Haver/Server/POE.pm
===================================================================
--- trunk/main/server/lib/Haver/Server/POE.pm 2004-08-21 03:23:54 UTC (rev
354)
+++ trunk/main/server/lib/Haver/Server/POE.pm 2004-08-22 04:18:11 UTC (rev
355)
@@ -46,7 +46,13 @@
},
listener => {
interfaces => [
- { port => 7071 },
+ {
+ port => 7070,
+ },
+ {
+ port => 7072,
+ ssl => 1,
+ },
]
},
broadcaster => { },
Added: trunk/main/server/lib/SslClient.pm
===================================================================
--- trunk/main/server/lib/SslClient.pm 2004-08-21 03:23:54 UTC (rev 354)
+++ trunk/main/server/lib/SslClient.pm 2004-08-22 04:18:11 UTC (rev 355)
@@ -0,0 +1,213 @@
+# $Id$
+# License and documentation are after __END__.
+
+package SslClient;
+
+use strict;
+
+use vars qw($VERSION);
+$VERSION = (qw($Revision$ ))[1];
+
+use POSIX qw(F_GETFL F_SETFL O_NONBLOCK EAGAIN EWOULDBLOCK);
+
+use Net::SSLeay qw(ERROR_WANT_READ ERROR_WANT_WRITE);
+use Net::SSLeay::Handle;
+use vars qw(@ISA);
[EMAIL PROTECTED] = qw(Net::SSLeay::Handle);
+use Carp;
+
+my %Filenum_Object;
+
+sub _get_self {
+ return $Filenum_Object{fileno(shift)};
+}
+
+sub _get_ssl {
+ my $socket = shift;
+ return $Filenum_Object{fileno($socket)}->{ssl};
+}
+
+sub _set_filenum_obj {
+ my ($self, $fileno, $ssl, $ctx, $socket, $accepted) = @_;
+ $Filenum_Object{$fileno} =
+ { ssl => $ssl,
+ ctx => $ctx,
+ #socket => $socket,
+ fileno => $fileno,
+ _is_accepted => $accepted,
+ };
+}
+
+sub TIEHANDLE {
+ my ($class, $socket, $port) = @_;
+
+ # Net::SSLeay needs nonblocking for setup.
+ my $flags = fcntl($socket, F_GETFL, 0) or die $!;
+ until (fcntl($socket, F_SETFL, $flags | O_NONBLOCK)) {
+ die $! unless $! == EAGAIN or $! == EWOULDBLOCK;
+ }
+
+ ref $socket eq "GLOB" or $socket = $class->make_socket($socket, $port);
+
+ $class->_initialize();
+
+ my $ctx = Net::SSLeay::CTX_new() or die_now("Failed to create SSL_CTX $!");
+ my $ssl = Net::SSLeay::new($ctx) or die_now("Failed to create SSL $!");
+
+ my $fileno = fileno($socket);
+
+ Net::SSLeay::set_fd($ssl, $fileno); # Must use fileno
+
+ my $connected = 0;
+ my $resp = Net::SSLeay::connect($ssl);
+ if ($resp <= 0) { # 0 is really controlled shutdown but we signal error
+ my $errno = Net::SSLeay::get_error($ssl, $resp);
+ if ($errno == ERROR_WANT_READ or $errno == ERROR_WANT_WRITE) {
+ # we try again next time in WRITE
+ }
+ else {
+ # handshake failed
+ die "handshake failed: $errno";
+ return undef;
+ }
+ }
+ else {
+ $connected = 1;
+ }
+
+ $Filenum_Object{$fileno} =
+ { ssl => $ssl,
+ ctx => $ctx,
+ socket => $socket,
+ fileno => $fileno,
+ _is_connected => $connected,
+ };
+
+ return bless $socket, $class;
+}
+
+sub READ {
+ my ($socket, $buf, $len, $offset) = \ (@_);
+ my $ssl = $$socket->_get_ssl();
+ my $self = $$socket->_get_self();
+
+ if (exists $self->{_is_accepted} && $self->{_is_accepted} == 0) {
+ my $resp = Net::SSLeay::accept($ssl);
+ if ($resp <= 0) {
+ if (Net::SSLeay::get_error($ssl, $resp) == ERROR_WANT_READ) {
+ return $$len;
+ }
+ else {
+ #confess ("handshake failed");
+ $! = 104;
+ return undef;
+ }
+ }
+ $self->{_is_accepted} = 1;
+ return $$len;
+ }
+
+ # No offset. Replace the buffer.
+ unless (defined $$offset) {
+ $$buf = Net::SSLeay::read($ssl, $$len);
+ return length($$buf) if defined $$buf;
+ $$buf = "";
+ return;
+ }
+
+ defined(my $read = Net::SSLeay::read($ssl, $$len))
+ or return undef;
+
+ my $buf_len = length($$buf);
+ $$offset > $buf_len and $$buf .= chr(0) x ($$offset - $buf_len);
+ substr($$buf, $$offset) = $read;
+ return length($read);
+}
+
+sub WRITE {
+ my $socket = shift;
+ my ($buf, $len, $offset) = @_;
+ $offset = 0 unless defined $offset;
+ my $ssl = $socket->_get_ssl();
+ my $self = $socket->_get_self();
+
+ if (exists $self->{_is_connected} && $self->{_is_connected} == 0) {
+ my $resp = Net::SSLeay::connect($ssl);
+ if ($resp <= 0) {
+ my $errno = Net::SSLeay::get_error($ssl, $resp);
+ if ($errno == ERROR_WANT_WRITE or $errno == ERROR_WANT_READ) {
+ return 0;
+ }
+ else {
+ die "handshake failed: $errno";
+ }
+ }
+ $self->{_is_connected} = 1;
+ }
+
+ # Return number of characters written.
+ my $wrote_len = Net::SSLeay::write($ssl, substr($buf, $offset, $len));
+
+ # Net::SSLeay::write() returns the number of bytes written, or -1 on
+ # error. Normal syswrite() expects 0 here.
+ return 0 if $wrote_len < 0;
+ return $wrote_len;
+}
+
+sub CLOSE {
+ print "CLOSE\n";
+ my $socket = shift;
+ my $fileno = fileno($socket);
+ return unless exists $Filenum_Object{$fileno};
+ my $self = $socket->_get_self();
+ delete $Filenum_Object{$fileno};
+ Net::SSLeay::free ($self->{ssl});
+ Net::SSLeay::CTX_free ($self->{ctx});
+ close $socket;
+}
+
+sub DESTROY {
+ print "DESTROY!!!\n";
+ shift->CLOSE;
+}
+
+1;
+
+__END__
+
+=head1 NAME
+
+POE::Component::Client::HTTP::SSL - non-blocking SSL file handles
+
+=head1 SYNOPSIS
+
+ See Net::SSLeay::Handle
+
+=head1 DESCRIPTION
+
+This is a temporary subclass of Net::SSLeay::Handle with what I
+consider proper read() and sysread() semantics. This module will go
+away if or when Net::SSLeay::Handle adopts these semantics.
+
+POE::Component::Client::HTTP::SSL functions identically to
+Net::SSLeay::Handle, but the READ function does not block until LENGTH
+bytes are read.
+
+=head1 SEE ALSO
+
+Net::SSLeay::Handle
+
+=head1 BUGS
+
+None known.
+
+=head1 AUTHOR & COPYRIGHTS
+
+POE::Component::Client::HTTP::SSL is Copyright 1999-2002 by Rocco
+Caputo. All rights are reserved. This module is free software; you
+may redistribute it and/or modify it under the same terms as Perl
+itself.
+
+Rocco may be contacted by e-mail via [EMAIL PROTECTED]
+
+=cut
Added: trunk/main/server/lib/SslServer.pm
===================================================================
--- trunk/main/server/lib/SslServer.pm 2004-08-21 03:23:54 UTC (rev 354)
+++ trunk/main/server/lib/SslServer.pm 2004-08-22 04:18:11 UTC (rev 355)
@@ -0,0 +1,115 @@
+# $Id$
+# License and documentation are after __END__.
+
+package SslServer;
+
+use warnings;
+use strict;
+
+use Carp qw(croak);
+
+use vars qw($VERSION);
+$VERSION = (qw($Revision$ ))[1];
+
+use SslClient;
+use vars qw(@ISA);
[EMAIL PROTECTED] = qw(SslClient);
+
+use Net::SSLeay qw(die_if_ssl_error ERROR_WANT_READ ERROR_WANT_WRITE);
+use POSIX qw(F_GETFL F_SETFL O_NONBLOCK EAGAIN EWOULDBLOCK);
+
+sub TIEHANDLE {
+ my ($class, $socket, $key, $cert) = @_;
+
+ # Validate the certificate.
+ croak "no such file: $cert" unless -f $cert;
+ croak "can't read file: $cert" unless -R $cert;
+
+ # Net::SSLeay needs nonblocking for setup.
+ my $flags = fcntl($socket, F_GETFL, 0) or die $!;
+ until (fcntl($socket, F_SETFL, $flags | O_NONBLOCK)) {
+ die $! unless $! == EAGAIN or $! == EWOULDBLOCK;
+ }
+
+ $class->_initialize();
+
+ my $ctx = Net::SSLeay::CTX_new() or die_now("Failed to create SSL_CTX $!");
+ my $ssl = Net::SSLeay::new($ctx) or die_now("Failed to create SSL $!");
+
+ my $fileno = fileno($socket);
+
+ Net::SSLeay::set_fd($ssl, $fileno); # Must use fileno
+
+ Net::SSLeay::use_RSAPrivateKey_file( $ssl,
+ $key,
+ &Net::SSLeay::FILETYPE_PEM
+ );
+ die_if_ssl_error("private key");
+ Net::SSLeay::use_certificate_file( $ssl,
+ $cert,
+ &Net::SSLeay::FILETYPE_PEM
+ );
+ die_if_ssl_error("certificate");
+
+ my $accepted = 0;
+ my $resp = Net::SSLeay::accept($ssl);
+ if ($resp <= 0) { # 0 is really controlled shutdown but we signal error
+ my $errno = Net::SSLeay::get_error($ssl, $resp);
+ if ($errno == ERROR_WANT_READ or $errno == ERROR_WANT_WRITE) {
+ # we try again next time in READ
+ }
+ else {
+ # handshake failed
+ die "handshake failed: $errno";
+ return undef;
+ }
+ }
+ else {
+ $accepted = 1;
+ }
+
+ $class->_set_filenum_obj($fileno, $ssl, $ctx, $socket, $accepted);
+
+ return bless $socket, $class;
+}
+
+1;
+
+__END__
+
+=head1 NAME
+
+POE::Component::Client::HTTP::SSL - non-blocking SSL file handles
+
+=head1 SYNOPSIS
+
+ See Net::SSLeay::Handle
+
+=head1 DESCRIPTION
+
+This is a temporary subclass of Net::SSLeay::Handle with what I
+consider proper read() and sysread() semantics. This module will go
+away if or when Net::SSLeay::Handle adopts these semantics.
+
+POE::Component::Client::HTTP::SSL functions identically to
+Net::SSLeay::Handle, but the READ function does not block until LENGTH
+bytes are read.
+
+=head1 SEE ALSO
+
+Net::SSLeay::Handle
+
+=head1 BUGS
+
+None known.
+
+=head1 AUTHOR & COPYRIGHTS
+
+POE::Component::Client::HTTP::SSL is Copyright 1999-2002 by Rocco
+Caputo. All rights are reserved. This module is free software; you
+may redistribute it and/or modify it under the same terms as Perl
+itself.
+
+Rocco may be contacted by e-mail via [EMAIL PROTECTED]
+
+=cut
Added: trunk/main/server/plain-cert.pem
===================================================================
--- trunk/main/server/plain-cert.pem 2004-08-21 03:23:54 UTC (rev 354)
+++ trunk/main/server/plain-cert.pem 2004-08-22 04:18:11 UTC (rev 355)
@@ -0,0 +1,17 @@
+-----BEGIN CERTIFICATE-----
+MIICqTCCAhICAQAwDQYJKoZIhvcNAQEEBQAwgZwxCzAJBgNVBAYTAlhYMRQwEgYD
+VQQIEwtOZXQ6OlNTTGVheTESMBAGA1UEBxMJdGVzdCBsYW5kMRIwEAYDVQQKEwlU
+ZXN0IENpdHkxITAfBgNVBAsTGE5ldDo6U1NMZWF5IE9yZ2FuaXphdGlvbjESMBAG
+A1UEAxMJVGVzdCBVbml0MRgwFgYJKoZIhvcNAQkBFgkxMjcuMC4wLjEwHhcNMDQw
+ODIxMDQzNzI2WhcNMTQwODE5MDQzNzI2WjCBnDELMAkGA1UEBhMCWFgxFDASBgNV
+BAgTC05ldDo6U1NMZWF5MRIwEAYDVQQHEwl0ZXN0IGxhbmQxEjAQBgNVBAoTCVRl
+c3QgQ2l0eTEhMB8GA1UECxMYTmV0OjpTU0xlYXkgT3JnYW5pemF0aW9uMRIwEAYD
+VQQDEwlUZXN0IFVuaXQxGDAWBgkqhkiG9w0BCQEWCTEyNy4wLjAuMTCBnzANBgkq
+hkiG9w0BAQEFAAOBjQAwgYkCgYEA6OAVreLmph9H5+IH0J+oDC9S+gTTpM6+fFcI
+slDgz/E4fclb+MHT/rGwnpqda5p2H6AUww/BkptTdWztjVJBA5q13tJpKzRi24S5
+h9ROyem7gQfzxdtUnL8eWqqrV1fUKWNHOuunjV/PFXLM/H1kdf2tdYGa03P7aLqc
+psBK/nMCAwEAATANBgkqhkiG9w0BAQQFAAOBgQCjC6lIUac3Fg7mY60MTs8faWG4
+vECP65rLIY/IhFO3NOUCnY54gOobtYR2NdEjJFnG8f06SaQysUUOlDGt808L2b8C
++Ww2AxDfyp5XIM2asGGe4l1f+eeNM26I4rYJJPVNOrh8jxxp363aoC/n6PKDZ/Ka
+diGO1T/g/6ApRdEioQ==
+-----END CERTIFICATE-----
Added: trunk/main/server/plain-rsa.pem
===================================================================
--- trunk/main/server/plain-rsa.pem 2004-08-21 03:23:54 UTC (rev 354)
+++ trunk/main/server/plain-rsa.pem 2004-08-22 04:18:11 UTC (rev 355)
@@ -0,0 +1,15 @@
+-----BEGIN RSA PRIVATE KEY-----
+MIICXAIBAAKBgQDo4BWt4uamH0fn4gfQn6gML1L6BNOkzr58VwiyUODP8Th9yVv4
+wdP+sbCemp1rmnYfoBTDD8GSm1N1bO2NUkEDmrXe0mkrNGLbhLmH1E7J6buBB/PF
+21Scvx5aqqtXV9QpY0c666eNX88Vcsz8fWR1/a11gZrTc/toupymwEr+cwIDAQAB
+AoGAKsSctqapPXEZP5jfXo0zy6kVUB160RW3HhbN3hHEd+wRN+i3H2RZjrkLetVi
+e9SORRidN4W5QzeLiFFM/1tP3QPirV1kRIrFZSmpXZZGhzME0LxGLyrqDrAqBWVR
+v2GoBQL/zDboUYTFvNAx9VjfVCNQa7gObImZpL1nNQPagIECQQD6S+mGwB5y8yTc
+/VmE6Zh51mEHcxs8yHuQrzl6Opn372bjYstbL24TJ12Gu/D+cFTPBaSvm2G9WfTm
+RD3dF1IRAkEA7i6MDW78RVnvVli9ltvCt7NcCz7T8aSDUHND6kTo3LdFdKURwC/L
+/BodYRM5YLyNWGrADL3AUzaLapgqtyREQwJBALxdbuTLJt8pXv+05q7hQa/Hh4Qc
+u03WLy/mvuHewkrV71+G1TXNjxB5GqiwPiCuFxUp0RObY0YmMektSEVgLJECQDNp
+NK3JoQZPLUwUB4hCkzsXqex7eUAVZIq+9o/go+rQXFubLcOwDXWzJVhIz//Dczb8
+g8u8QYE0qs8tXTr+xwUCQCawiEBPxogaAmjnHULk0bZNO5VVHsL4cFBMEXoZBw73
+CyFG5tPcsQb5n6UiP6CKeZWxx46fAc9MQX7HF24gVyE=
+-----END RSA PRIVATE KEY-----