Completed
Push — master ( b34111...bbfc02 )
by Morris
18:28
created
apps/files_external/lib/AppInfo/Application.php 1 patch
Indentation   +84 added lines, -84 removed lines patch added patch discarded remove patch
@@ -66,89 +66,89 @@
 block discarded – undo
66 66
  */
67 67
 class Application extends App implements IBackendProvider, IAuthMechanismProvider {
68 68
 
69
-	public function __construct(array $urlParams = array()) {
70
-		parent::__construct('files_external', $urlParams);
71
-
72
-		$container = $this->getContainer();
73
-
74
-		$container->registerService(IUserMountCache::class, function (IAppContainer $c) {
75
-			return $c->getServer()->query('UserMountCache');
76
-		});
77
-
78
-		$backendService = $container->query(BackendService::class);
79
-		$backendService->registerBackendProvider($this);
80
-		$backendService->registerAuthMechanismProvider($this);
81
-
82
-		// force-load auth mechanisms since some will register hooks
83
-		// TODO: obsolete these and use the TokenProvider to get the user's password from the session
84
-		$this->getAuthMechanisms();
85
-
86
-		// app developers: do NOT depend on this! it will disappear with oC 9.0!
87
-		\OC::$server->getEventDispatcher()->dispatch(
88
-			'OCA\\Files_External::loadAdditionalBackends'
89
-		);
90
-	}
91
-
92
-	/**
93
-	 * @{inheritdoc}
94
-	 */
95
-	public function getBackends() {
96
-		$container = $this->getContainer();
97
-
98
-		$backends = [
99
-			$container->query(Local::class),
100
-			$container->query(FTP::class),
101
-			$container->query(DAV::class),
102
-			$container->query(OwnCloud::class),
103
-			$container->query(SFTP::class),
104
-			$container->query(AmazonS3::class),
105
-			$container->query(Swift::class),
106
-			$container->query(SFTP_Key::class),
107
-			$container->query(SMB::class),
108
-			$container->query(SMB_OC::class),
109
-		];
110
-
111
-		return $backends;
112
-	}
113
-
114
-	/**
115
-	 * @{inheritdoc}
116
-	 */
117
-	public function getAuthMechanisms() {
118
-		$container = $this->getContainer();
119
-
120
-		return [
121
-			// AuthMechanism::SCHEME_NULL mechanism
122
-			$container->query(NullMechanism::class),
123
-
124
-			// AuthMechanism::SCHEME_BUILTIN mechanism
125
-			$container->query(Builtin::class),
126
-
127
-			// AuthMechanism::SCHEME_PASSWORD mechanisms
128
-			$container->query(Password::class),
129
-			$container->query(SessionCredentials::class),
130
-			$container->query(LoginCredentials::class),
131
-			$container->query(UserProvided::class),
132
-			$container->query(GlobalAuth::class),
133
-
134
-			// AuthMechanism::SCHEME_OAUTH1 mechanisms
135
-			$container->query(OAuth1::class),
136
-
137
-			// AuthMechanism::SCHEME_OAUTH2 mechanisms
138
-			$container->query(OAuth2::class),
139
-
140
-			// AuthMechanism::SCHEME_PUBLICKEY mechanisms
141
-			$container->query(RSA::class),
142
-			$container->query(RSAPrivateKey::class),
143
-
144
-			// AuthMechanism::SCHEME_OPENSTACK mechanisms
145
-			$container->query(OpenStackV2::class),
146
-			$container->query(OpenStackV3::class),
147
-			$container->query(Rackspace::class),
148
-
149
-			// Specialized mechanisms
150
-			$container->query(AccessKey::class),
151
-		];
152
-	}
69
+    public function __construct(array $urlParams = array()) {
70
+        parent::__construct('files_external', $urlParams);
71
+
72
+        $container = $this->getContainer();
73
+
74
+        $container->registerService(IUserMountCache::class, function (IAppContainer $c) {
75
+            return $c->getServer()->query('UserMountCache');
76
+        });
77
+
78
+        $backendService = $container->query(BackendService::class);
79
+        $backendService->registerBackendProvider($this);
80
+        $backendService->registerAuthMechanismProvider($this);
81
+
82
+        // force-load auth mechanisms since some will register hooks
83
+        // TODO: obsolete these and use the TokenProvider to get the user's password from the session
84
+        $this->getAuthMechanisms();
85
+
86
+        // app developers: do NOT depend on this! it will disappear with oC 9.0!
87
+        \OC::$server->getEventDispatcher()->dispatch(
88
+            'OCA\\Files_External::loadAdditionalBackends'
89
+        );
90
+    }
91
+
92
+    /**
93
+     * @{inheritdoc}
94
+     */
95
+    public function getBackends() {
96
+        $container = $this->getContainer();
97
+
98
+        $backends = [
99
+            $container->query(Local::class),
100
+            $container->query(FTP::class),
101
+            $container->query(DAV::class),
102
+            $container->query(OwnCloud::class),
103
+            $container->query(SFTP::class),
104
+            $container->query(AmazonS3::class),
105
+            $container->query(Swift::class),
106
+            $container->query(SFTP_Key::class),
107
+            $container->query(SMB::class),
108
+            $container->query(SMB_OC::class),
109
+        ];
110
+
111
+        return $backends;
112
+    }
113
+
114
+    /**
115
+     * @{inheritdoc}
116
+     */
117
+    public function getAuthMechanisms() {
118
+        $container = $this->getContainer();
119
+
120
+        return [
121
+            // AuthMechanism::SCHEME_NULL mechanism
122
+            $container->query(NullMechanism::class),
123
+
124
+            // AuthMechanism::SCHEME_BUILTIN mechanism
125
+            $container->query(Builtin::class),
126
+
127
+            // AuthMechanism::SCHEME_PASSWORD mechanisms
128
+            $container->query(Password::class),
129
+            $container->query(SessionCredentials::class),
130
+            $container->query(LoginCredentials::class),
131
+            $container->query(UserProvided::class),
132
+            $container->query(GlobalAuth::class),
133
+
134
+            // AuthMechanism::SCHEME_OAUTH1 mechanisms
135
+            $container->query(OAuth1::class),
136
+
137
+            // AuthMechanism::SCHEME_OAUTH2 mechanisms
138
+            $container->query(OAuth2::class),
139
+
140
+            // AuthMechanism::SCHEME_PUBLICKEY mechanisms
141
+            $container->query(RSA::class),
142
+            $container->query(RSAPrivateKey::class),
143
+
144
+            // AuthMechanism::SCHEME_OPENSTACK mechanisms
145
+            $container->query(OpenStackV2::class),
146
+            $container->query(OpenStackV3::class),
147
+            $container->query(Rackspace::class),
148
+
149
+            // Specialized mechanisms
150
+            $container->query(AccessKey::class),
151
+        ];
152
+    }
153 153
 
154 154
 }
