Tonight's incomplete proof-of-concept bad-idea code

An RT IRC bot. the code’s messy as hell. IRC’s not at all secure.
I suspect that this bot’s authentication is even more dodgy than most.
You don’t want to run this code at all. But you ESPECIALLY don’t want to run
it on a public IRC network.

It lets anyone query open tickets in a queue or show a ticket or show an attachment.

It lets users who’ve issued a “login” command open/stall/resolve tickets.

It’s undocumented.

You really don’t want to run this code, but it might be fun to play with.

If anyone really wants to pick this up and run with it, they should get
in touch with me.

-j

#!/usr/bin/perl -w

use strict;
use POE;
use POE::Component::IRC;
use Text::Wrapper;
use strict;
use Carp;
use Getopt::Long;

use lib “/opt/rt-cpan/lib”;
use lib “/opt/rt-cpan/etc”;

use RT::Interface::CLI qw(CleanEnv LoadConfig DBConnect
GetCurrentUser GetMessageContent);

use RT::Queues;
use RT::Tickets;

#Clean out all the nasties from the environment
CleanEnv();

#Load etc/config.pm and drop privs
LoadConfig();

#Connect to the database and get RT::SystemUser and RT::Nobody loaded
DBConnect();

#Drop setgid permissions
RT::DropSetGIDPermissions();

my $CurrentUser = $RT::SystemUser;

package main;
my $nick = shift || ‘ellie’;

Create the IRC and Connection objects

sub start {
my ($kernel) = $
[KERNEL];

print "About to connect to the irc server\n";

$kernel->alias_set( ‘smileyninja’ );
$kernel->post( ‘dicebot’, ‘register’, ‘all’);
$kernel->post( ‘dicebot’, ‘connect’, { Debug => 1,
Nick => $nick,
Server => $ARGV[0] || ‘irc.example.com’,
Port => $ARGV[1] || 6667,
Username => ‘ellie’,
Ircname => “obra’s testbot”,}
);
}

sub irc_001 {
my ($kernel) = $_[KERNEL];

$kernel->post( ‘dicebot’, ‘mode’, $nick, ‘+i’ );
}

sub irc_disconnected {
my ($server) = $_[ARG0];
print “Lost connection to server $server.\n”;
}

sub irc_error {
my $err = $_[ARG0];
print “Server error occurred! $err\n”;
}

sub irc_socketerr {
my $err = $_[ARG0];
print “Couldn’t connect to server: $err\n”;
}

sub stop {
my ($kernel) = $
[KERNEL];

print “Control session stopped.\n”;
$kernel->post( ‘dicebot’, ‘quit’, ‘Neenios on ice!’ );
$kernel->alias_remove( ‘smileyninja’ );
}
sub irc_msg {
my ($kernel, $session, $who, $chan, $msg) = @_[KERNEL, HEAP, ARG0 … ARG2];
if ($who =~ /^(.)!(.)$/ ) {
my $nick = $1;
my $mask = $2;
print “Got $msg from $who\n”;
if ($msg =~ /^login (.) (.)$/) {
my $username = $1;
my $pass = $2;

        print "Pass is $pass\n";
        my $userobj = new RT::CurrentUser($username);
        print "Loading ".$userobj->Name ."\n";
        if ($userobj->IsPassword($pass)) {
           $session->{'users'}->{$mask}->{userobj} =  $userobj;
            msg($kernel, $nick, "Hi, ".$session->{'users'}->{$mask}->{userobj}->Name);
        }
        else {
            print $userobj->__Value('Password') ."\n". crypt($username, $userobj->__Value('Password')) ."\n";
            print "$username tried to log in with $pass-- as a password\n";
            msg($kernel, $nick, "Go away.");
            $session->{'users'}->{$mask} == undef;
        }
    }

elsif ($msg =~ /^whoami$/) {
    if ($session->{'users'}->{$mask}->{userobj}) {
        msg($kernel, $nick, "You are ".$session->{'users'}->{$mask}->{userobj}->Name);
    } else{
        msg ($kernel, $nick, "You don't look familiar. you might want to login");
        }
}

elsif ($msg =~ /show ticket (\d*)$/) {
    show_ticket($kernel, $nick, $1)

}
elsif ($msg =~ /show attachment (.*?)$/) {
    show_attachment($kernel, $nick, $1);

}

elsif ($msg =~ /open tickets in (.*?)$/) {
    open_tickets_in($kernel, $nick, $1);
}
else {
    if ($session->{'users'}->{$mask}->{userobj}) {
        my $CurrentUser = $session->{'users'}->{$mask}->{userobj};
   
        my %statusmap = ( 'new'=> 'new', 'open' => 'open', 'stall' => 'stalled', 'resolve' => 'resolved', 'close' => 'resolved');

        if ($msg =~ /^(open|close|resolve|stall|new) (\d+)$/) {
            my $action = $1;
            my $id = $2;

            my $ticket = RT::Ticket->new($CurrentUser);
            $ticket->Load($id);
            unless ($ticket->id) {
                msg($kernel, $nick, "Couldn't find ticket $id");
            }
            
            my ($val, $ret) = $ticket->SetStatus($statusmap{$action}) ; 
            msg($kernel, $nick, "#".$ticket->Id.": $ret". $statusmap{$action});
        }

    }

}
}     

else {
   warn "Weird-ass who: $who";
}

}

POE::Component::IRC->new( ‘dicebot’ ) or
die “Can’t instantiate new IRC component!\n”;
POE::Session->new( ‘main’ => [qw(_start _stop irc_001 irc_disconnected
irc_msg
irc_socketerr irc_error )] );
$poe_kernel->run();

exit 0;

{{{ show_attach

sub show_attachment {
my $kernel = shift;
my $nick = shift;
my $attach = shift;
my $attachment = new RT::Attachment($CurrentUser);
$attachment->Load($attach);
if ($attachment->Id) {
foreach my $line( split(/\n/,$attachment->Content)) {
msg($kernel,$nick, $line);
}

    } else {
        msg($kernel,$nick, "No such attachment");
    }

}

}}}

{{{ show_ticket

sub show_ticket {
my $kernel = shift;
my $nick = shift;
my $tid = shift;

my $ticket = new RT::Ticket($CurrentUser);
$ticket->Load($tid);
if ($ticket->Id) {

    msg($kernel,$nick, "Subject:   ",$ticket->Subject);
    msg($kernel,$nick, "Status:    ",$ticket->Status , "  Priority:  ",$ticket->Priority);
    msg($kernel,$nick, "Owner:     ", $ticket->OwnerObj->Name);
    msg($kernel,$nick, "Requestors:", $ticket->RequestorsAsString);
    msg($kernel,$nick, "Cc:        ", $ticket->CcAsString);
    msg($kernel,$nick, "AdminCc:   ", $ticket->AdminCcAsString);
    
    msg($kernel,$nick, "----History----");
    
    my $trans = $ticket->Transactions;
    while (my $t = $trans->Next) {
	msg($kernel,$nick, $t->CreatedObj->AsString, ' ', $t->Description);
	if ($t->Attachments->Count) {
	    my $a = $t->Attachments;
	    while ( my $attach = $a->Next) {
		if ($attach->ContentType =~ /multipart\//) { next }
		elsif ($attach->ContentType !~ /^text/i) {
		    msg($kernel,$nick, $attach->ContentType , ' file not shown.');
		    msg($kernel,$nick, $RT::WebURL,'/NoAuth/Attachment/',$t->id,'/',$attach->Id,'/',$attach->Filename);
		}
		else {
		    my $wrapper =  Text::Wrapper->new(columns => 60);
		    my @lines = split(/\n/, $wrapper->wrap($attach->Content));
		    for (my $i = 0; $i <8; $i++) {
			msg($kernel,$nick, shift @lines) if (@lines);
		    }	
		    if (@lines) {
			msg($kernel,$nick, ".... (see ".$RT::WebURL,'/NoAuth/Attachment/',$t->Id,'/',$attach->Id,'/',$attach->Filename);
		    }
		    
		}	
		
		
	    }	
	}	
	
    }	
    msg($kernel,$nick, "----End of history----");

}
else {
    msg($kernel,$nick, "Ticket $1 could not be found");
}	
}

}}}

{{{ open tix

sub open_tickets_in {
my $kernel = shift;
my $nick = shift;
my $queuename = shift;
my $q = new RT::Queue($CurrentUser);
$q->Load($queuename);

if ($q->id) {
    my $search = new RT::Tickets($CurrentUser);

    $search->LimitStatus(VALUE => 'new', OPERATOR => '=', ENTRYAGGREGATOR => 'or');
    $search->LimitStatus(VALUE => 'open', OPERATOR => '=', ENTRYAGGREGATOR => 'or');
    $search->LimitQueue(VALUE => $q->id);
    $search->GotoFirstItem();
    msg($kernel,$nick,$search->Count, ' open tickets found for ',$q->Name);
    $search->GotoFirstItem();
    while (my $t = $search->Next) {
	msg($kernel,$nick,$t->id, " ", $t->Subject );
    }
}	
else {
    msg($kernel,$nick, "Queue $1 could not be found");
}	

}

}}}

{{{ send a msg convenience function

sub msg {
my $kernel = shift;
$kernel->post(‘dicebot’ , ‘privmsg’, @_);
}

}}}

http://www.bestpractical.com/products/rt – Trouble Ticketing. Free.

An RT IRC bot. the code’s messy as hell. IRC’s not at all secure.
I suspect that this bot’s authentication is even more dodgy than most.
You don’t want to run this code at all. But you ESPECIALLY don’t want to run
it on a public IRC network.

Has anyone mentioned lately that you’re a touch scary at times? I mean,
really scary :wink:

But, I’m sure that one of the irc networks with services (and a bit of
codework to let this authenticate off the irc service daemon) might pick
it up to track various outages/DOS attacks/best places to get sushi.

                         Bruce Campbell                            RIPE
                                                                    NCC
                                                             Operations

An RT IRC bot. the code’s messy as hell. IRC’s not at all secure.
I suspect that this bot’s authentication is even more dodgy than most.
You don’t want to run this code at all. But you ESPECIALLY don’t want to run
it on a public IRC network.

Has anyone mentioned lately that you’re a touch scary at times? I mean,
really scary :wink:

shrug I’ve been running an RTBot on zephyr for a while now (hacked
into RT1)… but I admit that the same for IRC strikes me as a Bad Idea
:slight_smile:

brandon s. allbery [os/2][linux][solaris][japh]
allbery@kf8nh.apk.net
system administrator [WAY too many hats]
allbery@ece.cmu.edu
electrical and computer engineering
KF8NH
carnegie mellon university [“better check the oblivious first”
-ke6sls]

Actually, an IRC bot makes a lot of sense - I could’ve used this
about a year ago, back before my employer sank beneath the
waves of inky red. We used a private IRC server for internal Ops
communication and RT for work management (funny how I have the
time to install, maintain and enhance RT but it’s outside my job
description to support migration to Remedy. Heh.)

I can’t imagine running this in public. IRC in a cloistered
environment is scary enough.

– BobOn 24 Dec 2001, at 11:15, Brandon S. Allbery wrote:

On Mon, 2001-12-24 at 09:09, Bruce Campbell wrote:

On Sun, 23 Dec 2001, Jesse Vincent wrote:

An RT IRC bot. the code’s messy as hell. IRC’s not at all secure.
I suspect that this bot’s authentication is even more dodgy than
most. You don’t want to run this code at all. But you ESPECIALLY
don’t want to run it on a public IRC network.

Has anyone mentioned lately that you’re a touch scary at times? I
mean, really scary :wink:

shrug I’ve been running an RTBot on zephyr for a while now (hacked
into RT1)… but I admit that the same for IRC strikes me as a Bad
Idea :slight_smile:


brandon s. allbery [os/2][linux][solaris][japh]
allbery@kf8nh.apk.net
system administrator [WAY too many hats]
allbery@ece.cmu.edu
electrical and computer engineering
KF8NH carnegie mellon university [“better check the oblivious
first” -ke6sls]


rt-devel mailing list
rt-devel@lists.fsck.com
http://lists.fsck.com/mailman/listinfo/rt-devel

Actually, an IRC bot makes a lot of sense - I could’ve used this
about a year ago, back before my employer sank beneath the
waves of inky red. We used a private IRC server for internal Ops
communication and RT for work management (funny how I have the
time to install, maintain and enhance RT but it’s outside my job
description to support migration to Remedy. Heh.)

I can’t imagine running this in public. IRC in a cloistered
environment is scary enough.

– Bob

nod That’s exactly the sort of environment I’d been thinking of this for. We did a similar
thing when I was at into. and when I was at Leftbank. At least one site is already
sucessfully using a query-only prototype of the prototype I’d hacked up a week or so ago.

It’s really handy to not have to fire up a seperate shell or browser to talk to RT. One thing
I may play with some time is a line-oriented text editor component, so that one can do more than
single-line ticket updates from an IRC session.

-j

http://www.bestpractical.com/products/rt – Trouble Ticketing. Free.