|
2 | 2 | <?php
|
3 | 3 |
|
4 | 4 | $root = dirname(dirname(dirname(__FILE__)));
|
5 |
| -require_once $root.'/scripts/__init_script__.php'; |
| 5 | +require_once $root.'/scripts/init/init-script.php'; |
| 6 | + |
| 7 | +// NOTE: We are caching a datastructure rather than the flat key file because |
| 8 | +// the path on disk to "ssh-exec" is arbitrarily mutable at runtime. See T12397. |
6 | 9 |
|
7 | 10 | $cache = PhabricatorCaches::getMutableCache();
|
8 |
| -$authfile_key = PhabricatorAuthSSHKeyQuery::AUTHFILE_CACHEKEY; |
9 |
| -$authfile = $cache->getKey($authfile_key); |
| 11 | +$authstruct_key = PhabricatorAuthSSHKeyQuery::AUTHSTRUCT_CACHEKEY; |
| 12 | +$authstruct_raw = $cache->getKey($authstruct_key); |
| 13 | + |
| 14 | +$authstruct = null; |
| 15 | + |
| 16 | +if (strlen($authstruct_raw)) { |
| 17 | + try { |
| 18 | + $authstruct = phutil_json_decode($authstruct_raw); |
| 19 | + } catch (Exception $ex) { |
| 20 | + // Ignore any issues with the cached data; we'll just rebuild the |
| 21 | + // structure below. |
| 22 | + } |
| 23 | +} |
10 | 24 |
|
11 |
| -if ($authfile === null) { |
| 25 | +if ($authstruct === null) { |
12 | 26 | $keys = id(new PhabricatorAuthSSHKeyQuery())
|
13 | 27 | ->setViewer(PhabricatorUser::getOmnipotentUser())
|
14 | 28 | ->withIsActive(true)
|
|
19 | 33 | exit(1);
|
20 | 34 | }
|
21 | 35 |
|
22 |
| - $bin = $root.'/bin/ssh-exec'; |
| 36 | + $key_list = array(); |
23 | 37 | foreach ($keys as $ssh_key) {
|
24 | 38 | $key_argv = array();
|
25 | 39 | $object = $ssh_key->getObject();
|
|
42 | 56 | $key_argv[] = '--phabricator-ssh-key';
|
43 | 57 | $key_argv[] = $ssh_key->getID();
|
44 | 58 |
|
45 |
| - $cmd = csprintf('%s %Ls', $bin, $key_argv); |
46 |
| - |
47 |
| - $instance = PhabricatorEnv::getEnvConfig('cluster.instance'); |
48 |
| - if (strlen($instance)) { |
49 |
| - $cmd = csprintf('PHABRICATOR_INSTANCE=%s %C', $instance, $cmd); |
50 |
| - } |
51 |
| - |
52 |
| - // This is additional escaping for the SSH 'command="..."' string. |
53 |
| - $cmd = addcslashes($cmd, '"\\'); |
54 |
| - |
55 | 59 | // Strip out newlines and other nonsense from the key type and key body.
|
56 |
| - |
57 | 60 | $type = $ssh_key->getKeyType();
|
58 | 61 | $type = preg_replace('@[\x00-\x20]+@', '', $type);
|
59 | 62 | if (!strlen($type)) {
|
|
66 | 69 | continue;
|
67 | 70 | }
|
68 | 71 |
|
69 |
| - $options = array( |
70 |
| - 'command="'.$cmd.'"', |
71 |
| - 'no-port-forwarding', |
72 |
| - 'no-X11-forwarding', |
73 |
| - 'no-agent-forwarding', |
74 |
| - 'no-pty', |
| 72 | + $key_list[] = array( |
| 73 | + 'argv' => $key_argv, |
| 74 | + 'type' => $type, |
| 75 | + 'key' => $key, |
75 | 76 | );
|
76 |
| - $options = implode(',', $options); |
77 |
| - |
78 |
| - $lines[] = $options.' '.$type.' '.$key."\n"; |
79 | 77 | }
|
80 | 78 |
|
81 |
| - $authfile = implode('', $lines); |
| 79 | + $authstruct = array( |
| 80 | + 'keys' => $key_list, |
| 81 | + ); |
| 82 | + |
| 83 | + $authstruct_raw = phutil_json_encode($authstruct); |
82 | 84 | $ttl = phutil_units('24 hours in seconds');
|
83 |
| - $cache->setKey($authfile_key, $authfile, $ttl); |
| 85 | + $cache->setKey($authstruct_key, $authstruct_raw, $ttl); |
84 | 86 | }
|
85 | 87 |
|
| 88 | +$bin = $root.'/bin/ssh-exec'; |
| 89 | +$instance = PhabricatorEnv::getEnvConfig('cluster.instance'); |
| 90 | + |
| 91 | +$lines = array(); |
| 92 | +foreach ($authstruct['keys'] as $key_struct) { |
| 93 | + $key_argv = $key_struct['argv']; |
| 94 | + $key = $key_struct['key']; |
| 95 | + $type = $key_struct['type']; |
| 96 | + |
| 97 | + $cmd = csprintf('%s %Ls', $bin, $key_argv); |
| 98 | + |
| 99 | + if (strlen($instance)) { |
| 100 | + $cmd = csprintf('PHABRICATOR_INSTANCE=%s %C', $instance, $cmd); |
| 101 | + } |
| 102 | + |
| 103 | + // This is additional escaping for the SSH 'command="..."' string. |
| 104 | + $cmd = addcslashes($cmd, '"\\'); |
| 105 | + |
| 106 | + $options = array( |
| 107 | + 'command="'.$cmd.'"', |
| 108 | + 'no-port-forwarding', |
| 109 | + 'no-X11-forwarding', |
| 110 | + 'no-agent-forwarding', |
| 111 | + 'no-pty', |
| 112 | + ); |
| 113 | + $options = implode(',', $options); |
| 114 | + |
| 115 | + $lines[] = $options.' '.$type.' '.$key."\n"; |
| 116 | +} |
| 117 | + |
| 118 | +$authfile = implode('', $lines); |
| 119 | + |
86 | 120 | echo $authfile;
|
| 121 | + |
87 | 122 | exit(0);
|
0 commit comments