Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #!/usr/bin/perl
- use strict;
- use warnings;
- use DBI;
- use POE qw(Component::IRC::State);
- my $own_nick = shift;
- # SQL
- my $dbh = DBI->connect(
- 'DBI:mysql:bot',
- 'bot',
- '',
- {'mysql_auto_reconnect' => 1}
- ) or die 'DBI: ' . $DBI::errstr;
- # IRC
- my $irc = POE::Component::IRC->spawn(
- nick => $own_nick,
- ircname => 'servotron',
- server => '127.0.0.1',
- port => 6667,
- ) or die 'POE::Component::IRC: ' . $!;
- POE::Session->create(
- package_states => [ main => [ qw(_start irc_msg) ] ],
- heap => { irc => $irc }
- );
- $poe_kernel->run();
- sub _start {
- $irc->yield(register => 'all');
- $irc->yield(connect => {});
- }
- sub irc_msg {
- my ($sender, $who, $recipients, $what) = @_[SENDER, ARG0 .. ARG2];
- my $nick = (split /!/, $who)[0];
- open(LOG, ">> /home/bot/logs/" . $own_nick . ".txt");
- print LOG $who . ': ' . $what . "\n";
- close(LOG);
- $irc->yield(privmsg => $nick => answer($what));
- }
- sub answer {
- # To make it more interesting I split the userinput at whitespaces. This way
- # the attacker can not use them in the injection. Not hard to bypass though.
- my @what = split /\s/, shift;
- # Now let's parse the input.
- my $output;
- if (($#what == 0) && ($what[0] eq "credits")) {
- $output = 'All hail to our robotic overlord lama \0/';
- }
- elsif (($#what == 0) && ($what[0] eq "help")) {
- $output = 'help; details [movie id]; search [keyword]; add movie [title]; add robot [movie id] [name]';
- }
- elsif (($#what == 1) && ($what[0] eq "details")) {
- $output = details_request($what[1]);
- }
- elsif (($#what == 1) && ($what[0] eq "search")) {
- $output = search_request($what[1]);
- }
- elsif (($#what == 2) && ($what[0] eq "add") && ($what[1] eq "movie")) {
- $output = add_movie_request($what[2]);
- }
- elsif (($#what == 3) && ($what[0] eq "add") && ($what[1] eq "robot")) {
- $output = add_actor_request($what[2], $what[3]);
- }
- if ($output) {
- return $output;
- }
- else {
- return '?SYNTAX ERROR';
- }
- }
- sub search_request {
- my $keyword = shift;
- my $query = $dbh->prepare(
- "SELECT movies.id, movies.title FROM movies WHERE movies.title LIKE ? LIMIT 5"
- ) or return 0;
- $query->execute('%' . $keyword . '%') or return 0;
- if ($query->rows == 0) {
- return '?OUT OF DATA';
- }
- my $output = '';
- while (my ($id, $title) = $query->fetchrow_array()) {
- $output .= $id . ': ' . $title . '; ';
- }
- return $output;
- }
- sub details_request {
- my $movie_id = shift;
- # Sleep crashes the bot, so sadly I have to block it.
- return 0 if ($movie_id =~ /(sleep|benchmark)/i);
- # Get the total number of actors for this movie. Here's the bug.
- my $query1 = $dbh->prepare(
- "SELECT COUNT(foo.id) AS cid FROM (\n" .
- "SELECT actors.id FROM actors WHERE (actors.movie = '" . $movie_id . "')\n" .
- ") foo"
- ) or return 0;
- $query1->execute() or return 0;
- my ($count) = $query1->fetchrow_array();
- # Get the movie title.
- my $query2 = $dbh->prepare(
- "SELECT movies.title FROM movies WHERE movies.id = ?"
- ) or return 0;
- $query2->execute($movie_id) or return 0;
- if ($query2->rows == 0) {
- return '?OUT OF DATA';
- }
- my ($title) = $query2->fetchrow_array();
- my $output = $title . ': ';
- # Get the last 5 added robots of that movie.
- my $query3 = $dbh->prepare(
- "SELECT actors.name FROM actors WHERE actors.movie = ? ORDER BY actors.id DESC LIMIT 5"
- ) or return 0;
- $query3->execute($movie_id) or return 0;
- if ($query3->rows > 0) {
- while (my ($name) = $query3->fetchrow_array()) {
- $output .= $name . '; ';
- }
- }
- # Add the total number of robots (the limitation makes the seperate total count realistic).
- return $output . '(' . $count . ' total)';
- }
- sub add_movie_request {
- my $title = shift;
- my $query = $dbh->prepare('INSERT INTO movies (`title`) VALUES (?)');
- $query->execute($title) or return 0;
- return '!OK';
- }
- sub add_actor_request {
- my $movie_id = shift;
- my $name = shift;
- my $query = $dbh->prepare('INSERT INTO actors (`movie`, `name`) VALUES (?, ?)');
- $query->execute($movie_id, $name) or return 0;
- return '!OK';
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement