private function getBareHostAndPort($host)
 {
     // Split out port information, since the command-line client requires a
     // separate flag for the port.
     $uri = new PhutilURI('mysql://' . $host);
     if ($uri->getPort()) {
         $port = $uri->getPort();
         $bare_hostname = $uri->getDomain();
     } else {
         $port = null;
         $bare_hostname = $host;
     }
     return array($bare_hostname, $port);
 }
 protected function getProxyCommand()
 {
     $uri = new PhutilURI($this->proxyURI);
     $username = AlmanacKeys::getClusterSSHUser();
     if ($username === null) {
         throw new Exception(pht('Unable to determine the username to connect with when trying ' . 'to proxy an SSH request within the Phabricator cluster.'));
     }
     $port = $uri->getPort();
     $host = $uri->getDomain();
     $key_path = AlmanacKeys::getKeyPath('device.key');
     if (!Filesystem::pathExists($key_path)) {
         throw new Exception(pht('Unable to proxy this SSH request within the cluster: this device ' . 'is not registered and has a missing device key (expected to ' . 'find key at "%s").', $key_path));
     }
     $options = array();
     $options[] = '-o';
     $options[] = 'StrictHostKeyChecking=no';
     $options[] = '-o';
     $options[] = 'UserKnownHostsFile=/dev/null';
     // This is suppressing "added <address> to the list of known hosts"
     // messages, which are confusing and irrelevant when they arise from
     // proxied requests. It might also be suppressing lots of useful errors,
     // of course. Ideally, we would enforce host keys eventually.
     $options[] = '-o';
     $options[] = 'LogLevel=quiet';
     // NOTE: We prefix the command with "@username", which the far end of the
     // connection will parse in order to act as the specified user. This
     // behavior is only available to cluster requests signed by a trusted
     // device key.
     return csprintf('ssh %Ls -l %s -i %s -p %s %s -- %s %Ls', $options, $username, $key_path, $port, $host, '@' . $this->getUser()->getUsername(), $this->getOriginalArguments());
 }
