mirror of
https://we.phorge.it/source/phorge.git
synced 2024-11-27 01:02:42 +01:00
88 lines
2.2 KiB
PHP
88 lines
2.2 KiB
PHP
|
#!/usr/bin/env php
|
||
|
<?php
|
||
|
|
||
|
$root = dirname(dirname(dirname(__FILE__)));
|
||
|
require_once $root.'/scripts/__init_script__.php';
|
||
|
|
||
|
$args = new PhutilArgumentParser($argv);
|
||
|
$args->setTagline('receive SSH requests');
|
||
|
$args->setSynopsis(<<<EOSYNOPSIS
|
||
|
**ssh-exec** --phabricator-ssh-user __user__ __commmand__ [__options__]
|
||
|
Receive SSH requests.
|
||
|
|
||
|
EOSYNOPSIS
|
||
|
);
|
||
|
|
||
|
// NOTE: Do NOT parse standard arguments. Arguments are coming from a remote
|
||
|
// client over SSH, and they should not be able to execute "--xprofile",
|
||
|
// "--recon", etc.
|
||
|
|
||
|
$args->parsePartial(
|
||
|
array(
|
||
|
array(
|
||
|
'name' => 'phabricator-ssh-user',
|
||
|
'param' => 'username',
|
||
|
),
|
||
|
));
|
||
|
|
||
|
try {
|
||
|
$user_name = $args->getArg('phabricator-ssh-user');
|
||
|
if (!strlen($user_name)) {
|
||
|
throw new Exception("No username.");
|
||
|
}
|
||
|
|
||
|
$user = id(new PhabricatorUser())->loadOneWhere(
|
||
|
'userName = %s',
|
||
|
$user_name);
|
||
|
if (!$user) {
|
||
|
throw new Exception("Invalid username.");
|
||
|
}
|
||
|
|
||
|
if ($user->getIsDisabled()) {
|
||
|
throw new Exception("You have been exiled.");
|
||
|
}
|
||
|
|
||
|
$workflows = array(
|
||
|
new ConduitSSHWorkflow(),
|
||
|
);
|
||
|
|
||
|
// This duplicates logic in parseWorkflows(), but allows us to raise more
|
||
|
// concise/relevant exceptions when the client is a remote SSH.
|
||
|
$remain = $args->getUnconsumedArgumentVector();
|
||
|
if (empty($remain)) {
|
||
|
throw new Exception("No command.");
|
||
|
} else {
|
||
|
$command = head($remain);
|
||
|
$workflow_names = mpull($workflows, 'getName', 'getName');
|
||
|
if (empty($workflow_names[$command])) {
|
||
|
throw new Exception("Invalid command.");
|
||
|
}
|
||
|
}
|
||
|
|
||
|
$workflow = $args->parseWorkflows($workflows);
|
||
|
$workflow->setUser($user);
|
||
|
|
||
|
$sock_stdin = fopen('php://stdin', 'r');
|
||
|
if (!$sock_stdin) {
|
||
|
throw new Exception("Unable to open stdin.");
|
||
|
}
|
||
|
|
||
|
$sock_stdout = fopen('php://stdout', 'w');
|
||
|
if (!$sock_stdout) {
|
||
|
throw new Exception("Unable to open stdout.");
|
||
|
}
|
||
|
|
||
|
$socket_channel = new PhutilSocketChannel(
|
||
|
$sock_stdin,
|
||
|
$sock_stdout);
|
||
|
$metrics_channel = new PhutilMetricsChannel($socket_channel);
|
||
|
$workflow->setIOChannel($metrics_channel);
|
||
|
|
||
|
$err = $workflow->execute($args);
|
||
|
|
||
|
$metrics_channel->flush();
|
||
|
} catch (Exception $ex) {
|
||
|
echo "phabricator-ssh-exec: ".$ex->getMessage()."\n";
|
||
|
exit(1);
|
||
|
}
|