Please login to merge, or discard this patch.
apps/files_external/lib/Lib/Storage/SFTP.php 1 patch
Indentation   +430 added lines, -430 removed lines patch added patch discarded remove patch
@@ -42,434 +42,434 @@
 block discarded – undo
42 42
 * provide access to SFTP servers.
43 43
 */
44 44
 class SFTP extends \OC\Files\Storage\Common {
45
-	private $host;
46
-	private $user;
47
-	private $root;
48
-	private $port = 22;
49
-
50
-	private $auth = [];
51
-
52
-	/**
53
-	 * @var \phpseclib\Net\SFTP
54
-	 */
55
-	protected $client;
56
-
57
-	/**
58
-	 * @param string $host protocol://server:port
59
-	 * @return array [$server, $port]
60
-	 */
61
-	private function splitHost($host) {
62
-		$input = $host;
63
-		if (strpos($host, '://') === false) {
64
-			// add a protocol to fix parse_url behavior with ipv6
65
-			$host = 'http://' . $host;
66
-		}
67
-
68
-		$parsed = parse_url($host);
69
-		if(is_array($parsed) && isset($parsed['port'])) {
70
-			return [$parsed['host'], $parsed['port']];
71
-		} else if (is_array($parsed)) {
72
-			return [$parsed['host'], 22];
73
-		} else {
74
-			return [$input, 22];
75
-		}
76
-	}
77
-
78
-	/**
79
-	 * {@inheritdoc}
80
-	 */
81
-	public function __construct($params) {
82
-		// Register sftp://
83
-		Stream::register();
84
-
85
-		$parsedHost =  $this->splitHost($params['host']);
86
-
87
-		$this->host = $parsedHost[0];
88
-		$this->port = $parsedHost[1];
89
-
90
-		if (!isset($params['user'])) {
91
-			throw new \UnexpectedValueException('no authentication parameters specified');
92
-		}
93
-		$this->user = $params['user'];
94
-
95
-		if (isset($params['public_key_auth'])) {
96
-			$this->auth[] = $params['public_key_auth'];
97
-		}
98
-		if (isset($params['password']) && $params['password'] !== '') {
99
-			$this->auth[] = $params['password'];
100
-		}
101
-
102
-		if ($this->auth === []) {
103
-			throw new \UnexpectedValueException('no authentication parameters specified');
104
-		}
105
-
106
-		$this->root
107
-			= isset($params['root']) ? $this->cleanPath($params['root']) : '/';
108
-
109
-		$this->root = '/' . ltrim($this->root, '/');
110
-		$this->root = rtrim($this->root, '/') . '/';
111
-	}
112
-
113
-	/**
114
-	 * Returns the connection.
115
-	 *
116
-	 * @return \phpseclib\Net\SFTP connected client instance
117
-	 * @throws \Exception when the connection failed
118
-	 */
119
-	public function getConnection() {
120
-		if (!is_null($this->client)) {
121
-			return $this->client;
122
-		}
123
-
124
-		$hostKeys = $this->readHostKeys();
125
-		$this->client = new \phpseclib\Net\SFTP($this->host, $this->port);
126
-
127
-		// The SSH Host Key MUST be verified before login().
128
-		$currentHostKey = $this->client->getServerPublicHostKey();
129
-		if (array_key_exists($this->host, $hostKeys)) {
130
-			if ($hostKeys[$this->host] !== $currentHostKey) {
131
-				throw new \Exception('Host public key does not match known key');
132
-			}
133
-		} else {
134
-			$hostKeys[$this->host] = $currentHostKey;
135
-			$this->writeHostKeys($hostKeys);
136
-		}
137
-
138
-		$login = false;
139
-		foreach ($this->auth as $auth) {
140
-			$login = $this->client->login($this->user, $auth);
141
-			if ($login === true) {
142
-				break;
143
-			}
144
-		}
145
-
146
-		if ($login === false) {
147
-			throw new \Exception('Login failed');
148
-		}
149
-		return $this->client;
150
-	}
151
-
152
-	/**
153
-	 * {@inheritdoc}
154
-	 */
155
-	public function test() {
156
-		if (
157
-			!isset($this->host)
158
-			|| !isset($this->user)
159
-		) {
160
-			return false;
161
-		}
162
-		return $this->getConnection()->nlist() !== false;
163
-	}
164
-
165
-	/**
166
-	 * {@inheritdoc}
167
-	 */
168
-	public function getId(){
169
-		$id = 'sftp::' . $this->user . '@' . $this->host;
170
-		if ($this->port !== 22) {
171
-			$id .= ':' . $this->port;
172
-		}
173
-		// note: this will double the root slash,
174
-		// we should not change it to keep compatible with
175
-		// old storage ids
176
-		$id .= '/' . $this->root;
177
-		return $id;
178
-	}
179
-
180
-	/**
181
-	 * @return string
182
-	 */
183
-	public function getHost() {
184
-		return $this->host;
185
-	}
186
-
187
-	/**
188
-	 * @return string
189
-	 */
190
-	public function getRoot() {
191
-		return $this->root;
192
-	}
193
-
194
-	/**
195
-	 * @return mixed
196
-	 */
197
-	public function getUser() {
198
-		return $this->user;
199
-	}
200
-
201
-	/**
202
-	 * @param string $path
203
-	 * @return string
204
-	 */
205
-	private function absPath($path) {
206
-		return $this->root . $this->cleanPath($path);
207
-	}
208
-
209
-	/**
210
-	 * @return string|false
211
-	 */
212
-	private function hostKeysPath() {
213
-		try {
214
-			$storage_view = \OCP\Files::getStorage('files_external');
215
-			if ($storage_view) {
216
-				return \OC::$server->getConfig()->getSystemValue('datadirectory', \OC::$SERVERROOT . '/data') .
217
-					$storage_view->getAbsolutePath('') .
218
-					'ssh_hostKeys';
219
-			}
220
-		} catch (\Exception $e) {
221
-		}
222
-		return false;
223
-	}
224
-
225
-	/**
226
-	 * @param $keys
227
-	 * @return bool
228
-	 */
229
-	protected function writeHostKeys($keys) {
230
-		try {
231
-			$keyPath = $this->hostKeysPath();
232
-			if ($keyPath && file_exists($keyPath)) {
233
-				$fp = fopen($keyPath, 'w');
234
-				foreach ($keys as $host => $key) {
235
-					fwrite($fp, $host . '::' . $key . "\n");
236
-				}
237
-				fclose($fp);
238
-				return true;
239
-			}
240
-		} catch (\Exception $e) {
241
-		}
242
-		return false;
243
-	}
244
-
245
-	/**
246
-	 * @return array
247
-	 */
248
-	protected function readHostKeys() {
249
-		try {
250
-			$keyPath = $this->hostKeysPath();
251
-			if (file_exists($keyPath)) {
252
-				$hosts = array();
253
-				$keys = array();
254
-				$lines = file($keyPath, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
255
-				if ($lines) {
256
-					foreach ($lines as $line) {
257
-						$hostKeyArray = explode("::", $line, 2);
258
-						if (count($hostKeyArray) === 2) {
259
-							$hosts[] = $hostKeyArray[0];
260
-							$keys[] = $hostKeyArray[1];
261
-						}
262
-					}
263
-					return array_combine($hosts, $keys);
264
-				}
265
-			}
266
-		} catch (\Exception $e) {
267
-		}
268
-		return array();
269
-	}
270
-
271
-	/**
272
-	 * {@inheritdoc}
273
-	 */
274
-	public function mkdir($path) {
275
-		try {
276
-			return $this->getConnection()->mkdir($this->absPath($path));
277
-		} catch (\Exception $e) {
278
-			return false;
279
-		}
280
-	}
281
-
282
-	/**
283
-	 * {@inheritdoc}
284
-	 */
285
-	public function rmdir($path) {
286
-		try {
287
-			$result = $this->getConnection()->delete($this->absPath($path), true);
288
-			// workaround: stray stat cache entry when deleting empty folders
289
-			// see https://github.com/phpseclib/phpseclib/issues/706
290
-			$this->getConnection()->clearStatCache();
291
-			return $result;
292
-		} catch (\Exception $e) {
293
-			return false;
294
-		}
295
-	}
296
-
297
-	/**
298
-	 * {@inheritdoc}
299
-	 */
300
-	public function opendir($path) {
301
-		try {
302
-			$list = $this->getConnection()->nlist($this->absPath($path));
303
-			if ($list === false) {
304
-				return false;
305
-			}
306
-
307
-			$id = md5('sftp:' . $path);
308
-			$dirStream = array();
309
-			foreach($list as $file) {
310
-				if ($file !== '.' && $file !== '..') {
311
-					$dirStream[] = $file;
312
-				}
313
-			}
314
-			return IteratorDirectory::wrap($dirStream);
315
-		} catch(\Exception $e) {
316
-			return false;
317
-		}
318
-	}
319
-
320
-	/**
321
-	 * {@inheritdoc}
322
-	 */
323
-	public function filetype($path) {
324
-		try {
325
-			$stat = $this->getConnection()->stat($this->absPath($path));
326
-			if ((int) $stat['type'] === NET_SFTP_TYPE_REGULAR) {
327
-				return 'file';
328
-			}
329
-
330
-			if ((int) $stat['type'] === NET_SFTP_TYPE_DIRECTORY) {
331
-				return 'dir';
332
-			}
333
-		} catch (\Exception $e) {
334
-
335
-		}
336
-		return false;
337
-	}
338
-
339
-	/**
340
-	 * {@inheritdoc}
341
-	 */
342
-	public function file_exists($path) {
343
-		try {
344
-			return $this->getConnection()->stat($this->absPath($path)) !== false;
345
-		} catch (\Exception $e) {
346
-			return false;
347
-		}
348
-	}
349
-
350
-	/**
351
-	 * {@inheritdoc}
352
-	 */
353
-	public function unlink($path) {
354
-		try {
355
-			return $this->getConnection()->delete($this->absPath($path), true);
356
-		} catch (\Exception $e) {
357
-			return false;
358
-		}
359
-	}
360
-
361
-	/**
362
-	 * {@inheritdoc}
363
-	 */
364
-	public function fopen($path, $mode) {
365
-		try {
366
-			$absPath = $this->absPath($path);
367
-			switch($mode) {
368
-				case 'r':
369
-				case 'rb':
370
-					if ( !$this->file_exists($path)) {
371
-						return false;
372
-					}
373
-				case 'w':
374
-				case 'wb':
375
-				case 'a':
376
-				case 'ab':
377
-				case 'r+':
378
-				case 'w+':
379
-				case 'wb+':
380
-				case 'a+':
381
-				case 'x':
382
-				case 'x+':
383
-				case 'c':
384
-				case 'c+':
385
-					$context = stream_context_create(array('sftp' => array('session' => $this->getConnection())));
386
-					$handle = fopen($this->constructUrl($path), $mode, false, $context);
387
-					return RetryWrapper::wrap($handle);
388
-			}
389
-		} catch (\Exception $e) {
390
-		}
391
-		return false;
392
-	}
393
-
394
-	/**
395
-	 * {@inheritdoc}
396
-	 */
397
-	public function touch($path, $mtime=null) {
398
-		try {
399
-			if (!is_null($mtime)) {
400
-				return false;
401
-			}
402
-			if (!$this->file_exists($path)) {
403
-				$this->getConnection()->put($this->absPath($path), '');
404
-			} else {
405
-				return false;
406
-			}
407
-		} catch (\Exception $e) {
408
-			return false;
409
-		}
410
-		return true;
411
-	}
412
-
413
-	/**
414
-	 * @param string $path
415
-	 * @param string $target
416
-	 * @throws \Exception
417
-	 */
418
-	public function getFile($path, $target) {
419
-		$this->getConnection()->get($path, $target);
420
-	}
421
-
422
-	/**
423
-	 * @param string $path
424
-	 * @param string $target
425
-	 * @throws \Exception
426
-	 */
427
-	public function uploadFile($path, $target) {
428
-		$this->getConnection()->put($target, $path, NET_SFTP_LOCAL_FILE);
429
-	}
430
-
431
-	/**
432
-	 * {@inheritdoc}
433
-	 */
434
-	public function rename($source, $target) {
435
-		try {
436
-			if ($this->file_exists($target)) {
437
-				$this->unlink($target);
438
-			}
439
-			return $this->getConnection()->rename(
440
-				$this->absPath($source),
441
-				$this->absPath($target)
442
-			);
443
-		} catch (\Exception $e) {
444
-			return false;
445
-		}
446
-	}
447
-
448
-	/**
449
-	 * {@inheritdoc}
450
-	 */
451
-	public function stat($path) {
452
-		try {
453
-			$stat = $this->getConnection()->stat($this->absPath($path));
454
-
455
-			$mtime = $stat ? $stat['mtime'] : -1;
456
-			$size = $stat ? $stat['size'] : 0;
457
-
458
-			return array('mtime' => $mtime, 'size' => $size, 'ctime' => -1);
459
-		} catch (\Exception $e) {
460
-			return false;
461
-		}
462
-	}
463
-
464
-	/**
465
-	 * @param string $path
466
-	 * @return string
467
-	 */
468
-	public function constructUrl($path) {
469
-		// Do not pass the password here. We want to use the Net_SFTP object
470
-		// supplied via stream context or fail. We only supply username and
471
-		// hostname because this might show up in logs (they are not used).
472
-		$url = 'sftp://' . urlencode($this->user) . '@' . $this->host . ':' . $this->port . $this->root . $path;
473
-		return $url;
474
-	}
45
+    private $host;
46
+    private $user;
47
+    private $root;
48
+    private $port = 22;
49
+
50
+    private $auth = [];
51
+
52
+    /**
53
+     * @var \phpseclib\Net\SFTP
54
+     */
55
+    protected $client;
56
+
57
+    /**
58
+     * @param string $host protocol://server:port
59
+     * @return array [$server, $port]
60
+     */
61
+    private function splitHost($host) {
62
+        $input = $host;
63
+        if (strpos($host, '://') === false) {
64
+            // add a protocol to fix parse_url behavior with ipv6
65
+            $host = 'http://' . $host;
66
+        }
67
+
68
+        $parsed = parse_url($host);
69
+        if(is_array($parsed) && isset($parsed['port'])) {
70
+            return [$parsed['host'], $parsed['port']];
71
+        } else if (is_array($parsed)) {
72
+            return [$parsed['host'], 22];
73
+        } else {
74
+            return [$input, 22];
75
+        }
76
+    }
77
+
78
+    /**
79
+     * {@inheritdoc}
80
+     */
81
+    public function __construct($params) {
82
+        // Register sftp://
83
+        Stream::register();
84
+
85
+        $parsedHost =  $this->splitHost($params['host']);
86
+
87
+        $this->host = $parsedHost[0];
88
+        $this->port = $parsedHost[1];
89
+
90
+        if (!isset($params['user'])) {
91
+            throw new \UnexpectedValueException('no authentication parameters specified');
92
+        }
93
+        $this->user = $params['user'];
94
+
95
+        if (isset($params['public_key_auth'])) {
96
+            $this->auth[] = $params['public_key_auth'];
97
+        }
98
+        if (isset($params['password']) && $params['password'] !== '') {
99
+            $this->auth[] = $params['password'];
100
+        }
101
+
102
+        if ($this->auth === []) {
103
+            throw new \UnexpectedValueException('no authentication parameters specified');
104
+        }
105
+
106
+        $this->root
107
+            = isset($params['root']) ? $this->cleanPath($params['root']) : '/';
108
+
109
+        $this->root = '/' . ltrim($this->root, '/');
110
+        $this->root = rtrim($this->root, '/') . '/';
111
+    }
112
+
113
+    /**
114
+     * Returns the connection.
115
+     *
116
+     * @return \phpseclib\Net\SFTP connected client instance
117
+     * @throws \Exception when the connection failed
118
+     */
119
+    public function getConnection() {
120
+        if (!is_null($this->client)) {
121
+            return $this->client;
122
+        }
123
+
124
+        $hostKeys = $this->readHostKeys();
125
+        $this->client = new \phpseclib\Net\SFTP($this->host, $this->port);
126
+
127
+        // The SSH Host Key MUST be verified before login().
128
+        $currentHostKey = $this->client->getServerPublicHostKey();
129
+        if (array_key_exists($this->host, $hostKeys)) {
130
+            if ($hostKeys[$this->host] !== $currentHostKey) {
131
+                throw new \Exception('Host public key does not match known key');
132
+            }
133
+        } else {
134
+            $hostKeys[$this->host] = $currentHostKey;
135
+            $this->writeHostKeys($hostKeys);
136
+        }
137
+
138
+        $login = false;
139
+        foreach ($this->auth as $auth) {
140
+            $login = $this->client->login($this->user, $auth);
141
+            if ($login === true) {
142
+                break;
143
+            }
144
+        }
145
+
146
+        if ($login === false) {
147
+            throw new \Exception('Login failed');
148
+        }
149
+        return $this->client;
150
+    }
151
+
152
+    /**
153
+     * {@inheritdoc}
154
+     */
155
+    public function test() {
156
+        if (
157
+            !isset($this->host)
158
+            || !isset($this->user)
159
+        ) {
160
+            return false;
161
+        }
162
+        return $this->getConnection()->nlist() !== false;
163
+    }
164
+
165
+    /**
166
+     * {@inheritdoc}
167
+     */
168
+    public function getId(){
169
+        $id = 'sftp::' . $this->user . '@' . $this->host;
170
+        if ($this->port !== 22) {
171
+            $id .= ':' . $this->port;
172
+        }
173
+        // note: this will double the root slash,
174
+        // we should not change it to keep compatible with
175
+        // old storage ids
176
+        $id .= '/' . $this->root;
177
+        return $id;
178
+    }
179
+
180
+    /**
181
+     * @return string
182
+     */
183
+    public function getHost() {
184
+        return $this->host;
185
+    }
186
+
187
+    /**
188
+     * @return string
189
+     */
190
+    public function getRoot() {
191
+        return $this->root;
192
+    }
193
+
194
+    /**
195
+     * @return mixed
196
+     */
197
+    public function getUser() {
198
+        return $this->user;
199
+    }
200
+
201
+    /**
202
+     * @param string $path
203
+     * @return string
204
+     */
205
+    private function absPath($path) {
206
+        return $this->root . $this->cleanPath($path);
207
+    }
208
+
209
+    /**
210
+     * @return string|false
211
+     */
212
+    private function hostKeysPath() {
213
+        try {
214
+            $storage_view = \OCP\Files::getStorage('files_external');
215
+            if ($storage_view) {
216
+                return \OC::$server->getConfig()->getSystemValue('datadirectory', \OC::$SERVERROOT . '/data') .
217
+                    $storage_view->getAbsolutePath('') .
218
+                    'ssh_hostKeys';
219
+            }
220
+        } catch (\Exception $e) {
221
+        }
222
+        return false;
223
+    }
224
+
225
+    /**
226
+     * @param $keys
227
+     * @return bool
228
+     */
229
+    protected function writeHostKeys($keys) {
230
+        try {
231
+            $keyPath = $this->hostKeysPath();
232
+            if ($keyPath && file_exists($keyPath)) {
233
+                $fp = fopen($keyPath, 'w');
234
+                foreach ($keys as $host => $key) {
235
+                    fwrite($fp, $host . '::' . $key . "\n");
236
+                }
237
+                fclose($fp);
238
+                return true;
239
+            }
240
+        } catch (\Exception $e) {
241
+        }
242
+        return false;
243
+    }
244
+
245
+    /**
246
+     * @return array
247
+     */
248
+    protected function readHostKeys() {
249
+        try {
250
+            $keyPath = $this->hostKeysPath();
251
+            if (file_exists($keyPath)) {
252
+                $hosts = array();
253
+                $keys = array();
254
+                $lines = file($keyPath, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
255
+                if ($lines) {
256
+                    foreach ($lines as $line) {
257
+                        $hostKeyArray = explode("::", $line, 2);
258
+                        if (count($hostKeyArray) === 2) {
259
+                            $hosts[] = $hostKeyArray[0];
260
+                            $keys[] = $hostKeyArray[1];
261
+                        }
262
+                    }
263
+                    return array_combine($hosts, $keys);
264
+                }
265
+            }
266
+        } catch (\Exception $e) {
267
+        }
268
+        return array();
269
+    }
270
+
271
+    /**
272
+     * {@inheritdoc}
273
+     */
274
+    public function mkdir($path) {
275
+        try {
276
+            return $this->getConnection()->mkdir($this->absPath($path));
277
+        } catch (\Exception $e) {
278
+            return false;
279
+        }
280
+    }
281
+
282
+    /**
283
+     * {@inheritdoc}
284
+     */
285
+    public function rmdir($path) {
286
+        try {
287
+            $result = $this->getConnection()->delete($this->absPath($path), true);
288
+            // workaround: stray stat cache entry when deleting empty folders
289
+            // see https://github.com/phpseclib/phpseclib/issues/706
290
+            $this->getConnection()->clearStatCache();
291
+            return $result;
292
+        } catch (\Exception $e) {
293
+            return false;
294
+        }
295
+    }
296
+
297
+    /**
298
+     * {@inheritdoc}
299
+     */
300
+    public function opendir($path) {
301
+        try {
302
+            $list = $this->getConnection()->nlist($this->absPath($path));
303
+            if ($list === false) {
304
+                return false;
305
+            }
306
+
307
+            $id = md5('sftp:' . $path);
308
+            $dirStream = array();
309
+            foreach($list as $file) {
310
+                if ($file !== '.' && $file !== '..') {
311
+                    $dirStream[] = $file;
312
+                }
313
+            }
314
+            return IteratorDirectory::wrap($dirStream);
315
+        } catch(\Exception $e) {
316
+            return false;
317
+        }
318
+    }
319
+
320
+    /**
321
+     * {@inheritdoc}
322
+     */
323
+    public function filetype($path) {
324
+        try {
325
+            $stat = $this->getConnection()->stat($this->absPath($path));
326
+            if ((int) $stat['type'] === NET_SFTP_TYPE_REGULAR) {
327
+                return 'file';
328
+            }
329
+
330
+            if ((int) $stat['type'] === NET_SFTP_TYPE_DIRECTORY) {
331
+                return 'dir';
332
+            }
333
+        } catch (\Exception $e) {
334
+
335
+        }
336
+        return false;
337
+    }
338
+
339
+    /**
340
+     * {@inheritdoc}
341
+     */
342
+    public function file_exists($path) {
343
+        try {
344
+            return $this->getConnection()->stat($this->absPath($path)) !== false;
345
+        } catch (\Exception $e) {
346
+            return false;
347
+        }
348
+    }
349
+
350
+    /**
351
+     * {@inheritdoc}
352
+     */
353
+    public function unlink($path) {
354
+        try {
355
+            return $this->getConnection()->delete($this->absPath($path), true);
356
+        } catch (\Exception $e) {
357
+            return false;
358
+        }
359
+    }
360
+
361
+    /**
362
+     * {@inheritdoc}
363
+     */
364
+    public function fopen($path, $mode) {
365
+        try {
366
+            $absPath = $this->absPath($path);
367
+            switch($mode) {
368
+                case 'r':
369
+                case 'rb':
370
+                    if ( !$this->file_exists($path)) {
371
+                        return false;
372
+                    }
373
+                case 'w':
374
+                case 'wb':
375
+                case 'a':
376
+                case 'ab':
377
+                case 'r+':
378
+                case 'w+':
379
+                case 'wb+':
380
+                case 'a+':
381
+                case 'x':
382
+                case 'x+':
383
+                case 'c':
384
+                case 'c+':
385
+                    $context = stream_context_create(array('sftp' => array('session' => $this->getConnection())));
386
+                    $handle = fopen($this->constructUrl($path), $mode, false, $context);
387
+                    return RetryWrapper::wrap($handle);
388
+            }
389
+        } catch (\Exception $e) {
390
+        }
391
+        return false;
392
+    }
393
+
394
+    /**
395
+     * {@inheritdoc}
396
+     */
397
+    public function touch($path, $mtime=null) {
398
+        try {
399
+            if (!is_null($mtime)) {
400
+                return false;
401
+            }
402
+            if (!$this->file_exists($path)) {
403
+                $this->getConnection()->put($this->absPath($path), '');
404
+            } else {
405
+                return false;
406
+            }
407
+        } catch (\Exception $e) {
408
+            return false;
409
+        }
410
+        return true;
411
+    }
412
+
413
+    /**
414
+     * @param string $path
415
+     * @param string $target
416
+     * @throws \Exception
417
+     */
418
+    public function getFile($path, $target) {
419
+        $this->getConnection()->get($path, $target);
420
+    }
421
+
422
+    /**
423
+     * @param string $path
424
+     * @param string $target
425
+     * @throws \Exception
426
+     */
427
+    public function uploadFile($path, $target) {
428
+        $this->getConnection()->put($target, $path, NET_SFTP_LOCAL_FILE);
429
+    }
430
+
431
+    /**
432
+     * {@inheritdoc}
433
+     */
434
+    public function rename($source, $target) {
435
+        try {
436
+            if ($this->file_exists($target)) {
437
+                $this->unlink($target);
438
+            }
439
+            return $this->getConnection()->rename(
440
+                $this->absPath($source),
441
+                $this->absPath($target)
442
+            );
443
+        } catch (\Exception $e) {
444
+            return false;
445
+        }
446
+    }
447
+
448
+    /**
449
+     * {@inheritdoc}
450
+     */
451
+    public function stat($path) {
452
+        try {
453
+            $stat = $this->getConnection()->stat($this->absPath($path));
454
+
455
+            $mtime = $stat ? $stat['mtime'] : -1;
456
+            $size = $stat ? $stat['size'] : 0;
457
+
458
+            return array('mtime' => $mtime, 'size' => $size, 'ctime' => -1);
459
+        } catch (\Exception $e) {
460
+            return false;
461
+        }
462
+    }
463
+
464
+    /**
465
+     * @param string $path
466
+     * @return string
467
+     */
468
+    public function constructUrl($path) {
469
+        // Do not pass the password here. We want to use the Net_SFTP object
470
+        // supplied via stream context or fail. We only supply username and
471
+        // hostname because this might show up in logs (they are not used).
472
+        $url = 'sftp://' . urlencode($this->user) . '@' . $this->host . ':' . $this->port . $this->root . $path;
473
+        return $url;
474
+    }
475 475
 }
Please login to merge, or discard this patch.
apps/files_external/lib/Lib/Auth/PublicKey/RSAPrivateKey.php 1 patch
Indentation   +24 added lines, -24 removed lines patch added patch discarded remove patch
@@ -35,31 +35,31 @@
 block discarded – undo
35 35
  */
36 36
 class RSAPrivateKey extends AuthMechanism {
37 37
 
38
-	/** @var IConfig */
39
-	private $config;
38
+    /** @var IConfig */
39
+    private $config;
40 40
 
41
-	public function __construct(IL10N $l, IConfig $config) {
42
-		$this->config = $config;
41
+    public function __construct(IL10N $l, IConfig $config) {
42
+        $this->config = $config;
43 43
 
44
-		$this
45
-			->setIdentifier('publickey::rsa_private')
46
-			->setScheme(self::SCHEME_PUBLICKEY)
47
-			->setText($l->t('RSA private key'))
48
-			->addParameters([
49
-				new DefinitionParameter('user', $l->t('Username')),
50
-				(new DefinitionParameter('password', $l->t('Password')))
51
-					->setFlag(DefinitionParameter::FLAG_OPTIONAL)
52
-					->setType(DefinitionParameter::VALUE_PASSWORD),
53
-				new DefinitionParameter('private_key', $l->t('Private key')),
54
-			]);
55
-	}
44
+        $this
45
+            ->setIdentifier('publickey::rsa_private')
46
+            ->setScheme(self::SCHEME_PUBLICKEY)
47
+            ->setText($l->t('RSA private key'))
48
+            ->addParameters([
49
+                new DefinitionParameter('user', $l->t('Username')),
50
+                (new DefinitionParameter('password', $l->t('Password')))
51
+                    ->setFlag(DefinitionParameter::FLAG_OPTIONAL)
52
+                    ->setType(DefinitionParameter::VALUE_PASSWORD),
53
+                new DefinitionParameter('private_key', $l->t('Private key')),
54
+            ]);
55
+    }
56 56
 
57
-	public function manipulateStorageConfig(StorageConfig &$storage, IUser $user = null) {
58
-		$auth = new RSACrypt();
59
-		$auth->setPassword($this->config->getSystemValue('secret', ''));
60
-		if (!$auth->loadKey($storage->getBackendOption('private_key'))) {
61
-			throw new \RuntimeException('unable to load private key');
62
-		}
63
-		$storage->setBackendOption('public_key_auth', $auth);
64
-	}
57
+    public function manipulateStorageConfig(StorageConfig &$storage, IUser $user = null) {
58
+        $auth = new RSACrypt();
59
+        $auth->setPassword($this->config->getSystemValue('secret', ''));
60
+        if (!$auth->loadKey($storage->getBackendOption('private_key'))) {
61
+            throw new \RuntimeException('unable to load private key');
62
+        }
63
+        $storage->setBackendOption('public_key_auth', $auth);
64
+    }
65 65
 }
Please login to merge, or discard this patch.