Example #3
0
 /**
  * Makes sure a given custom blog uri is properly configured in DNS
  * to point at this Phabricator instance. If there is an error in
  * the configuration, return a string describing the error and how
  * to fix it. If there is no error, return an empty string.
  *
  * @return string
  */
 public function validateCustomDomain($custom_domain)
 {
     $example_domain = 'blog.example.com';
     $label = pht('Invalid');
     // note this "uri" should be pretty busted given the desired input
     // so just use it to test if there's a protocol specified
     $uri = new PhutilURI($custom_domain);
     if ($uri->getProtocol()) {
         return array($label, pht('The custom domain should not include a protocol. Just provide ' . 'the bare domain name (for example, "%s").', $example_domain));
     }
     if ($uri->getPort()) {
         return array($label, pht('The custom domain should not include a port number. Just provide ' . 'the bare domain name (for example, "%s").', $example_domain));
     }
     if (strpos($custom_domain, '/') !== false) {
         return array($label, pht('The custom domain should not specify a path (hosting a Phame ' . 'blog at a path is currently not supported). Instead, just provide ' . 'the bare domain name (for example, "%s").', $example_domain));
     }
     if (strpos($custom_domain, '.') === false) {
         return array($label, pht('The custom domain should contain at least one dot (.) because ' . 'some browsers fail to set cookies on domains without a dot. ' . 'Instead, use a normal looking domain name like "%s".', $example_domain));
     }
     if (!PhabricatorEnv::getEnvConfig('policy.allow-public')) {
         $href = PhabricatorEnv::getProductionURI('/config/edit/policy.allow-public/');
         return array(pht('Fix Configuration'), pht('For custom domains to work, this Phabricator instance must be ' . 'configured to allow the public access policy. Configure this ' . 'setting %s, or ask an administrator to configure this setting. ' . 'The domain can be specified later once this setting has been ' . 'changed.', phutil_tag('a', array('href' => $href), pht('here'))));
     }
     return null;
 }
 public function getWikiURI()
 {
     $config = $this->getProviderConfig();
     $uri = $config->getProperty(self::PROPERTY_MEDIAWIKI_URI);
     $uri = new PhutilURI($uri);
     $normalized = $uri->getProtocol() . '://' . $uri->getDomain();
     if ($uri->getPort() != 80 && $uri->getPort() != 443) {
         $normalized .= ':' . $uri->getPort();
     }
     if (strlen($uri->getPath()) > 0 && $uri->getPath() !== '/') {
         $normalized .= $uri->getPath();
     }
     if (substr($normalized, -1) == '/') {
         $normalized = substr($normalized, 0, -1);
     }
     return $normalized;
 }
 public function testURIParsing()
 {
     $uri = new PhutilURI('http://*****:*****@host:99/path/?query=value#fragment');
     $this->assertEqual('http', $uri->getProtocol(), pht('protocol'));
     $this->assertEqual('user', $uri->getUser(), pht('user'));
     $this->assertEqual('pass', $uri->getPass(), pht('password'));
     $this->assertEqual('host', $uri->getDomain(), pht('domain'));
     $this->assertEqual('99', $uri->getPort(), pht('port'));
     $this->assertEqual('/path/', $uri->getPath(), pht('path'));
     $this->assertEqual(array('query' => 'value'), $uri->getQueryParams(), 'query params');
     $this->assertEqual('fragment', $uri->getFragment(), pht('fragment'));
     $this->assertEqual('http://*****:*****@host:99/path/?query=value#fragment', (string) $uri, 'uri');
     $uri = new PhutilURI('ssh://git@example.com/example/example.git');
     $this->assertEqual('ssh', $uri->getProtocol(), pht('protocol'));
     $this->assertEqual('git', $uri->getUser(), pht('user'));
     $this->assertEqual('', $uri->getPass(), pht('password'));
     $this->assertEqual('example.com', $uri->getDomain(), pht('domain'));
     $this->assertEqual('', $uri->getPort(), 'port');
     $this->assertEqual('/example/example.git', $uri->getPath(), pht('path'));
     $this->assertEqual(array(), $uri->getQueryParams(), pht('query parameters'));
     $this->assertEqual('', $uri->getFragment(), pht('fragment'));
     $this->assertEqual('ssh://git@example.com/example/example.git', (string) $uri, 'uri');
     $uri = new PhutilURI('http://0@domain.com/');
     $this->assertEqual('0', $uri->getUser());
     $this->assertEqual('http://0@domain.com/', (string) $uri);
     $uri = new PhutilURI('http://*****:*****@domain.com/');
     $this->assertEqual('0', $uri->getUser());
     $this->assertEqual('0', $uri->getPass());
     $this->assertEqual('http://*****:*****@domain.com/', (string) $uri);
     $uri = new PhutilURI('http://%20:%20@domain.com/');
     $this->assertEqual(' ', $uri->getUser());
     $this->assertEqual(' ', $uri->getPass());
     $this->assertEqual('http://%20:%20@domain.com/', (string) $uri);
     $uri = new PhutilURI('http://%40:%40@domain.com/');
     $this->assertEqual('@', $uri->getUser());
     $this->assertEqual('@', $uri->getPass());
     $this->assertEqual('http://%40:%40@domain.com/', (string) $uri);
     // These tests are covering cases where cURL and parse_url() behavior
     // may differ in potentially dangerous ways. See T6755 for discussion.
     // In general, we defuse these attacks by emitting URIs which escape
     // special characters so that they are interpreted unambiguously by
     // cURL in the same way that parse_url() interpreted them.
     $uri = new PhutilURI('http://*****:*****@evil.com?@good.com');
     $this->assertEqual('u', $uri->getUser());
     $this->assertEqual('p', $uri->getPass());
     $this->assertEqual('evil.com', $uri->getDomain());
     $this->assertEqual('http://*****:*****@evil.com?%40good.com=', (string) $uri);
     $uri = new PhutilURI('http://good.com#u:p@evil.com/');
     $this->assertEqual('good.com#u', $uri->getUser());
     $this->assertEqual('p', $uri->getPass());
     $this->assertEqual('evil.com', $uri->getDomain());
     $this->assertEqual('http://good.com%23u:p@evil.com/', (string) $uri);
     $uri = new PhutilURI('http://good.com?u:p@evil.com/');
     $this->assertEqual('', $uri->getUser());
     $this->assertEqual('', $uri->getPass());
     $this->assertEqual('good.com', $uri->getDomain());
     $this->assertEqual('http://good.com?u%3Ap%40evil.com%2F=', (string) $uri);
 }
 protected final function launch($debug = false)
 {
     $console = PhutilConsole::getConsole();
     if ($debug) {
         $console->writeOut(pht("Starting Aphlict server in foreground...\n"));
     } else {
         Filesystem::writeFile($this->getPIDPath(), getmypid());
     }
     $server_uri = PhabricatorEnv::getEnvConfig('notification.server-uri');
     $server_uri = new PhutilURI($server_uri);
     $client_uri = PhabricatorEnv::getEnvConfig('notification.client-uri');
     $client_uri = new PhutilURI($client_uri);
     $user = PhabricatorEnv::getEnvConfig('notification.user');
     $log = PhabricatorEnv::getEnvConfig('notification.log');
     $server_argv = array();
     $server_argv[] = csprintf('--port=%s', $client_uri->getPort());
     $server_argv[] = csprintf('--admin=%s', $server_uri->getPort());
     $server_argv[] = csprintf('--host=%s', $server_uri->getDomain());
     if ($user) {
         $server_argv[] = csprintf('--user=%s', $user);
     }
     if (!$debug) {
         $server_argv[] = csprintf('--log=%s', $log);
     }
     $command = csprintf('%s %s %C', $this->getNodeBinary(), dirname(__FILE__) . '/../../../../support/aphlict/server/aphlict_server.js', implode(' ', $server_argv));
     if (!$debug) {
         declare (ticks=1);
         pcntl_signal(SIGINT, array($this, 'cleanup'));
         pcntl_signal(SIGTERM, array($this, 'cleanup'));
     }
     register_shutdown_function(array($this, 'cleanup'));
     if ($debug) {
         $console->writeOut("Launching server:\n\n    \$ " . $command . "\n\n");
         $err = phutil_passthru('%C', $command);
         $console->writeOut(">>> Server exited!\n");
         exit($err);
     } else {
         while (true) {
             global $g_future;
             $g_future = new ExecFuture('exec %C', $command);
             $g_future->resolve();
             // If the server exited, wait a couple of seconds and restart it.
             unset($g_future);
             sleep(2);
         }
     }
 }
