Skip to content

Commit

Permalink
Added SSL support via IO::Socket::SSL
Browse files Browse the repository at this point in the history
Added P (port) lines to the configuration file
Updated INTERNALS and README to reflect the above changes
  • Loading branch information
jkominek committed Dec 13, 2000
1 parent 5e40721 commit dadc30e
Show file tree
Hide file tree
Showing 7 changed files with 93 additions and 34 deletions.
6 changes: 3 additions & 3 deletions Connection.pm
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
#
# Connection.pm
# Created: Tue Sep 15 14:26:26 1998 by [email protected]
# Revised: Thu Mar 23 16:56:38 2000 by [email protected]
# Revised: Tue Dec 12 18:13:47 2000 by [email protected]
# Copyright 1998 Jay F. Kominek ([email protected])
#
# Consult the file 'LICENSE' for the complete terms under which you
Expand All @@ -29,8 +29,8 @@ sub new {
$this->{'server'} = shift;
$this->{'connected'} = $this->{last_active} = time();

# print $this->{'socket'};
# print "\n";
$this->{'ssl'} = $this->{'socket'}->isa("IO::Socket::SSL");

my($port,$iaddr) = sockaddr_in(getpeername($this->{'socket'}));
$this->{'host'} = gethostbyaddr($iaddr,AF_INET) || inet_ntoa($iaddr);
$this->{'host_ip'} = inet_ntoa($iaddr);
Expand Down
15 changes: 10 additions & 5 deletions INTERNALS
Original file line number Diff line number Diff line change
Expand Up @@ -45,13 +45,18 @@ fail.
exiting. It then attempts to create a new session, with itself as the parent.
(This also removes any controlling tty)

Listening Socket
----------------
Listening Socket(s)
-------------------
pircd uses IO::Socket::INET to create a listening socket. The port defaults
to 6667, with a backlog of 10. Both values are changable via the command line.
If IO::Socket::INET fails to return a valid socket, pircd will log an error
message, and exit. Slightly after that, IO::Select is used to allow easy
select()ing of the sockets. The listening socket is passed to the constructor.
message, and exit.
If SSL is turned on, it will create another IO::Socket::SSL which listens.
Luckily, IO::Socket::SSL works identically to IO::Socket::INET
P: lines specify other ports to listen on. Each of these is iterated over
and a listening socket is created for it.
All listening sockets are stored in a hash as keys. All of the keys are
added to the IO::Select object

Local Server creation and Configuration file parsing
----------------------------------------------------
Expand All @@ -66,7 +71,7 @@ at the beginning, since on a system with lots of connections, we would
probably need it multiple times during that loop. We then proceed to loop
over each socket which can be read from at the moment.
{
* When the newly active socket happens to be the listening one, we seperate
* When the newly active socket happens to be a listening one, we seperate
the new socket from the listening one by accept()ing, make the new socket
non-blocking, create a new instance of Connection to represent the connection,
and add it to the right arrays.
Expand Down
13 changes: 12 additions & 1 deletion LocalServer.pm
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
#
# LocalServer.pm
# Created: Sat Sep 26 18:11:12 1998 by [email protected]
# Revised: Sat Aug 19 23:10:44 2000 by [email protected]
# Revised: Tue Dec 12 19:37:32 2000 by [email protected]
# Copyright 1998 Jay F. Kominek ([email protected])
#
# Consult the file 'LICENSE' for the complete terms under which you
Expand Down Expand Up @@ -113,6 +113,17 @@ sub loadconffile {
$this->{'opers'}->{ $nick }->{'password'} = $password;
next CONFPARSE;
}
# Port line
if($line =~ /^P:([^:]+):([^:]+)$/) {
if($2) {
# SSL socket
push @{ $this->{'sslports'} }, $1;
} else {
# Normal socket
push @{ $this->{'ports'} }, $1;
}
next CONFPARSE;
}
# Kill Line
if($line =~ /^K:([^:]+):([^:]+):([^.]+)$/) {
my($mask,$reason,$usermask) = ($1,$2,$3);
Expand Down
18 changes: 12 additions & 6 deletions README
Original file line number Diff line number Diff line change
Expand Up @@ -31,32 +31,38 @@ appropriate code via a lookup table to subroutine references, no excessively
large if..elsif..else structure, no conversion of the strings into something
that they are not (numeric values, if I remember how ircu does it).

pircd is now reasonably complete. It lacks nick history, commands based upon
nick history, /STATS output that has any relation to reality, interserver
communication, and a few finishing touches. As of this writing, it is 3115
pircd is now reasonably complete. It lacks STATS output with any relation
to reality, and interserver communication. As of this writing, it is 3810
lines long (counting comments and everything). I do not anticipate it getting
past twice that with the addition of the remaining features. (interserver
communication being the big one.)

If you would like to know more about how pircd operates internally, please
consult the included file, 'INTERNALS'.

*** SSL

pircd is the only IRC server in existance which supports SSL. As of this
writing, however, no clients support SSL. Hopefully, support for authentication
and such based on SSL certificates will be added.

*** Requirements

* Perl 5.004 and later.
* The following Perl modules:
Fcntl, Getopt::Long, IO::Select, IO::Socket,
POSIX, Sys::Syslog, Tie::RefHash, UNIVERSAL
IO::Socket::SSL if you want to use SSL
In the future, I may make use of Compress::Zlib, however
I imagine its use will be optional.
* A computer
* A port that you can bind to, preferably 6667

*** About the author

I am studying Electrical and Computer Engineering at the University of
Colorado, Boulder. I used to be available for contract programming work,
but I got a job.
I am studying Computer Science at the University of Colorado, Boulder.
I'm available and interested in one-shot programming work where I don't
have to interact with people.

An up to date list of people helping with the development of pircd can
be found at http://sourceforge.net/project/memberlist.php?group_id=671
Expand Down
11 changes: 10 additions & 1 deletion User.pm
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
#
# User.pm
# Created: Tue Sep 15 12:56:51 1998 by [email protected]
# Revised: Thu Mar 23 16:55:47 2000 by [email protected]
# Revised: Tue Dec 12 19:14:00 2000 by [email protected]
# Copyright 1998 Jay F. Kominek ([email protected])
#
# Consult the file 'LICENSE' for the complete terms under which you
Expand Down Expand Up @@ -83,6 +83,7 @@ sub new {
$this->{'ircname'} = $connection->{'ircname'};
$this->{'server'} = $connection->{'server'};
$this->{'connected'} = $connection->{'connected'};
$this->{'ssl'} = $connection->{'ssl'};
$this->{'idle_base'} =
$this->{'last_active'} = time();
$this->{'modes'} = { };
Expand Down Expand Up @@ -433,6 +434,9 @@ sub handle_whois {
if($user->islocal()) {
$this->sendnumeric($this->server,317,($user->nick,time()-$user->{'idle_base'},$user->connected),"seconds idle, signon time");
}
if($user->ssl()) {
$this->sendnumeric($this->server,342,$user->nick." is connected via SSL");
}
} else {
$this->sendnumeric($this->server,401,$target,"No suck nick");
}
Expand Down Expand Up @@ -1109,6 +1113,11 @@ sub away {
return $this->{awaymsg};
}

sub ssl {
my $this = shift;
return $this->{'ssl'};
}

# We don't want to ping someone we've already pung.
sub ping_in_air {
my $this = shift;
Expand Down
62 changes: 44 additions & 18 deletions pircd
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
#
# pircd
# Created: Mon Sep 14 12:55:01 1998 by [email protected]
# Revised: Wed Nov 22 11:07:48 2000 by [email protected]
# Revised: Tue Dec 12 19:40:07 2000 by [email protected]
# Copyright 1998 Jay F. Kominek ([email protected])
#
# Consult the file 'LICENSE' for the complete terms under which you
Expand Down Expand Up @@ -38,9 +38,13 @@ $| = 1;
# things breaking.
my %connections = ();
my %unfinished = ();
my %serversocks = ();
tie %connections, 'Tie::RefHash';
tie %unfinished, 'Tie::RefHash';
tie %serversocks, 'Tie::RefHash';
my $port = 6667;
my $sslport = 36900;
my $ssl = 0;
my $backlog = 10;
my $daemon = 0;
my $conf = "server.conf";
Expand All @@ -49,9 +53,11 @@ my $logfile = "/var/log/pircd";
# Parse the command line
use Getopt::Std;
my %opts;
getopts('dhp:b:f:l:',\%opts) || &displayhelp;
getopts('dhp:q:sb:f:l:',\%opts) || &displayhelp;
if(defined($opts{'p'})) { $port = $opts{'p'}; }
if(defined($opts{'p'})) { $sslport = $opts{'p'}; }
if(defined($opts{'b'})) { $backlog = $opts{'b'}; }
if(defined($opts{'s'})) { $ssl = 1; }
if(defined($opts{'d'})) { $daemon = 1; }
if(defined($opts{'f'})) { $conf = $opts{'f'}; }
if(defined($opts{'h'})) { &displayhelp; }
Expand All @@ -63,22 +69,41 @@ if($daemon) {
POSIX::setsid() || Utils::syslog('notice',"Cannot start a new session: $!");
}

my $server = IO::Socket::INET->new(LocalPort => $port,
Listen => $backlog,
Reuse => 1,
Proto => 'tcp');
if(!defined($server)) {
# note that 5.004 Socket.pm's _error() spooges on $!, so we use $@ here
Utils::syslog('err',"Failed to open listening socket on port $port: $@");
exit(-1);
}

my $tmp = LocalServer->new($conf);
Utils::servers()->{$tmp->name()} = $Utils::thisserver = $tmp;
$Utils::stats{highclients} = 0;
$Utils::stats{highconnections} = 0;

my $select = IO::Select->new($server);
foreach my $tmpport ($port,@{ $tmp->{'ports'} }) {
my $server = IO::Socket::INET->new(LocalPort => $tmpport,
Listen => $backlog,
Reuse => 1,
Proto => 'tcp');
if(!defined($server)) {
# note that 5.004 Socket.pm's _error() spooges on $!, so we use $@ here
Utils::syslog('err',"Failed to open listening socket on port $tmpport: $@");
exit(-1);
}
$serversocks{$server} = 1;
}

if($ssl) {
use IO::Socket::SSL;

foreach my $tmpport ($sslport,@{ $tmp->{'sslports'} }) {
my $sslserver = IO::Socket::SSL->new(LocalPort => $tmpport,
Listen => $backlog,
Reuse => 1,
Proto => 'tcp');
if(!defined($sslserver)) {
Utils::syslog('err',"Failed to open SSL listening socket on port $tmpport: $@");
exit(-1);
}
$serversocks{$sslserver} = 1;
}
}

my $select = IO::Select->new(keys %serversocks);
# While we key these on the $client's socket object, we
# don't have to iterate over them in such as way that they
# have to be RefHashes
Expand All @@ -99,12 +124,11 @@ for(;;) {
my $time;

foreach $client ($select->can_read(0.5)) {
if($client == $server) {
if($serversocks{$client}) {
# Activity on the listening socket means we have a new
# client attempting to connect.
my($iaddr,$address,$port,$peer_host,$peer_ip);
# Get ahold of the new socket, assign it to all the whatnot, etc
$client = $server->accept;
$client = $client->accept;
$select->add($client);
&setnonblocking($client);
$connections{$client} = Connection->new($client, \%outbuffer,
Expand All @@ -115,7 +139,7 @@ for(;;) {
$time = time();
$timer{$client} = $time if $timer{$client} < $time;
my($data,$got);
$got = $client->recv($data,POSIX::BUFSIZ,0);
$got = $client->sysread($data,POSIX::BUFSIZ);
unless(defined $got && length $data) {
# Aww. We had an error reading from their socket, so we have
# to cut them loose.
Expand Down Expand Up @@ -212,7 +236,7 @@ for(;;) {
# Skip it if we don't have anything available to send it.
next unless $outbuffer{$client};
# Actually attempt to send some of the data.
my $sent = $client->send($outbuffer{$client},0);
my $sent = $client->syswrite($outbuffer{$client},POSIX::BUFSIZ);
if(!defined($sent)) { next; }
# If we couldn't manage to send the whole thing, then trim what we
# did manage to send them out of the out-going buffer so we don't
Expand Down Expand Up @@ -302,6 +326,8 @@ sub setnonblocking {
sub displayhelp {
print "Usage: pircd [OPTION]...
-p Set default listening port [$port]
-q Set default SSL port [$sslport]
-s Enable SSL
-b Set the max incoming backlog [$backlog]
-f Server configuration file [$conf]
-d Fork and daemonize
Expand Down
2 changes: 2 additions & 0 deletions server.conf
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,5 @@ MOTD:server.motd
O:Taliesin:*.colorado.edu:$1$$TVOnNWraOf3DxUmboOTOa/
O:Taliesin2:localhost:428quTPELwvuA
MECH:90:90:1:10
P:6668:0
P:36901:1

0 comments on commit dadc30e

Please sign in to comment.