# HG changeset patch # User Dan # Date 1232507287 18000 # Node ID 508400fc5282df03647196d93879e4da849557cf # Parent 45164bc2567a81fad0b1ad25c3f1a6139b6457ce Major change to permissions backend - performs whois check (only supported blitzed and freenode right now) and advanced permissions supported. diff -r 45164bc2567a -r 508400fc5282 config-sample.php --- a/config-sample.php Sat Jan 10 14:12:36 2009 -0500 +++ b/config-sample.php Tue Jan 20 22:08:07 2009 -0500 @@ -7,7 +7,12 @@ $pass = ''; $name = 'Enano CMS logging/message bot'; $user = 'enano'; -$privileged_list = array('your', 'nick', 'list', 'here'); +$permissions = array( + 'your' => array('admin', 'alert'), + 'nick' => array('admin', 'alert'), + 'list' => array('echo', 'suspend', 'pm', 'channel' => array('#enano', '#ubuntu')), + 'here' => array('echo', 'suspend', 'pm', 'shutdown', 'channel' => array('#enano')), + ); $mysql_host = 'localhost'; $mysql_user = ''; $mysql_pass = ''; diff -r 45164bc2567a -r 508400fc5282 database.php --- a/database.php Sat Jan 10 14:12:36 2009 -0500 +++ b/database.php Tue Jan 20 22:08:07 2009 -0500 @@ -49,10 +49,11 @@ // alert everyone on the bot's alert list if ( is_object($irc) ) { - global $alert_list; - foreach ( $alert_list as $nick ) + global $permissions; + foreach ( $permissions as $nick => $perms ) { - $irc->privmsg($nick, "MySQL query error: $m_e"); + if ( check_permissions($nick, array('context' => 'alert')) ) + $irc->privmsg($nick, "MySQL query error: $m_e"); } } else diff -r 45164bc2567a -r 508400fc5282 enanobot.php --- a/enanobot.php Sat Jan 10 14:12:36 2009 -0500 +++ b/enanobot.php Tue Jan 20 22:08:07 2009 -0500 @@ -75,6 +75,22 @@ require('hooks.php'); require('config.php'); require('database.php'); +require('permissions.php'); + +if ( !isset($permissions) ) +{ + foreach ( $privileged_list as $user ) + { + $permissions[$user] = array('admin'); + } + if ( isset($alert_list) ) + { + foreach ( $alert_list as $user ) + { + $permissions[$user] = array('admin', 'alert'); + } + } +} $enanobot_version = '0.5-unstable'; @@ -141,7 +157,7 @@ { global $irc, $nick, $mysql_conn, $privileged_list; - if ( strpos($message['message'], $nick) && !in_array($message['nick'], $privileged_list) && $message['nick'] != $nick ) + if ( strpos($message['message'], $nick) && !check_permissions($message['nick'], array('context' => 'channel', 'channel' => $chan->get_channel_name())) && $message['nick'] != $nick ) { $target_nick =& $message['nick']; // $chan->msg("{$target_nick}, I'm only a bot. :-) You should probably rely on the advice of humans if you need further assistance.", true); @@ -156,40 +172,47 @@ { global $privileged_list, $irc, $nick; static $part_cache = array(); - if ( in_array($message['nick'], $privileged_list) && $message['message'] == 'Suspend' && $message['action'] == 'PRIVMSG' ) + if ( $message['message'] == 'Suspend' && $message['action'] == 'PRIVMSG' && check_permissions($message['nick'], array('context' => 'suspend'), false) ) { foreach ( $irc->channels as $channel ) { $part_cache[] = array($channel->get_channel_name(), $channel->get_handler()); - $channel->msg("I've received a request from {$message['nick']} to stop responding to requests, messages, and activities. Don't forget to unsuspend me with /msg $nick Resume when finished.", true); - $channel->part("Logging and presence suspended by {$message['nick']}", true); + $channel->part("suspended by {$message['nick']}", true); } } - else if ( in_array($message['nick'], $privileged_list) && $message['message'] == 'Resume' && $message['action'] == 'PRIVMSG' ) + else if ( $message['message'] == 'Resume' && $message['action'] == 'PRIVMSG' && check_permissions($message['nick'], array('context' => 'suspend'), false) ) { global $nick; foreach ( $part_cache as $chan_data ) { $chan_name = substr($chan_data[0], 1); $GLOBALS[$chan_name] = $irc->join($chan_data[0], $chan_data[1]); - $GLOBALS[$chan_name]->msg("Bot resumed by {$message['nick']}.", true); + $GLOBALS[$chan_name]->msg("(resumed by {$message['nick']})", true); $irc->privmsg('ChanServ', "OP {$chan_data[0]} $nick"); } $part_cache = array(); } - else if ( in_array($message['nick'], $privileged_list) && preg_match('/^Shutdown(?: (.+))?$/i', $message['message'], $match) && $message['action'] == 'PRIVMSG' ) + else if ( preg_match('/^Shutdown(?: (.+))?$/i', $message['message'], $match) && $message['action'] == 'PRIVMSG' && check_permissions($message['nick'], array('context' => 'shutdown'), false) ) { $GLOBALS['_shutdown'] = true; $quitmessage = empty($match[1]) ? "Remote bot shutdown requested by {$message['nick']}" : $match[1]; $irc->close($quitmessage, true); return 'BREAK'; } - else if ( in_array($message['nick'], $privileged_list) && preg_match('/^re(?:hash|load)?(?:config)?(?: |$)/', $message['message']) ) + else if ( preg_match('/^re(?:hash|load)?(?:config)?(?: |$)/', $message['message']) && check_permissions($message['nick'], array('context' => 'rehash'), false) ) { + $oldnick = $GLOBALS['nick']; require('config.php'); $GLOBALS['privileged_list'] = $privileged_list; $GLOBALS['alert_list'] = $alert_list; $GLOBALS['channels'] = $channels; + $GLOBALS['permissions'] = $permissions; + if ( $nick != $oldnick ) + { + $irc->change_nick($nick, $pass); + $GLOBALS['nick'] = $nick; + $GLOBALS['pass'] = $pass; + } $in = array(); foreach ( $irc->channels as $channel ) { diff -r 45164bc2567a -r 508400fc5282 libirc.php --- a/libirc.php Sat Jan 10 14:12:36 2009 -0500 +++ b/libirc.php Tue Jan 20 22:08:07 2009 -0500 @@ -256,6 +256,58 @@ } /** + * Returns WHOIS information about a nick. + * @param string Nick + * @return array + */ + + public function whois($nick) + { + static $cache = array(); + if ( isset($cache[$nick]) ) + { + if ( $cache[$nick]['time'] + 20 >= time() ) + { + return $cache[$nick]; + } + } + $this->put("WHOIS $nick\r\n"); + $lines = array(); + $return = array( + 'identified' => false, + 'time' => time() + ); + while ( $line = $this->get(3) ) + { + $lines[] = $line; + list(, $code) = explode(' ', $line); + $code = intval($code); + switch($code) + { + case 401: + return false; + case 311: + list(, , , $return['nick'], $return['user'], $return['host']) = explode(' ', $line); + $return['ircname'] = substr($line, strpos(substr($line, 1), ':') + 2); + break; + case 319: + $return['channels'] = explode(' ', substr($line, strpos(substr($line, 1), ':') + 2)); + break; + case 307: + case 320: + if ( strstr($line, 'identified') ) + $return['identified'] = true; + break; + case 318: + $cache[$nick] = $return; + return $return; + } + } + $cache[$nick] = $return; + return $return; + } + + /** * Parse bold (...) tags and color tags in a text into IRC speak, and process /me commands. Colors are ..., specify background with .... Valid colors are white, black, navy, green, red, maroon, purple, orange, yellow, lime, teal, aqua, cyan, blue, pink, grey, and silver * @param string Text to filter * @return string diff -r 45164bc2567a -r 508400fc5282 modules/autoop.php --- a/modules/autoop.php Sat Jan 10 14:12:36 2009 -0500 +++ b/modules/autoop.php Tue Jan 20 22:08:07 2009 -0500 @@ -9,7 +9,7 @@ $channelname = $chan->get_channel_name(); // if a known op joins the channel, send mode +o - if ( in_array($message['nick'], $privileged_list) ) + if ( check_permissions($message['nick'], array('context' => 'channel', 'channel' => $channelname))) { $chan->parent->put("MODE $channelname +o {$message['nick']}\r\n"); } diff -r 45164bc2567a -r 508400fc5282 modules/ctcp.php --- a/modules/ctcp.php Sat Jan 10 14:12:36 2009 -0500 +++ b/modules/ctcp.php Tue Jan 20 22:08:07 2009 -0500 @@ -5,7 +5,7 @@ function handle_ctcp($ctcp, $params, $message) { global $irc; - global $alert_list; + global $permissions; switch($ctcp) { case 'PING': @@ -20,8 +20,9 @@ break; } $now = date('r'); - foreach ( $alert_list as $alertme ) + foreach ( $permissions as $alertme => $perms ) { - $irc->privmsg($alertme, "Received CTCP \"$ctcp\" from {$message['nick']}, " . $now); + if ( check_permissions($alertme, array('context' => 'alert')) ) + $irc->privmsg($alertme, "Received CTCP \"$ctcp\" from {$message['nick']}, " . $now); } } diff -r 45164bc2567a -r 508400fc5282 modules/echo.php --- a/modules/echo.php Sat Jan 10 14:12:36 2009 -0500 +++ b/modules/echo.php Tue Jan 20 22:08:07 2009 -0500 @@ -7,7 +7,7 @@ { global $privileged_list; - if ( preg_match('/^\!echo /', $message['message']) && in_array($message['nick'], $privileged_list) ) + if ( preg_match('/^\!echo /', $message['message']) && check_permissions($message['nick'], array('context' => 'echo')) ) { $chan->msg(eb_censor_words(preg_replace('/^\!echo /', '', $message['message'])), true); } @@ -17,7 +17,7 @@ { global $privileged_list; - if ( in_array($message['nick'], $privileged_list) && preg_match("/^(?:\!echo-|\/msg )([^\007, \r\n\a\t]+) (.+)/", $message['message'], $match) ) + if ( preg_match("/^(?:\!echo-|\/msg )([#&][^\007, \r\n\a\t]+) (.+)/", $message['message'], $match) && check_permissions($message['nick'], array('context' => 'echo')) ) { global $libirc_channels; $channel_name =& $match[1]; @@ -26,7 +26,7 @@ $libirc_channels[$channel_name]->msg(eb_censor_words($match[2]), true); } } - else if ( in_array($message['nick'], $privileged_list) && preg_match("/^(?:\!pm|\/msg) ([^\007, \r\n\a\t]+) (.+)/", $message['message'], $match) ) + else if ( preg_match("/^(?:\!pm|\/msg) ([^\007, \r\n\a\t]+) (.+)/", $message['message'], $match) && check_permissions($message['nick'], array('context' => 'pm'), false) ) { global $irc; $irc->privmsg($match[1], eb_censor_words($match[2])); diff -r 45164bc2567a -r 508400fc5282 permissions.php --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/permissions.php Tue Jan 20 22:08:07 2009 -0500 @@ -0,0 +1,72 @@ +whois($nick); + if ( !$whois || ( $whois && !$whois['identified']) ) + { + if ( defined('LIBIRC_DEBUG') ) + echo "[!!!] Denied action {$params['context']} to {$nick} (whois check failed)\n"; + if ( !$quiet ) + $irc->privmsg($nick, "Please identify to services before you do that. (If you are already identified, wait 20 seconds for the whois cache to clear and try again)"); + return false; + } + + // Is the user an admin? + if ( in_array('admin', $permissions[$nick]) && $params['context'] !== 'alert' ) + { + if ( defined('LIBIRC_DEBUG') ) + echo "[!!!] Granted action {$params['context']} to {$nick} (has admin rights)\n"; + return true; + } + + switch($params['context']): + case 'channel': + if ( isset($permissions[$nick]['channel']) && is_array($permissions[$nick]['channel']) ) + { + if ( in_array($params['channel'], $permissions[$nick]['channel']) ) + { + if ( defined('LIBIRC_DEBUG') ) + echo "[!!!] Granted action {$params['context']} to {$nick} in channel {$params['channel']} (on channel whitelist)\n"; + return true; + } + } + if ( defined('LIBIRC_DEBUG') ) + echo "[!!!] Denied action {$params['context']} to {$nick} in channel {$params['channel']} (not on channel whitelist)\n"; + return false; + default: + eval(eb_fetch_hook('permission_check')); + if ( isset($result) ) + { + $perm = $result ? 'Granted' : 'Denied'; + if ( defined('LIBIRC_DEBUG') ) + echo "[!!!] $perm action {$params['context']} to {$nick} (plugin overridden)\n"; + return $result; + } + $result = in_array($params['context'], $permissions[$nick]); + $perm = $result ? 'Granted' : 'Denied'; + if ( defined('LIBIRC_DEBUG') ) + echo "[!!!] $perm action {$params['context']} to {$nick} (default handler)\n"; + return $result; + endswitch; +} + diff -r 45164bc2567a -r 508400fc5282 statsincludes/stats_frontend.php --- a/statsincludes/stats_frontend.php Sat Jan 10 14:12:36 2009 -0500 +++ b/statsincludes/stats_frontend.php Tue Jan 20 22:08:07 2009 -0500 @@ -15,7 +15,7 @@ if ( empty($targetuser) ) $targetuser = $message['nick']; - if ( $targetuser != $message['nick'] && !in_array($message['nick'], $privileged_list) ) + if ( $targetuser != $message['nick'] && !check_permissions($message['nick'], array('context' => 'deletestats')) ) { $irc->privmsg($message['nick'], "Sorry, you need to be a moderator to delete statistics for users other than yourself."); return true;