PluginProbe
ManageWP Worker / 4.9.25
ManageWP Worker v4.9.25
4.9.38 4.9.37 4.9.36 4.9.35 4.9.34 3.8.7 3.8.8 3.9.0 3.9.1 3.9.10 3.9.11 3.9.12 3.9.13 3.9.14 3.9.15 3.9.16 3.9.17 3.9.18 3.9.19 3.9.2 3.9.20 3.9.21 3.9.22 3.9.23 3.9.24 All 73 releases
worker / src / PHPSecLib / System / SSH / Agent.php

Agent.php in ManageWP Worker 4.9.25, at src/PHPSecLib/System/SSH/Agent.php

321 lines 9.4 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * Pure-PHP ssh-agent client.
4 *
5 * PHP versions 4 and 5
6 *
7 * Here are some examples of how to use this library:
8 * <code>
9 * <?php
10 * include 'System/SSH/Agent.php';
11 * include 'Net/SSH2.php';
12 *
13 * $agent = new System_SSH_Agent();
14 *
15 * $ssh = new Net_SSH2('www.domain.tld');
16 * if (!$ssh->login('username', $agent)) {
17 * exit('Login Failed');
18 * }
19 *
20 * echo $ssh->exec('pwd');
21 * echo $ssh->exec('ls -la');
22 * ?>
23 * </code>
24 *
25 * LICENSE: Permission is hereby granted, free of charge, to any person obtaining a copy
26 * of this software and associated documentation files (the "Software"), to deal
27 * in the Software without restriction, including without limitation the rights
28 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
29 * copies of the Software, and to permit persons to whom the Software is
30 * furnished to do so, subject to the following conditions:
31 *
32 * The above copyright notice and this permission notice shall be included in
33 * all copies or substantial portions of the Software.
34 *
35 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
36 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
37 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
38 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
39 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
40 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
41 * THE SOFTWARE.
42 *
43 * @category System
44 * @package System_SSH_Agent
45 * @author Jim Wigginton <terrafrost@php.net>
46 * @copyright MMXIV Jim Wigginton
47 * @license http://www.opensource.org/licenses/mit-license.html MIT License
48 * @link http://phpseclib.sourceforge.net
49 * @internal See http://api.libssh.org/rfc/PROTOCOL.agent
50 */
51
52 /**#@+
53 * Message numbers
54 *
55 * @access private
56 */
57 // to request SSH1 keys you have to use SSH_AGENTC_REQUEST_RSA_IDENTITIES (1)
58 define('SYSTEM_SSH_AGENTC_REQUEST_IDENTITIES', 11);
59 // this is the SSH2 response; the SSH1 response is SSH_AGENT_RSA_IDENTITIES_ANSWER (2).
60 define('SYSTEM_SSH_AGENT_IDENTITIES_ANSWER', 12);
61 define('SYSTEM_SSH_AGENT_FAILURE', 5);
62 // the SSH1 request is SSH_AGENTC_RSA_CHALLENGE (3)
63 define('SYSTEM_SSH_AGENTC_SIGN_REQUEST', 13);
64 // the SSH1 response is SSH_AGENT_RSA_RESPONSE (4)
65 define('SYSTEM_SSH_AGENT_SIGN_RESPONSE', 14);
66 /**#@-*/
67
68 /**
69 * Pure-PHP ssh-agent client identity object
70 *
71 * Instantiation should only be performed by System_SSH_Agent class.
72 * This could be thought of as implementing an interface that Crypt_RSA
73 * implements. ie. maybe a Net_SSH_Auth_PublicKey interface or something.
74 * The methods in this interface would be getPublicKey, setSignatureMode
75 * and sign since those are the methods phpseclib looks for to perform
76 * public key authentication.
77 *
78 * @package System_SSH_Agent
79 * @author Jim Wigginton <terrafrost@php.net>
80 * @access internal
81 */
82 class System_SSH_Agent_Identity
83 {
84 /**
85 * Key Object
86 *
87 * @var Crypt_RSA
88 * @access private
89 * @see System_SSH_Agent_Identity::getPublicKey()
90 */
91 public $key;
92
93 /**
94 * Key Blob
95 *
96 * @var String
97 * @access private
98 * @see System_SSH_Agent_Identity::sign()
99 */
100 public $key_blob;
101
102 /**
103 * Socket Resource
104 *
105 * @var Resource
106 * @access private
107 * @see System_SSH_Agent_Identity::sign()
108 */
109 public $fsock;
110
111 /**
112 * Default Constructor.
113 *
114 * @param Resource $fsock
115 *
116 * @return System_SSH_Agent_Identity
117 * @access private
118 */
119 public function __construct($fsock)
120 {
121 $this->fsock = $fsock;
122 }
123
124 /**
125 * Set Public Key
126 *
127 * Called by System_SSH_Agent::requestIdentities()
128 *
129 * @param Crypt_RSA $key
130 *
131 * @access private
132 */
133 public function setPublicKey($key)
134 {
135 $this->key = $key;
136 $this->key->setPublicKey();
137 }
138
139 /**
140 * Set Public Key
141 *
142 * Called by System_SSH_Agent::requestIdentities(). The key blob could be extracted from $this->key
143 * but this saves a small amount of computation.
144 *
145 * @param String $key_blob
146 *
147 * @access private
148 */
149 public function setPublicKeyBlob($key_blob)
150 {
151 $this->key_blob = $key_blob;
152 }
153
154 /**
155 * Get Public Key
156 *
157 * Wrapper for $this->key->getPublicKey()
158 *
159 * @param Integer $format optional
160 *
161 * @return Mixed
162 * @access public
163 */
164 public function getPublicKey($format = null)
165 {
166 return !isset($format) ? $this->key->getPublicKey() : $this->key->getPublicKey($format);
167 }
168
169 /**
170 * Set Signature Mode
171 *
172 * Doesn't do anything as ssh-agent doesn't let you pick and choose the signature mode. ie.
173 * ssh-agent's only supported mode is CRYPT_RSA_SIGNATURE_PKCS1
174 *
175 * @param Integer $mode
176 *
177 * @access public
178 */
179 public function setSignatureMode($mode)
180 {
181 }
182
183 /**
184 * Create a signature
185 *
186 * See "2.6.2 Protocol 2 private key signature request"
187 *
188 * @param String $message
189 *
190 * @return String
191 * @access public
192 */
193 public function sign($message)
194 {
195 // the last parameter (currently 0) is for flags and ssh-agent only defines one flag (for ssh-dss): SSH_AGENT_OLD_SIGNATURE
196 $packet = pack('CNa*Na*N', SYSTEM_SSH_AGENTC_SIGN_REQUEST, strlen($this->key_blob), $this->key_blob, strlen($message), $message, 0);
197 $packet = pack('Na*', strlen($packet), $packet);
198 if (strlen($packet) != fputs($this->fsock, $packet)) {
199 user_error('Connection closed during signing');
200 }
201
202 $length = current(unpack('N', fread($this->fsock, 4)));
203 $type = ord(fread($this->fsock, 1));
204 if ($type != SYSTEM_SSH_AGENT_SIGN_RESPONSE) {
205 user_error('Unable to retreive signature');
206 }
207
208 $signature_blob = fread($this->fsock, $length - 1);
209 // the only other signature format defined - ssh-dss - is the same length as ssh-rsa
210 // the + 12 is for the other various SSH added length fields
211 return substr($signature_blob, strlen('ssh-rsa') + 12);
212 }
213 }
214
215 /**
216 * Pure-PHP ssh-agent client identity factory
217 *
218 * requestIdentities() method pumps out System_SSH_Agent_Identity objects
219 *
220 * @package System_SSH_Agent
221 * @author Jim Wigginton <terrafrost@php.net>
222 * @access internal
223 */
224 class System_SSH_Agent
225 {
226 /**
227 * Socket Resource
228 *
229 * @var Resource
230 * @access private
231 */
232 public $fsock;
233
234 /**
235 * Default Constructor
236 *
237 * @return System_SSH_Agent
238 * @access public
239 */
240 public function __construct()
241 {
242 switch (true) {
243 case isset($_SERVER['SSH_AUTH_SOCK']):
244 $address = $_SERVER['SSH_AUTH_SOCK'];
245 break;
246 case isset($_ENV['SSH_AUTH_SOCK']):
247 $address = $_ENV['SSH_AUTH_SOCK'];
248 break;
249 default:
250 user_error('SSH_AUTH_SOCK not found');
251
252 return false;
253 }
254
255 $this->fsock = fsockopen('unix://'.$address, 0, $errno, $errstr);
256 if (!$this->fsock) {
257 user_error("Unable to connect to ssh-agent (Error $errno: $errstr)");
258 }
259 }
260
261 /**
262 * Request Identities
263 *
264 * See "2.5.2 Requesting a list of protocol 2 keys"
265 * Returns an array containing zero or more System_SSH_Agent_Identity objects
266 *
267 * @return Array
268 * @access public
269 */
270 public function requestIdentities()
271 {
272 if (!$this->fsock) {
273 return array();
274 }
275
276 $packet = pack('NC', 1, SYSTEM_SSH_AGENTC_REQUEST_IDENTITIES);
277 if (strlen($packet) != fputs($this->fsock, $packet)) {
278 user_error('Connection closed while requesting identities');
279 }
280
281 $length = current(unpack('N', fread($this->fsock, 4)));
282 $type = ord(fread($this->fsock, 1));
283 if ($type != SYSTEM_SSH_AGENT_IDENTITIES_ANSWER) {
284 user_error('Unable to request identities');
285 }
286
287 $identities = array();
288 $keyCount = current(unpack('N', fread($this->fsock, 4)));
289 for ($i = 0; $i < $keyCount; $i++) {
290 $length = current(unpack('N', fread($this->fsock, 4)));
291 $key_blob = fread($this->fsock, $length);
292 $length = current(unpack('N', fread($this->fsock, 4)));
293 $key_comment = fread($this->fsock, $length);
294 $length = current(unpack('N', substr($key_blob, 0, 4)));
295 $key_type = substr($key_blob, 4, $length);
296 switch ($key_type) {
297 case 'ssh-rsa':
298 if (!class_exists('Crypt_RSA')) {
299 require_once dirname(__FILE__).'/../../Crypt/RSA.php';
300 }
301 $key = new Crypt_RSA();
302 $key->loadKey('ssh-rsa '.base64_encode($key_blob).' '.$key_comment);
303 break;
304 case 'ssh-dss':
305 // not currently supported
306 break;
307 }
308 // resources are passed by reference by default
309 if (isset($key)) {
310 $identity = new System_SSH_Agent_Identity($this->fsock);
311 $identity->setPublicKey($key);
312 $identity->setPublicKeyBlob($key_blob);
313 $identities[] = $identity;
314 unset($key);
315 }
316 }
317
318 return $identities;
319 }
320 }
321