PageRenderTime 25ms CodeModel.GetById 29ms RepoModel.GetById 0ms app.codeStats 0ms

/tools/respond/client-scripts/challenge-irssi.pl

https://github.com/alyx/sporksircd
Perl | 173 lines | 124 code | 29 blank | 20 comment | 15 complexity | 6df153ea10ea5c025cb9481cb247fb9c MD5 | raw file
  1. # ro-challenge.pl
  2. #
  3. # Thanks fly out to:
  4. # zap, who wrote the POC ho_challenge.pl I reworked into this
  5. #
  6. # Changelog:
  7. #
  8. # v1.0 Initial version
  9. # v1.1 Avoid leaving zombies
  10. use strict;
  11. use vars qw($VERSION %IRSSI);
  12. use Irssi;
  13. use Irssi::TextUI;
  14. use IPC::Open2;
  15. use FileHandle;
  16. %IRSSI = (
  17. authors => 'James Seward',
  18. contact => 'james@jamesoff.net',
  19. name => 'ro_challenge.pl',
  20. description => 'Implementation of ratbox2.2 ssl-based challenge-response-authentication for IRC operators',
  21. license => 'GPL',
  22. url => 'http://www.jamesoff.net/',
  23. changed => '2006-02-22'
  24. );
  25. #
  26. # Global vars
  27. my $challenge_text = '';
  28. my $challenge_keyphrase = "";
  29. #
  30. # Handle /challenge
  31. sub cmd_challenge {
  32. my ($cmdline, $server, $channel) = @_;
  33. $cmdline =~ s/\s+$//;
  34. my $debug = Irssi::settings_get_bool("ro_challenge_debug");
  35. Irssi::print("challenge commandline = $cmdline") if ($debug);
  36. if ($cmdline eq '') {
  37. Irssi::print("challange: /CHALLENGE <opername> [keyphrase]");
  38. return 0;
  39. }
  40. my ($opernick, $keyphrase) = split(" ", $cmdline);
  41. Irssi::print("challenge: opernick = $opernick") if ($debug);
  42. if ($debug) {
  43. if ($keyphrase eq '') {
  44. Irssi::print("challenge: keyphrase = <empty>");
  45. }
  46. else {
  47. Irssi::print("challenge: keyphrase = <hidden>");
  48. }
  49. }
  50. if ($keyphrase eq '') {
  51. Irssi::print("challenge: Attempting challenge with blank keyphrase (!)");
  52. }
  53. $challenge_text = "";
  54. $challenge_keyphrase = $keyphrase;
  55. $server->send_raw("CHALLENGE $opernick");
  56. Irssi::print("challenge: sent CHALLENGE") if ($debug);
  57. }
  58. #
  59. # Handle incoming 740 numeric (receive one or more parts
  60. # of the challenge text from server)
  61. sub event_challenge_rpl {
  62. my ($server, $challenge) = @_;
  63. my $debug = Irssi::settings_get_bool("ro_challenge_debug");
  64. Irssi::print("challenge: received text --> $challenge") if ($debug);
  65. $challenge =~ s/^[^ ]+ ://;
  66. $challenge_text .= $challenge;
  67. Irssi::print("current challenge = $challenge") if ($debug);
  68. }
  69. #
  70. # Handle incoming 741 numeric - server has sent us all
  71. # challenge text, and we should generate and send our reply
  72. sub event_challenge_rpl_end {
  73. my ($server, $blah) = @_;
  74. my $debug = Irssi::settings_get_bool("ro_challenge_debug");
  75. my $pid;
  76. Irssi::print("challenge: Received all challenge text, running response...") if ($debug);
  77. my $respond_path = Irssi::settings_get_str("ro_challenge_respond");
  78. my $keyfile_path = Irssi::settings_get_str("ro_challenge_keyfile");
  79. if ($respond_path eq '') {
  80. Irssi::print("challenge: whoops! You need to /set ro_challenge_respond <path to binary>");
  81. return 0;
  82. }
  83. if ($keyfile_path eq '') {
  84. Irssi::print("challenge: whoops! You need to /set ro_challenge_keyfile <path to private key file");
  85. return 0;
  86. }
  87. #check respond binary exists and is executable
  88. if (! -x $respond_path) {
  89. Irssi::print("challenge: $respond_path is not executable by you :(");
  90. return 0;
  91. }
  92. if (! -r $keyfile_path) {
  93. Irssi::print("challenge: $keyfile_path is not readable by you :(");
  94. return 0;
  95. }
  96. unless ($pid = open2(*Reader, *Writer, $respond_path, $keyfile_path)) {
  97. Irssi::print("challenge: couldn't exec respond, failed!");
  98. return 0;
  99. }
  100. print Writer "$challenge_keyphrase\n";
  101. print Writer "$challenge_text\n";
  102. #erase data, just in case
  103. $challenge_keyphrase =~ s/./!/g;
  104. $challenge_text =~ s/./!/g;
  105. $challenge_keyphrase = $challenge_text = '';
  106. my $output = scalar <Reader>;
  107. chomp($output);
  108. waitpid $pid, 0;
  109. if ($output =~ /^Error:/) {
  110. $output =~ s/^Error: //;
  111. Irssi::print("challenge: Error from respond: $output");
  112. return 0;
  113. }
  114. Irssi::print("received output: $output") if ($debug);
  115. Irssi::print("challenge: Response processed, opering up...") if ($debug);
  116. $server->send_raw("CHALLENGE +$output");
  117. return 1;
  118. }
  119. #
  120. # Signals
  121. Irssi::signal_add('event 740', 'event_challenge_rpl');
  122. Irssi::signal_add('event 741', 'event_challenge_rpl_end');
  123. #
  124. # Settings
  125. Irssi::settings_add_bool("ro", 'ro_challenge_debug', 0);
  126. Irssi::settings_add_str("ro", "ro_challenge_keyfile", '');
  127. Irssi::settings_add_str("ro", "ro_challenge_respond", '');
  128. #
  129. # Commands
  130. Irssi::command_bind('challenge', 'cmd_challenge');