# Run a challenge response oper thingie
#
# (C) 2006 by Joerg Jaspert <joerg@debian.org>
#
#    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 script; if not, write to the Free Software
#    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA


# This script needs "rsa_respond" out of the hybrid ircd to actually work.
# svn for that is svn+ssh://helium.oftc.net/svn/oftc-hybrid
# And you need to have an rsa keypair in your oper block. Create one with
# openssl genrsa -des3 1024 > oper-whatever.key
# openssl rsa -pubout < oper-whatever.key > oper-whatever.pub
# and send the .pub to your noc :)

# You have two settings to change after loading this script, just type
# /set challenge to see them. Then you can use it in the future to oper by
# typing /cr YOUROPERNICK


use strict;

use vars qw($VERSION %WEECHAT);


$VERSION = '0.0.0.0.1.alpha.0.2~weechat';
%WEECHAT = (
    authors     => 'Joerg Jaspert, Neil McGovern',
    contact     => 'joerg@debian.org, neilm@debian.org',
    name  => 'challenge',
    description => 'Performs challenge-response oper auth',
    license     => 'GPL v2 (and no later)',
);


# Gets called from user, $arg should only contain the oper name
sub challenge_oper {
  my ($something1, $buffer, $arg, $argcount2, $something3, $something4) = @_;

  if (length($arg) < 2) { # a one char oper name? not here
	weechat::print("","No username provided");
	return weechat::WEECHAT_RC_ERROR;
  } else {
	weechat::hook_signal("*,irc_in_386", "event_challenge_received", "");
#    $server->redirect_event('challenge', 1, "", -1, undef,
#			    {
#			     "" => "redir challenge received",
#			    });
#	$server->send_raw("challenge $arg");
	weechat::command($buffer, "/quote challenge $arg");
	return weechat::WEECHAT_RC_OK;
  }
}


# This event now actually handles the challenge, the rest was just setup
sub event_challenge_received{
  my ($pointer, $type, $data) = @_;
  # Data contains "nick :challenge"
  my (undef, $chatnet, $challenge) = split(/:/, $data);
  my ($server, undef, undef) = split (/ /,$chatnet);


  my $key = weechat::config_string(weechat::config_get('plugins.var.perl.challenge.oper_key'));
  my $respond = weechat::config_string(weechat::config_get('plugins.var.perl.challenge.rsa_path'));

  my $passphrase = "XXXXXXXXXXXXX";

  my $response = `$respond $key $challenge $passphrase`;

  my $buffer = weechat::info_get("irc_buffer", $server);
  weechat::command($buffer, "/quote challenge +$response");
  weechat::command($buffer, "/umode +Rabcdfiklnorsuwxyz");
  #my $pid = open(RSA, "$respond $key $challenge |") or die "Damn, couldnt run $respond";
  #my $response = <RSA>;
  #close (RSA);
  #$server->send_raw("challenge +$response");

#  my $window = weechat::current_window();
#  $window->command("redraw");
}


# ---------- Do the startup tasks ----------

# Register the script with weechat
weechat::register(
	$WEECHAT{name},
	$WEECHAT{authors},
	$VERSION,
	$WEECHAT{license},
	$WEECHAT{description},
	"",
	"");
weechat::print("","Hello from perl!");

weechat::hook_command('cr', 'challenge response', '[username]', 'Nickname of user to register', "", 'challenge_oper', "");

# Add the settings
weechat::config_set_plugin("oper_key","/home/maulkin/.weechat/certs/oper-maulkin.key");
weechat::config_set_plugin("rsa_path", "/home/maulkin/bin/respond");

# Ok, setup the redirect event, so we can later handle the challenge thing.
#Irssi::Irc::Server::redirect_register("challenge",
#									  0, # not a remote one
#									  5, # wait at max 5 seconds for a reply
#									  undef, # no start event
#									  {
#									   "event 386" => -1, # act on the 386, the rsa challenge
#									  },
#									  undef, # no optional event
#									 );
#Irssi::signal_add({'redir challenge received' => \&event_challenge_received,});
