#!/usr/bin/perl # CGI:IRC - http://cgiirc.sourceforge.net/ # Copyright (C) 2000-2006 David Leadbeater # vim:set ts=3 expandtab shiftwidth=3 cindent: # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # Uncomment this if the server doesn't chdir (Boa). # BEGIN { (my $dir = $0) =~ s|[^/]+$||; chdir($dir) } use strict; use vars qw($VERSION $config $config_path); use lib qw/modules interfaces/; no warnings 'uninitialized'; ($VERSION = '$Name: rel_0_5_9 $ 0_5_CVS $Id: irc.cgi,v 1.41 2022/06/06 18:53:50 dgl Exp $' ) =~ s/^.*?(\d\S+) .*?(\d{4}\/\S+) .*$/$1/; $VERSION .= " ($2)"; $VERSION =~ s/_/./g; require 'parse.pl'; my $cgi = cgi_read(); for('', '/etc/cgiirc/', '/etc/') { last if -r ($config_path = $_) . 'cgiirc.config'; } $config = parse_config($config_path . 'cgiirc.config'); if(!parse_cookie()) { print "Set-cookie: cgiircauth=". random(25) .";path=/\r\n"; } print join("\r\n", # Hack to make sure we print the correct type for stylesheets too.. 'Content-type: text/' . (ref $cgi && defined $cgi->{item} && $cgi->{item} eq 'style' ? 'css' : 'html') # We need this for some JavaScript magic that detects the character set. # Basically don't send a character set for the login page.. . (ref $cgi && ($cgi->{item} || $cgi->{Nickname}) ? '; charset=utf-8' : ''), 'Pragma: no-cache', 'Cache-control: must-revalidate, no-cache', 'Expires: -1') . "\r\n"; # Please leave this. my $copy = <CGI:IRC $VERSION
EOF my $scriptname = $config->{script_login} || 'irc.cgi'; my $interface = ref $cgi && defined $cgi->{interface} ? $cgi->{interface} : 'default'; $interface =~ /^([a-z0-9]+)/; $interface = $1; require($interface . '.pm'); if(ref $cgi && defined $cgi->{item}) { print "\r\n"; # send final header my $name = $cgi->{item}; exit unless $interface->exists($name); $interface->$name($cgi, $config, 0); }elsif(ref $cgi && defined $cgi->{Nickname}) { print "\r\n"; # send final header my $r = random(); my($format, $style); my %p = ( Nickname => 'nick', Channel => 'chan', Port => 'port', Server => 'serv', Realname => 'name', interface => 'interface', Password => 'pass', Format => 'format', 'Character_set' => 'charset', ); my $out; for(keys %p) { if(exists $cgi->{"${_}_text"}) { if(!defined $cgi->{$_} or $cgi->{$_} eq '') { $cgi->{$_} = $cgi->{"${_}_text"}; } } next unless exists $cgi->{$_}; $out .= cgi_encode($p{$_}) . '=' . cgi_encode($cgi->{$_}) . '&'; } $format = exists $cgi->{Format} ? $cgi->{Format} : $config->{format} || 'default'; $format =~ s/[^a-z]//gi; $format = parse_config($config_path . "formats/$format"); $style = exists $format->{style} ? $format->{style} : 'default'; $out .= "R=$r"; if(defined $config->{'login secret'}) { require Digest::MD5; my $t = time; my $token = Digest::MD5::md5_hex($t . $config->{'login secret'} . $r); $out .= "&token=$token&time=$t"; } $interface->frameset($scriptname, $config, $r, $out, $interface, $style); }elsif(defined $config->{form_redirect}) { print join("\r\n", "Status: 302", "Location: $config->{form_redirect}", "", $config->{form_redirect}); }else{ print "\r\n"; # send final header my $have_entities = 0; eval { require HTML::Entities; $have_entities = 1; }; my(%items,@order); my $server = dolist($config->{default_server}); my $channel = dolist($config->{default_channel}); my $port = dolist($config->{default_port}); my $charset = [ $config->{'irc charset'} || 'Unicode (UTF-8)' ]; # Add some useful suggestions for character sets: for my $set('Western (ISO-8859-1)', 'Cyrillic (ISO-8859-5)', 'Cyrillic (KOI8-R)', 'Japanese (ShiftJIS)', 'Chinese (Big5)', 'Chinese (GB2312)', 'Korean (EUC-KR)') { push @$charset, $set unless grep { $set =~ /$_/i } @$charset } if(defined $ENV{HTTP_ACCEPT_CHARSET}) { for my $set(split ',', $ENV{HTTP_ACCEPT_CHARSET}) { next if $set =~ /;q=0($|\.0$)/ or $set =~ /\*/; $set =~ s/;.*//; push @$charset, $set unless grep { /$set/i } @$charset; } } if(ref $cgi && $cgi->{chan}) { $channel = $cgi->{chan}; } if(!defined $config->{allow_non_default} || !$config->{allow_non_default}) { add_disabled($server); add_disabled($channel); add_disabled($port); }else{ add_disabled($server) unless defined $config->{access_server}; add_disabled($port) unless defined $config->{access_port}; add_disabled($channel) unless defined $config->{access_channel}; } opendir(FORMATS, $config_path . "formats"); my @formats; for(sort readdir FORMATS) { next unless !/^\./ && -f $config_path . "formats/$_"; if($_ eq ($config->{format} || 'default')) { unshift(@formats, $_); }else{ push(@formats, $_); } } closedir(FORMATS); %items = ( Nickname => $ENV{REMOTE_USER} || $config->{default_nick}, Channel => $channel, Server => $server, Port => $port, Password => '-PASSWORD-', Realname => $config->{default_name}, Format => \@formats, 'Character set' => $charset ); my $func = \&escape_html; $func = \&HTML::Entities::encode_entities if $have_entities; @items{keys %items} = map { ref $_ ? [map { $func->($_) } @$_] : $func->($_) } values %items; $items{Nickname} =~ s/\?/int rand 10/eg; if(ref $cgi && $cgi->{adv}) { if($config->{'login advanced'}) { @order = split(/,\s*/, $config->{'login advanced'}); }else{ @order = qw/Nickname Realname Server Port Channel Password Format/; push @order, 'Character set'; } }else{ if($config->{'login basic'}) { @order = split(/,\s*/, $config->{'login basic'}); }else{ @order = qw/Nickname Server Channel/; } } $interface->login($scriptname, $interface, $copy, $config, \@order, \%items, (ref $cgi && $cgi->{adv} ? 0 : 1)); } sub random { return join('',map(('a'..'z','0'..'9')[int rand 62], 0..($_[0] || 15))); } sub dolist { my($var) = @_; my @tmp = split(/,\s*/, $var); return [@tmp] if $#tmp > 0; return $var; } sub add_disabled { if(ref $_[0]) { unshift @{$_[0]}, "-DISABLED-"; } else { $_[0] = "-DISABLED- $_[0]"; } } sub cgi_read { return unless defined $ENV{REQUEST_METHOD}; if($ENV{REQUEST_METHOD} eq 'GET' && $ENV{QUERY_STRING}) { return parse_query($ENV{QUERY_STRING}); }elsif($ENV{REQUEST_METHOD} eq 'POST' && $ENV{CONTENT_LENGTH}) { my $tmp; read(STDIN, $tmp, $ENV{CONTENT_LENGTH}); return parse_query($tmp); } } sub cgi_encode { # from CGI.pm my $toencode = shift; $toencode=~s/([^a-zA-Z0-9_.-])/uc sprintf("%%%02x",ord($1))/eg; return $toencode; } sub error { die(@_); }