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()); }
private function getForcedUser() { switch ($this->getBuiltinProtocol()) { case self::BUILTIN_PROTOCOL_SSH: return AlmanacKeys::getClusterSSHUser(); default: return null; } }
} if ($credential_phid) { throw new Exception(pht('Attempting to proxy an SSH connection that authenticates with ' . 'both the current device and a specific credential. These options ' . 'are mutually exclusive.')); } } if ($credential_phid) { $viewer = PhabricatorUser::getOmnipotentUser(); $key = PassphraseSSHKey::loadFromPHID($credential_phid, $viewer); $pattern[] = '-l %P'; $arguments[] = $key->getUsernameEnvelope(); $pattern[] = '-i %P'; $arguments[] = $key->getKeyfileEnvelope(); } if ($as_device) { $pattern[] = '-l %R'; $arguments[] = AlmanacKeys::getClusterSSHUser(); $pattern[] = '-i %R'; $arguments[] = AlmanacKeys::getKeyPath('device.key'); } // Subversion passes us a host in the form "domain.com:port", which is not // valid for normal SSH but which we can parse into a valid "-p" flag. $passthru_args = $unconsumed_argv; $host = array_shift($passthru_args); $parts = explode(':', $host, 2); $host = $parts[0]; $port = $args->getArg('port'); if (!$port) { if (count($parts) == 2) { $port = $parts[1]; } }