]> git.mxchange.org Git - quix0rs-gnu-social.git/blobdiff - scripts/xmppdaemon.php
CSRF protection in user registration
[quix0rs-gnu-social.git] / scripts / xmppdaemon.php
index e5ecf9d2da3670c65c4b26519382bce68bf83533..da1638011603f57250187d78e9679afd91a76d6e 100755 (executable)
 function xmppdaemon_error_handler($errno, $errstr, $errfile, $errline, $errcontext) {
     switch ($errno) {
      case E_USER_ERROR:
-       echo "ERROR: [$errno] $errstr ($errfile:$errline)\n";
-       echo "  Fatal error on line $errline in file $errfile";
-       echo ", PHP " . PHP_VERSION . " (" . PHP_OS . ")\n";
-       echo "Aborting...\n";
-       exit(1);
-       break;
+               echo "ERROR: [$errno] $errstr ($errfile:$errline)\n";
+               echo "  Fatal error on line $errline in file $errfile";
+               echo ", PHP " . PHP_VERSION . " (" . PHP_OS . ")\n";
+               echo "Aborting...\n";
+               exit(1);
+               break;
 
-    case E_USER_WARNING:
-       echo "WARNING [$errno] $errstr ($errfile:$errline)\n";
-       break;
+        case E_USER_WARNING:
+               echo "WARNING [$errno] $errstr ($errfile:$errline)\n";
+               break;
 
      case E_USER_NOTICE:
-       echo "My NOTICE [$errno] $errstr ($errfile:$errline)\n";
-       break;
-
-     default:
-       echo "Unknown error type: [$errno] $errstr ($errfile:$errline)\n";
-       break;
+               echo "NOTICE [$errno] $errstr ($errfile:$errline)\n";
+               break;
     }
 
     /* Don't execute PHP internal error handler */
@@ -55,6 +51,10 @@ if (isset($_SERVER) && array_key_exists('REQUEST_METHOD', $_SERVER)) {
 
 define('INSTALLDIR', realpath(dirname(__FILE__) . '/..'));
 define('LACONICA', true);
+define('CLAIM_TIMEOUT', 100000);
+
+define('MAX_BROADCAST_COUNT', 20);
+define('MAX_CONFIRM_COUNT', 20);
 
 require_once(INSTALLDIR . '/lib/common.php');
 require_once(INSTALLDIR . '/lib/jabber.php');
@@ -99,40 +99,22 @@ class XMPPDaemon {
 
        function handle() {
 
-               static $parts = array('message', 'presence',
-                                                         'end_stream', 'session_start');
-
+               $this->conn->addEventHandler('message', 'handle_message', $this);
+               $this->conn->addEventHandler('presence', 'handle_presence', $this);
+               $this->conn->addEventHandler('session_start', 'handle_session_start', $this);
+               
                while(!$this->conn->isDisconnected()) {
-
-                       $payloads = $this->conn->processUntil($parts, 10);
-
-                       if ($payloads) {
-                               foreach($payloads as $event) {
-                                       $pl = $event[1];
-                                       switch($event[0]) {
-                                        case 'message':
-                                               $this->handle_message($pl);
-                                               break;
-                                        case 'presence':
-                                               $this->handle_presence($pl);
-                                               break;
-                                        case 'session_start':
-                                               $this->handle_session($pl);
-                                               break;
-                                       }
-                               }
-                       }
-
+                       $this->conn->processTime(5);
                        $this->broadcast_queue();
                        $this->confirmation_queue();
                }
        }
 
-       function handle_session($pl) {
-               # XXX what to do here?
-               return true;
+       function handle_session_start(&$pl) {
+               $this->conn->getRoster();
+               $this->set_status("Send me a message to post a notice");
        }
-
+       
        function get_user($from) {
                $user = User::staticGet('jabber', jabber_normalize_jid($from));
                return $user;
@@ -153,7 +135,7 @@ class XMPPDaemon {
                if ($pl['type'] != 'chat') {
                        return;
                }
-               if (strlen($pl['body']) == 0) {
+               if (mb_strlen($pl['body']) == 0) {
                        return;
                }
 
@@ -176,6 +158,11 @@ class XMPPDaemon {
                        $this->log(LOG_INFO, 'Ignoring OTR from ' . $from);
                        return;
                } else {
+                       $len = mb_strlen($pl['body']);
+                       if($len > 140) {
+                               $this->from_site($from, 'Message too long - maximum is 140 characters, you sent ' . $len);
+                               return;
+                       }
                        $this->add_notice($user, $pl);
                }
        }
@@ -195,7 +182,7 @@ class XMPPDaemon {
                        return false;
                }
        }
-       
+
        function from_site($address, $msg) {
                $text = '['.common_config('site', 'name') . '] ' . $msg;
                jabber_send_message($address, $text);
@@ -203,15 +190,49 @@ class XMPPDaemon {
 
        function handle_command($user, $body) {
                # XXX: localise
-               switch(trim($body)) {
+               $p=explode(' ',$body);
+               if(count($p)>2)
+                       return false;
+               switch($p[0]) {
+                case 'help':
+                       if(count($p)!=1)
+                               return false;
+                       $this->from_site($user->jabber, "Commands:\n on     - turn on notifications\n off    - turn off notifications\n help   - show this help \n sub - subscribe to user\n unsub - unsubscribe from user");
+                       return true;
                 case 'on':
+                       if(count($p)!=1)
+                               return false;
                        $this->set_notify($user, true);
                        $this->from_site($user->jabber, 'notifications on');
                        return true;
                 case 'off':
+                       if(count($p)!=1)
+                               return false;
                        $this->set_notify($user, false);
                        $this->from_site($user->jabber, 'notifications off');
                        return true;
+                case 'sub':
+                       if(count($p)==1) {
+                               $this->from_site($user->jabber, 'Specify the name of the user to subscribe to');
+                               return true;
+                       }
+                       $result=subs_subscribe_user($user, $p[1]);
+                       if($result=='true')
+                               $this->from_site($user->jabber, 'Subscribed to ' . $p[1]);
+                       else
+                               $this->from_site($user->jabber, $result);
+                       return true;
+                case 'unsub':
+                       if(count($p)==1) {
+                               $this->from_site($user->jabber, 'Specify the name of the user to unsubscribe from');
+                               return true;
+                       }
+                       $result=subs_unsubscribe_user($user, $p[1]);
+                       if($result=='true')
+                               $this->from_site($user->jabber, 'Unsubscribed from ' . $p[1]);
+                       else
+                               $this->from_site($user->jabber, $result);
+                       return true;
                 default:
                        return false;
                }
@@ -221,7 +242,7 @@ class XMPPDaemon {
                $orig = clone($user);
                $user->jabbernotify = $notify;
                $result = $user->update($orig);
-               if (!$id) {
+               if (!$result) {
                        $last_error = &PEAR::getStaticProperty('DB_DataObject','lastError');
                        $this->log(LOG_ERR,
                                           'Could not set notify flag to ' . $notify .
@@ -305,7 +326,7 @@ class XMPPDaemon {
                        # (or old)?
                        $this->log(LOG_INFO, 'claiming queue item = ' . $qi->notice_id);
                        $orig = clone($qi);
-                       $qi->claimed = DB_DataObject_Cast::dateTime();
+                       $qi->claimed = common_sql_now();
                        $result = $qi->update($orig);
                        if ($result) {
                                $this->log(LOG_INFO, 'claim succeeded.');
@@ -321,6 +342,7 @@ class XMPPDaemon {
        function broadcast_queue() {
                $this->clear_old_claims();
                $this->log(LOG_INFO, 'checking for queued notices');
+               $cnt = 0;
                do {
                        $qi = $this->top_queue_item();
                        if ($qi) {
@@ -344,8 +366,9 @@ class XMPPDaemon {
                                        $this->log(LOG_WARNING, 'queue item for notice that does not exist');
                                }
                                $qi->delete();
+                               $cnt++;
                        }
-               } while ($qi);
+               } while ($qi && $cnt < MAX_BROADCAST_COUNT);
        }
 
        function clear_old_claims() {
@@ -363,6 +386,7 @@ class XMPPDaemon {
        function confirmation_queue() {
            # $this->clear_old_confirm_claims();
                $this->log(LOG_INFO, 'checking for queued confirmations');
+               $cnt = 0;
                do {
                        $confirm = $this->next_confirm();
                        if ($confirm) {
@@ -391,8 +415,9 @@ class XMPPDaemon {
                                                continue;
                                        }
                                }
+                               $cnt++;
                        }
-               } while ($confirm);
+               } while ($confirm && $cnt < MAX_CONFIRM_COUNT);
        }
 
        function next_confirm() {
@@ -408,7 +433,7 @@ class XMPPDaemon {
                        # working around some weird DB_DataObject behaviour
                        $confirm->whereAdd(''); # clears where stuff
                        $original = clone($confirm);
-                       $confirm->claimed = DB_DataObject_Cast::dateTime();
+                       $confirm->claimed = common_sql_now();
                        $result = $confirm->update($original);
                        if ($result) {
                                $this->log(LOG_INFO, 'Succeeded in claim! '. $result);
@@ -430,6 +455,8 @@ class XMPPDaemon {
 
 }
 
+mb_internal_encoding('UTF-8');
+
 $resource = ($argc > 1) ? $argv[1] : NULL;
 
 $daemon = new XMPPDaemon($resource);