Example #7
0
 public function testURIParsing()
 {
     $uri = new PhutilURI('http://*****:*****@host:99/path/?query=value#fragment');
     $this->assertEqual('http', $uri->getProtocol(), 'protocol');
     $this->assertEqual('user', $uri->getUser(), 'user');
     $this->assertEqual('pass', $uri->getPass(), 'pass');
     $this->assertEqual('host', $uri->getDomain(), 'domain');
     $this->assertEqual('99', $uri->getPort(), 'port');
     $this->assertEqual('/path/', $uri->getPath(), 'path');
     $this->assertEqual(array('query' => 'value'), $uri->getQueryParams(), 'query params');
     $this->assertEqual('fragment', $uri->getFragment(), 'fragment');
     $this->assertEqual('http://*****:*****@host:99/path/?query=value#fragment', (string) $uri, 'uri');
     $uri = new PhutilURI('ssh://git@example.com/example/example.git');
     $this->assertEqual('ssh', $uri->getProtocol(), 'protocol');
     $this->assertEqual('git', $uri->getUser(), 'user');
     $this->assertEqual('', $uri->getPass(), 'pass');
     $this->assertEqual('example.com', $uri->getDomain(), 'domain');
     $this->assertEqual('', $uri->getPort(), 'port');
     $this->assertEqual('/example/example.git', $uri->getPath(), 'path');
     $this->assertEqual(array(), $uri->getQueryParams(), 'query params');
     $this->assertEqual('', $uri->getFragment(), 'fragment');
     $this->assertEqual('ssh://git@example.com/example/example.git', (string) $uri, 'uri');
     $uri = new PhutilURI('http://0@domain.com/');
     $this->assertEqual('0', $uri->getUser());
     $this->assertEqual('http://0@domain.com/', (string) $uri);
     $uri = new PhutilURI('http://*****:*****@domain.com/');
     $this->assertEqual('0', $uri->getUser());
     $this->assertEqual('0', $uri->getPass());
     $this->assertEqual('http://*****:*****@domain.com/', (string) $uri);
     $uri = new PhutilURI('http://%20:%20@domain.com/');
     $this->assertEqual(' ', $uri->getUser());
     $this->assertEqual(' ', $uri->getPass());
     $this->assertEqual('http://%20:%20@domain.com/', (string) $uri);
     $uri = new PhutilURI('http://%40:%40@domain.com/');
     $this->assertEqual('@', $uri->getUser());
     $this->assertEqual('@', $uri->getPass());
     $this->assertEqual('http://%40:%40@domain.com/', (string) $uri);
 }
}
// Use always the version from the commandline if it is defined
$next_version = isset($options['v']) ? (int) $options['v'] : null;
$conf = DatabaseConfigurationProvider::getConfiguration();
if ($options['u']) {
    $conn_user = $options['u'];
    $conn_pass = $options['p'];
} else {
    $conn_user = $conf->getUser();
    $conn_pass = $conf->getPassword();
}
$conn_host = $conf->getHost();
// Split out port information, since the command-line client requires a
// separate flag for the port.
$uri = new PhutilURI('mysql://' . $conn_host);
if ($uri->getPort()) {
    $conn_port = $uri->getPort();
    $conn_bare_hostname = $uri->getDomain();
} else {
    $conn_port = null;
    $conn_bare_hostname = $conn_host;
}
$conn = new AphrontMySQLDatabaseConnection(array('user' => $conn_user, 'pass' => $conn_pass, 'host' => $conn_host, 'database' => null));
try {
    $create_sql = <<<END
  CREATE DATABASE IF NOT EXISTS `phabricator_meta_data`;
END;
    queryfx($conn, $create_sql);
    $create_sql = <<<END
  CREATE TABLE IF NOT EXISTS phabricator_meta_data.`schema_version` (
    `version` INTEGER not null
 private function getForcedPort()
 {
     $protocol = $this->getBuiltinProtocol();
     if ($protocol == self::BUILTIN_PROTOCOL_SSH) {
         return PhabricatorEnv::getEnvConfig('diffusion.ssh-port');
     }
     // If Phabricator is running on a nonstandard port, use that as the defualt
     // port for URIs with the same protocol.
     $is_http = $protocol == self::BUILTIN_PROTOCOL_HTTP;
     $is_https = $protocol == self::BUILTIN_PROTOCOL_HTTPS;
     if ($is_http || $is_https) {
         $uri = PhabricatorEnv::getURI('/');
         $uri = new PhutilURI($uri);
         $port = $uri->getPort();
         if (!$port) {
             return null;
         }
         $uri_protocol = $uri->getProtocol();
         $use_port = $is_http && $uri_protocol == 'http' || $is_https && $uri_protocol == 'https';
         if (!$use_port) {
             return null;
         }
         return $port;
     }
     return null;
 }
Example #10
0
list($err) = exec_manual('node -v');
if ($err) {
    throw new Exception('`node` is not in $PATH. You must install Node.js to run the Aphlict ' . 'server.');
}
$server_uri = PhabricatorEnv::getEnvConfig('notification.server-uri');
$server_uri = new PhutilURI($server_uri);
$client_uri = PhabricatorEnv::getEnvConfig('notification.client-uri');
$client_uri = new PhutilURI($client_uri);
$user = PhabricatorEnv::getEnvConfig('notification.user');
$log = PhabricatorEnv::getEnvConfig('notification.log');
$g_pidfile = PhabricatorEnv::getEnvConfig('notification.pidfile');
$g_future = null;
$foreground = $args->getArg('foreground');
// Build the argument list for the server itself.
$server_argv = array();
$server_argv[] = csprintf('--port=%s', $client_uri->getPort());
$server_argv[] = csprintf('--admin=%s', $server_uri->getPort());
if ($user) {
    $server_argv[] = csprintf('--user=%s', $user);
}
if ($log) {
    $server_argv[] = csprintf('--log=%s', $log);
}
// >>> Foreground / Background -------------------------------------------------
// If we start in the foreground, we use phutil_passthru() below to show any
// output from the server to the console, but this means *this* process won't
// receive signals until the child exits. If we write our pid to the pidfile
// and then another process starts, it will try to SIGTERM us but we won't
// receive the signal. Since the effect is the same and this is simpler, just
// ignore the pidfile if launched in `--foreground` mode; this is a debugging
// mode anyway.
Example #11
0
 /**
  * Build a string describing the host for this request.
  *
  * This method builds strings in two modes: with explicit ports for request
  * signing (which always include the port number) and with implicit ports
  * for use in the "Host:" header of requests (which omit the port number if
  * the port is the same as the default port for the protocol).
  *
  * This implicit port behavior is similar to what browsers do, so it is less
  * likely to get us into trouble with webserver configurations.
  *
  * @param bool True to include the port explicitly.
  * @return string String describing the host for the request.
  */
 private function newHostString($with_explicit_port)
 {
     $host = $this->getHost();
     $uri = new PhutilURI($this->uri);
     $protocol = $uri->getProtocol();
     $port = $uri->getPort();
     $implicit_ports = array('https' => 443);
     $default_port = 80;
     $implicit_port = idx($implicit_ports, $protocol, $default_port);
     if ($with_explicit_port) {
         if (!$port) {
             $port = $implicit_port;
         }
     } else {
         if ($port == $implicit_port) {
             $port = null;
         }
     }
     if (!$port) {
         $result = $host;
     } else {
         $result = $host . ':' . $port;
     }
     return $result;
 }
 protected function getBody()
 {
     $console = $this->getConsole();
     $tabs = array();
     foreach ($this->tabs as $name => $tab) {
         $tab_markup = phutil_render_tag('a', array('href' => idx($tab, 'href')), phutil_escape_html(idx($tab, 'name')));
         $tab_markup = phutil_render_tag('td', array('class' => $name == $this->selectedTab ? 'phabricator-selected-tab' : null), $tab_markup);
         $tabs[] = $tab_markup;
     }
     $tabs = implode('', $tabs);
     $login_stuff = null;
     $request = $this->getRequest();
     $user = null;
     if ($request) {
         $user = $request->getUser();
         // NOTE: user may not be set here if we caught an exception early
         // in the execution workflow.
         if ($user && $user->getPHID()) {
             $login_stuff = phutil_render_tag('a', array('href' => '/p/' . $user->getUsername() . '/'), phutil_escape_html($user->getUsername())) . ' &middot; ' . '<a href="/settings/">Settings</a>' . ' &middot; ' . phabricator_render_form($user, array('action' => '/search/', 'method' => 'post', 'style' => 'display: inline'), '<input type="text" name="query" id="standard-search-box" />' . ' in ' . AphrontFormSelectControl::renderSelectTag($this->getSearchDefaultScope(), PhabricatorSearchScope::getScopeOptions(), array('name' => 'scope')) . ' ' . '<button>Search</button>');
         }
     }
     $foot_links = array();
     $version = PhabricatorEnv::getEnvConfig('phabricator.version');
     $foot_links[] = phutil_escape_html('Phabricator ' . $version);
     $foot_links[] = '<a href="https://secure.phabricator.com/maniphest/task/create/">' . 'Report a Bug' . '</a>';
     if (PhabricatorEnv::getEnvConfig('darkconsole.enabled') && !PhabricatorEnv::getEnvConfig('darkconsole.always-on')) {
         if ($console) {
             $link = javelin_render_tag('a', array('href' => '/~/', 'sigil' => 'workflow'), 'Disable DarkConsole');
         } else {
             $link = javelin_render_tag('a', array('href' => '/~/', 'sigil' => 'workflow'), 'Enable DarkConsole');
         }
         $foot_links[] = $link;
     }
     if ($user && $user->getPHID()) {
         // This ends up very early in tab order at the top of the page and there's
         // a bunch of junk up there anyway, just shove it down here.
         $foot_links[] = phabricator_render_form($user, array('action' => '/logout/', 'method' => 'post', 'style' => 'display: inline'), '<button class="link">Logout</button>');
     }
     $foot_links = implode(' &middot; ', $foot_links);
     $admin_class = null;
     if ($this->getIsAdminInterface()) {
         $admin_class = 'phabricator-admin-page-view';
     }
     $custom_logo = null;
     $with_custom = null;
     $custom_conf = PhabricatorEnv::getEnvConfig('phabricator.custom.logo');
     if ($custom_conf) {
         $with_custom = 'phabricator-logo-with-custom';
         $custom_logo = phutil_render_tag('a', array('class' => 'logo-custom', 'href' => $custom_conf), ' ');
     }
     $notification_indicator = '';
     $notification_dropdown = '';
     $notification_container = '';
     if (PhabricatorEnv::getEnvConfig('notification.enabled') && $user && $user->isLoggedIn()) {
         $aphlict_object_id = 'aphlictswfobject';
         $client_uri = PhabricatorEnv::getEnvConfig('notification.client-uri');
         $client_uri = new PhutilURI($client_uri);
         if ($client_uri->getDomain() == 'localhost') {
             $this_host = $this->getRequest()->getHost();
             $this_host = new PhutilURI('http://' . $this_host . '/');
             $client_uri->setDomain($this_host->getDomain());
         }
         $enable_debug = PhabricatorEnv::getEnvConfig('notification.debug');
         Javelin::initBehavior('aphlict-listen', array('id' => $aphlict_object_id, 'server' => $client_uri->getDomain(), 'port' => $client_uri->getPort(), 'debug' => $enable_debug, 'pageObjects' => array_fill_keys($this->pageObjects, true)));
         Javelin::initBehavior('aphlict-dropdown', array());
         $notification_count = id(new PhabricatorFeedStoryNotification())->countUnread($user);
         $indicator_classes = array('phabricator-notification-indicator');
         if ($notification_count) {
             $indicator_classes[] = 'phabricator-notification-indicator-unread';
         }
         $notification_indicator = javelin_render_tag('div', array('id' => 'phabricator-notification-indicator', 'class' => implode(' ', $indicator_classes)), $notification_count);
         $notification_indicator = javelin_render_tag('div', array('id' => 'phabricator-notification-menu', 'class' => 'phabricator-icon-menu icon-menu-notifications', 'sigil' => 'aphlict-indicator'), $notification_indicator);
         $notification_indicator = javelin_render_tag('td', array('class' => 'phabricator-icon-menu-cell'), $notification_indicator);
         $notification_container = '<div id="aphlictswf-container" style="height:0px; width:0px;">' . '</div>';
         $notification_dropdown = javelin_render_tag('div', array('sigil' => 'aphlict-dropdown', 'id' => 'phabricator-notification-dropdown', 'style' => 'display: none'), '');
     }
     $header_chrome = null;
     $footer_chrome = null;
     if ($this->getShowChrome()) {
         $header_chrome = '<table class="phabricator-standard-header">' . '<tr>' . '<td class="phabricator-logo ' . $with_custom . '">' . $custom_logo . '<a class="logo-standard" href="/"> </a>' . '</td>' . $notification_indicator . '<td>' . '<table class="phabricator-primary-navigation">' . '<tr>' . '<th>' . phutil_render_tag('a', array('href' => $this->getBaseURI(), 'class' => 'phabricator-head-appname'), phutil_escape_html($this->getApplicationName())) . '</th>' . $tabs . '</tr>' . '</table>' . '</td>' . '<td class="phabricator-login-details">' . $login_stuff . '</td>' . '</tr>' . '</table>' . $notification_dropdown . $notification_container;
         $footer_chrome = '<div class="phabricator-page-foot">' . $foot_links . '</div>';
     }
     $developer_warning = null;
     if (PhabricatorEnv::getEnvConfig('phabricator.show-error-callout') && DarkConsoleErrorLogPluginAPI::getErrors()) {
         $developer_warning = '<div class="aphront-developer-error-callout">' . 'This page raised PHP errors. Find them in DarkConsole ' . 'or the error log.' . '</div>';
     }
     Javelin::initBehavior('device', array('id' => 'base-page'));
     $agent = idx($_SERVER, 'HTTP_USER_AGENT');
     // Try to guess the device resolution based on UA strings to avoid a flash
     // of incorrectly-styled content.
     $device_guess = 'device-desktop';
     if (preg_match('/iPhone|iPod/', $agent)) {
         $device_guess = 'device-phone';
     } else {
         if (preg_match('/iPad/', $agent)) {
             $device_guess = 'device-tablet';
         }
     }
     $classes = array('phabricator-standard-page', $admin_class, $device_guess);
     $classes = implode(' ', $classes);
     return ($console ? '<darkconsole />' : null) . $developer_warning . phutil_render_tag('div', array('id' => 'base-page', 'class' => $classes), $header_chrome . $this->bodyContent . '<div style="clear: both;"></div>') . $footer_chrome;
 }
 protected function getTail()
 {
     $request = $this->getRequest();
     $user = $request->getUser();
     $tail = array(parent::getTail());
     $response = CelerityAPI::getStaticResourceResponse();
     if (PhabricatorEnv::getEnvConfig('notification.enabled')) {
         if ($user && $user->isLoggedIn()) {
             $aphlict_object_id = celerity_generate_unique_node_id();
             $aphlict_container_id = celerity_generate_unique_node_id();
             $client_uri = PhabricatorEnv::getEnvConfig('notification.client-uri');
             $client_uri = new PhutilURI($client_uri);
             if ($client_uri->getDomain() == 'localhost') {
                 $this_host = $this->getRequest()->getHost();
                 $this_host = new PhutilURI('http://' . $this_host . '/');
                 $client_uri->setDomain($this_host->getDomain());
             }
             $map = CelerityResourceMap::getNamedInstance('phabricator');
             $swf_uri = $response->getURI($map, 'rsrc/swf/aphlict.swf', true);
             $enable_debug = PhabricatorEnv::getEnvConfig('notification.debug');
             $subscriptions = $this->pageObjects;
             if ($user) {
                 $subscriptions[] = $user->getPHID();
             }
             Javelin::initBehavior('aphlict-listen', array('id' => $aphlict_object_id, 'containerID' => $aphlict_container_id, 'server' => $client_uri->getDomain(), 'port' => $client_uri->getPort(), 'debug' => $enable_debug, 'swfURI' => $swf_uri, 'pageObjects' => array_fill_keys($this->pageObjects, true), 'subscriptions' => $subscriptions));
             $tail[] = phutil_tag('div', array('id' => $aphlict_container_id, 'style' => 'position: absolute; width: 0; height: 0; overflow: hidden;'), '');
         }
     }
     $tail[] = $response->renderHTMLFooter();
     return $tail;
 }
 private function getHostString()
 {
     $host = $this->getHost();
     $uri = new PhutilURI($this->uri);
     $port = $uri->getPort();
     if (!$port) {
         switch ($uri->getProtocol()) {
             case 'https':
                 $port = 443;
                 break;
             default:
                 $port = 80;
                 break;
         }
     }
     return $host . ':' . $port;
 }
 protected function getTail()
 {
     $request = $this->getRequest();
     $user = $request->getUser();
     $container = null;
     if (PhabricatorEnv::getEnvConfig('notification.enabled') && $user->isLoggedIn()) {
         $aphlict_object_id = celerity_generate_unique_node_id();
         $aphlict_container_id = celerity_generate_unique_node_id();
         $client_uri = PhabricatorEnv::getEnvConfig('notification.client-uri');
         $client_uri = new PhutilURI($client_uri);
         if ($client_uri->getDomain() == 'localhost') {
             $this_host = $this->getRequest()->getHost();
             $this_host = new PhutilURI('http://' . $this_host . '/');
             $client_uri->setDomain($this_host->getDomain());
         }
         $enable_debug = PhabricatorEnv::getEnvConfig('notification.debug');
         Javelin::initBehavior('aphlict-listen', array('id' => $aphlict_object_id, 'containerID' => $aphlict_container_id, 'server' => $client_uri->getDomain(), 'port' => $client_uri->getPort(), 'debug' => $enable_debug, 'pageObjects' => array_fill_keys($this->pageObjects, true)));
         $container = phutil_render_tag('div', array('id' => $aphlict_container_id, 'style' => 'position: absolute; width: 0; height: 0;'), '');
     }
     $response = CelerityAPI::getStaticResourceResponse();
     return $response->renderResourcesOfType('js') . $container . $response->renderHTMLFooter();
 }
Example #16
0
 public function testAmbiguousURIs()
 {
     // It's important that this be detected as a Javascript URI, because that
     // is how browsers will treat it.
     $uri = new PhutilURI('javascript:evil');
     $this->assertEqual('javascript', $uri->getProtocol());
     // This is "wrong", in that the user probably intends for this to be a
     // Git-style URI, but we can not easily parse it as one without making the
     // "javascript" case above unsafe.
     $uri = new PhutilURI('localhost:todo.txt');
     $this->assertEqual('localhost', $uri->getProtocol());
     // These variants are unambiguous and safe.
     $uri = new PhutilURI('localhost.com:todo.txt');
     $this->assertEqual('localhost.com', $uri->getDomain());
     $uri = new PhutilURI('user@localhost:todo.txt');
     $this->assertEqual('localhost', $uri->getDomain());
     // This could either be a Git URI with relative path "22", or a normal URI
     // with port "22". We should assume it is a port number because this is
     // relatively common, while relative Git URIs pointing at numeric filenames
     // are bizarre.
     $uri = new PhutilURI('domain.com:22');
     $this->assertEqual('domain.com', $uri->getDomain());
     $this->assertEqual('22', $uri->getPort());
 }
 /**
  * If there's a URI specified in an OAuth request, it must be validated in
  * its own right. Further, it must have the same domain, the same path, the
  * same port, and (at least) the same query parameters as the primary URI.
  */
 public function validateSecondaryRedirectURI(PhutilURI $secondary_uri, PhutilURI $primary_uri)
 {
     // The secondary URI must be valid.
     if (!$this->validateRedirectURI($secondary_uri)) {
         return false;
     }
     // Both URIs must point at the same domain.
     if ($secondary_uri->getDomain() != $primary_uri->getDomain()) {
         return false;
     }
     // Both URIs must have the same path
     if ($secondary_uri->getPath() != $primary_uri->getPath()) {
         return false;
     }
     // Both URIs must have the same port
     if ($secondary_uri->getPort() != $primary_uri->getPort()) {
         return false;
     }
     // Any query parameters present in the first URI must be exactly present
     // in the second URI.
     $need_params = $primary_uri->getQueryParams();
     $have_params = $secondary_uri->getQueryParams();
     foreach ($need_params as $key => $value) {
         if (!array_key_exists($key, $have_params)) {
             return false;
         }
         if ((string) $have_params[$key] != (string) $value) {
             return false;
         }
     }
     // If the first URI is HTTPS, the second URI must also be HTTPS. This
     // defuses an attack where a third party with control over the network
     // tricks you into using HTTP to authenticate over a link which is supposed
     // to be HTTPS only and sniffs all your token cookies.
     if (strtolower($primary_uri->getProtocol()) == 'https') {
         if (strtolower($secondary_uri->getProtocol()) != 'https') {
             return false;
         }
     }
     return true;
 }
 private function getServerArgv()
 {
     $ssl_key = PhabricatorEnv::getEnvConfig('notification.ssl-key');
     $ssl_cert = PhabricatorEnv::getEnvConfig('notification.ssl-cert');
     $server_uri = PhabricatorEnv::getEnvConfig('notification.server-uri');
     $server_uri = new PhutilURI($server_uri);
     $client_uri = PhabricatorEnv::getEnvConfig('notification.client-uri');
     $client_uri = new PhutilURI($client_uri);
     $log = $this->getLogPath();
     $server_argv = array();
     $server_argv[] = '--client-port=' . coalesce($this->clientPort, $client_uri->getPort());
     $server_argv[] = '--admin-port=' . $server_uri->getPort();
     $server_argv[] = '--admin-host=' . $server_uri->getDomain();
     if ($ssl_key) {
         $server_argv[] = '--ssl-key=' . $ssl_key;
     }
     if ($ssl_cert) {
         $server_argv[] = '--ssl-cert=' . $ssl_cert;
     }
     $server_argv[] = '--log=' . $log;
     if ($this->clientHost) {
         $server_argv[] = '--client-host=' . $this->clientHost;
     }
     return $server_argv;
 }