* Indenting and formatting.
[lhc/web/wiklou.git] / includes / User.php
index d0ac0d5..018324f 100644 (file)
@@ -251,8 +251,8 @@ class User {
         * just slightly outta sync and soon corrected - safer to block slightly more that less.
         * And it's cheaper to check slave first, then master if needed, than master always.
         */
-       function getBlockedStatus( $bFromSlave = false ) {
-               global $wgIP, $wgBlockCache, $wgProxyList;
+       function getBlockedStatus() {
+               global $wgIP, $wgBlockCache, $wgProxyList, $wgEnableSorbs, $bFromSlave;
 
                if ( -1 != $this->mBlockedby ) { return; }
 
@@ -265,6 +265,7 @@ class User {
                        if ( $block->load( $wgIP , $this->mId ) ) {
                                $this->mBlockedby = $block->mBy;
                                $this->mBlockreason = $block->mReason;
+                               $this->spreadBlock();
                        }
                }
 
@@ -272,7 +273,7 @@ class User {
                if ( !$this->mBlockedby ) {
                        # Check first against slave, and optionally from master.
                        $block = $wgBlockCache->get( $wgIP, true );
-                       if ( !block && !$bFromSlave )
+                       if ( !$block && !$bFromSlave )
                                {
                                # Not blocked: check against master, to make sure.
                                $wgBlockCache->clearLocal( );
@@ -291,8 +292,46 @@ class User {
                                $this->mBlockreason = wfMsg( 'proxyblockreason' );
                        }
                }
+
+               # DNSBL
+               if ( !$this->mBlockedby && $wgEnableSorbs ) {
+                       if ( $this->inSorbsBlacklist( $wgIP ) ) {
+                               $this->mBlockedby = wfMsg( 'sorbs' );
+                               $this->mBlockreason = wfMsg( 'sorbsreason' );
+                       }
+               }
+                       
        }
 
+       function inSorbsBlacklist( $ip ) {
+               $fname = 'User::inSorbsBlacklist';
+               wfProfileIn( $fname );
+               
+               $found = false;
+               $host = '';
+               
+               if ( preg_match( '/^(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})$/', $ip, $m ) ) {
+                       # Make hostname
+                       for ( $i=4; $i>=1; $i-- ) {
+                               $host .= $m[$i] . '.';
+                       }
+                       $host .= 'http.dnsbl.sorbs.net.';
+
+                       # Send query
+                       $ipList = gethostbynamel( $host );
+                       
+                       if ( $ipList ) {
+                               wfDebug( "Hostname $host is {$ipList[0]}, it's a proxy!\n" );
+                               $found = true;
+                       } else {
+                               wfDebug( "Requested $host, not found.\n" );
+                       }
+               }
+
+               wfProfileOut( $fname );
+               return $found;
+       }
+       
        /**
         * Check if user is blocked
         * @return bool True if blocked, false otherwise
@@ -392,7 +431,6 @@ class User {
                                else
                                        wfDebug( "User::loadFromSession() unable to save to memcached\n" );
                        }
-                       $user->spreadBlock();
                        return $user;
                }
                return new User(); # Can't log in from session
@@ -592,13 +630,16 @@ class User {
 
        # Set the random token (used for persistent authentication)
        function setToken( $token = false ) {
+               global $wgSecretKey, $wgProxyKey, $wgDBname;
                if ( !$token ) {
-                       $this->mToken = '';
-                       # Take random data from PRNG
-                       # This is reasonably secure if the PRNG has been seeded correctly
-                       for ($i = 0; $i<USER_TOKEN_LENGTH / 4; $i++) {
-                               $this->mToken .= sprintf( "%04X", mt_rand( 0, 65535 ) );
+                       if ( $wgSecretKey ) {
+                               $key = $wgSecretKey;
+                       } elseif ( $wgProxyKey ) {
+                               $key = $wgProxyKey;
+                       } else {
+                               $key = microtime();
                        }
+                       $this->mToken = md5( $wgSecretKey . mt_rand( 0, 0x7fffffff ) . $wgDBname . $this->mId );
                } else {
                        $this->mToken = $token;
                }
@@ -681,41 +722,43 @@ class User {
                $this->invalidateCache();
        }
 
+       /**
+        * A more legible check for non-anonymousness.
+        * Returns true if the user is not an anonymous visitor.
+        *
+        * @return bool
+        */
+       function isLoggedIn() {
+               return( $this->getID() != 0 );
+       }
+       
+       /**
+        * A more legible check for anonymousness.
+        * Returns true if the user is an anonymous visitor.
+        *
+        * @return bool
+        */
+       function isAnon() {
+               return !$this->isLoggedIn();
+       }
+       
        /**
         * Check if a user is sysop
         * Die with backtrace. Use User:isAllowed() instead.
         * @deprecated
         */
        function isSysop() {
-       /**
-               $this->loadFromDatabase();
-               if ( 0 == $this->mId ) { return false; }
-
-               return in_array( 'sysop', $this->mRights );
-       */
-       wfDebugDieBacktrace("User::isSysop() is deprecated. Use User::isAllowed() instead");
+               wfDebugDieBacktrace("User::isSysop() is deprecated. Use User::isAllowed() instead");
        }
 
        /** @deprecated */
        function isDeveloper() {
-       /**
-               $this->loadFromDatabase();
-               if ( 0 == $this->mId ) { return false; }
-
-               return in_array( 'developer', $this->mRights );
-       */
-       wfDebugDieBacktrace("User::isDeveloper() is deprecated. Use User::isAllowed() instead");
+               wfDebugDieBacktrace("User::isDeveloper() is deprecated. Use User::isAllowed() instead");
        }
 
        /** @deprecated */
        function isBureaucrat() {
-       /**
-               $this->loadFromDatabase();
-               if ( 0 == $this->mId ) { return false; }
-
-               return in_array( 'bureaucrat', $this->mRights );
-       */
-       wfDebugDieBacktrace("User::isBureaucrat() is deprecated. Use User::isAllowed() instead");
+               wfDebugDieBacktrace("User::isBureaucrat() is deprecated. Use User::isAllowed() instead");
        }
 
        /**
@@ -843,7 +886,7 @@ class User {
                $dbw =& wfGetDB( DB_MASTER );
                $success = $dbw->update( 'watchlist',
                                array( /* SET */
-                                       'wl_notificationtimestamp' => $dbw->timestamp(0)
+                                       'wl_notificationtimestamp' => 0
                                ), array( /* WHERE */
                                        'wl_title' => $title->getDBkey(),
                                        'wl_namespace' => $title->getNamespace(),
@@ -1112,11 +1155,8 @@ class User {
                // it will always be 0 when this function is called by parsercache.
 
                $confstr =        $this->getOption( 'math' );
-               $confstr .= '!' . $this->getOption( 'highlightbroken' );
                $confstr .= '!' . $this->getOption( 'stubthreshold' );
                $confstr .= '!' . $this->getOption( 'editsection' );
-               $confstr .= '!' . $this->getOption( 'editsectiononrightclick' );
-               $confstr .= '!' . $this->getOption( 'showtoc' );
                $confstr .= '!' . $this->getOption( 'date' );
                $confstr .= '!' . $this->getOption( 'numberheadings' );
                $confstr .= '!' . $this->getOption( 'language' );
@@ -1148,9 +1188,26 @@ class User {
                return wfSetVar( $this->mDataLoaded, $loaded );
        }
 
+       /**
+        * Get this user's personal page title.
+        *
+        * @return Title
+        * @access public
+        */
        function getUserPage() {
                return Title::makeTitle( NS_USER, $this->mName );
        }
+       
+       /**
+        * Get this user's talk page title.
+        *
+        * @return Title
+        * @access public
+        */
+       function getTalkPage() {
+               $title = $this->getUserPage();
+               return $title->getTalkPage();
+       }
 
        /**
         * @static
@@ -1210,15 +1267,22 @@ class User {
         * login credentials aren't being hijacked with a foreign form
         * submission.
         *
+        * @param mixed $salt - Optional function-specific data for hash.
+        *                      Use a string or an array of strings.
         * @return string
         * @access public
         */
-       function editToken() {
+       function editToken( $salt = '' ) {
                if( !isset( $_SESSION['wsEditToken'] ) ) {
                        $token = dechex( mt_rand() ) . dechex( mt_rand() );
                        $_SESSION['wsEditToken'] = $token;
+               } else {
+                       $token = $_SESSION['wsEditToken'];
+               }
+               if( is_array( $salt ) ) {
+                       $salt = implode( '|', $salt );
                }
-               return $_SESSION['wsEditToken'];
+               return md5( $token . $salt );
        }
        
        /**
@@ -1227,14 +1291,13 @@ class User {
         * user's own login session, not a form submission from a third-party
         * site.
         *
-        * @param string $val
+        * @param string $val - the input value to compare
+        * @param string $salt - Optional function-specific data for hash
         * @return bool
         * @access public
         */
-       function matchEditToken( $val ) {
-               if( !isset( $_SESSION['wsEditToken'] ) ) 
-                       return false;
-               return $_SESSION['wsEditToken'] == $val;
+       function matchEditToken( $val, $salt = '' ) {
+               return ( $val == $this->editToken( $salt ) );
        }
 }