@recaptime-dev's working patches + fork for Phorge, a community fork of Phabricator. (Upstream dev and stable branches are at upstream/main and upstream/stable respectively.) hq.recaptime.dev/wiki/Phorge
phorge phabricator
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Normalize remote IP addresses when writing to logs, etc

Summary:
Ref T11939. IPv4 addresses can normally only be written in one way, but IPv6 addresses have several formats.

For example, the addresses "FFF::", "FfF::", "fff::", "0ffF::", "0fFf:0::", and "0FfF:0:0:0:0:0:0:0" are all the same address.

Normalize all addresses before writing them to logs, etc, so we store the most-preferred form ("fff::", above).

Test Plan:
Ran an SSH clone over IPv6:

```
$ git fetch ssh://local@::1/diffusion/26/locktopia.git
```

It worked; verified that address read out of `SSH_CLIENT` sensibly.

Faked my remote address as a non-preferred-form IPv6 address using `preamble.php`.

Failed to login, verified that the preferred-form version of the address appeared in the user activity log.

Made IPv6 requests over HTTP:

```
$ curl -H "Host: local.phacility.com" "http://[::1]/"
```

Reviewers: chad

Reviewed By: chad

Maniphest Tasks: T11939

Differential Revision: https://secure.phabricator.com/D16987

+49 -10
+5 -3
src/aphront/AphrontRequest.php
··· 557 557 } 558 558 559 559 public function getRemoteAddress() { 560 - $address = $_SERVER['REMOTE_ADDR']; 561 - if (!strlen($address)) { 560 + $address = PhabricatorEnv::getRemoteAddress(); 561 + 562 + if (!$address) { 562 563 return null; 563 564 } 564 - return substr($address, 0, 64); 565 + 566 + return $address->getAddress(); 565 567 } 566 568 567 569 public function isHTTPS() {
+9 -1
src/aphront/configuration/AphrontApplicationConfiguration.php
··· 106 106 PhabricatorAccessLog::init(); 107 107 $access_log = PhabricatorAccessLog::getLog(); 108 108 PhabricatorStartup::setAccessLog($access_log); 109 + 110 + $address = PhabricatorEnv::getRemoteAddress(); 111 + if ($address) { 112 + $address_string = $address->getAddress(); 113 + } else { 114 + $address_string = '-'; 115 + } 116 + 109 117 $access_log->setData( 110 118 array( 111 119 'R' => AphrontRequest::getHTTPHeader('Referer', '-'), 112 - 'r' => idx($_SERVER, 'REMOTE_ADDR', '-'), 120 + 'r' => $address_string, 113 121 'M' => idx($_SERVER, 'REQUEST_METHOD', '-'), 114 122 )); 115 123
+13 -3
src/applications/people/storage/PhabricatorUserLog.php
··· 108 108 $log->setUserPHID((string)$object_phid); 109 109 $log->setAction($action); 110 110 111 - $log->remoteAddr = (string)idx($_SERVER, 'REMOTE_ADDR', ''); 111 + $address = PhabricatorEnv::getRemoteAddress(); 112 + if ($address) { 113 + $log->remoteAddr = $address->getAddress(); 114 + } else { 115 + $log->remoteAddr = ''; 116 + } 112 117 113 118 return $log; 114 119 } 115 120 116 121 public static function loadRecentEventsFromThisIP($action, $timespan) { 122 + $address = PhabricatorEnv::getRemoteAddress(); 123 + if (!$address) { 124 + return array(); 125 + } 126 + 117 127 return id(new PhabricatorUserLog())->loadAllWhere( 118 128 'action = %s AND remoteAddr = %s AND dateCreated > %d 119 129 ORDER BY dateCreated DESC', 120 130 $action, 121 - idx($_SERVER, 'REMOTE_ADDR'), 122 - time() - $timespan); 131 + $address->getAddress(), 132 + PhabricatorTime::getNow() - $timespan); 123 133 } 124 134 125 135 public function save() {
+15 -2
src/infrastructure/env/PhabricatorEnv.php
··· 818 818 return false; 819 819 } 820 820 821 - $address = idx($_SERVER, 'REMOTE_ADDR'); 821 + $address = self::getRemoteAddress(); 822 822 if (!$address) { 823 823 throw new Exception( 824 824 pht( 825 825 'Unable to test remote address against cluster whitelist: '. 826 - 'REMOTE_ADDR is not defined.')); 826 + 'REMOTE_ADDR is not defined or not valid.')); 827 827 } 828 828 829 829 return self::isClusterAddress($address); ··· 842 842 843 843 return PhutilCIDRList::newList($cluster_addresses) 844 844 ->containsAddress($address); 845 + } 846 + 847 + public static function getRemoteAddress() { 848 + $address = idx($_SERVER, 'REMOTE_ADDR'); 849 + if (!$address) { 850 + return null; 851 + } 852 + 853 + try { 854 + return PhutilIPAddress::newAddress($address); 855 + } catch (Exception $ex) { 856 + return null; 857 + } 845 858 } 846 859 847 860 /* -( Internals )---------------------------------------------------------- */
+7 -1
src/infrastructure/ssh/PhabricatorSSHWorkflow.php
··· 95 95 // This has the format "<ip> <remote-port> <local-port>". Grab the IP. 96 96 $remote_address = head(explode(' ', $ssh_client)); 97 97 98 - return $remote_address; 98 + try { 99 + $address = PhutilIPAddress::newAddress($remote_address); 100 + } catch (Exception $ex) { 101 + return null; 102 + } 103 + 104 + return $address->getAddress(); 99 105 } 100 106 101 107 }