summaryrefslogtreecommitdiffstats
path: root/core/lib/Drupal/Core/FileTransfer/SSH.php
blob: 82edcda5a120d3d59c62bb9083a0c005ae84c63c (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
<?php

/**
 * @file
 * Definition of Drupal\Core\FileTransfer\SSH.
 */

namespace Drupal\Core\FileTransfer;

/**
 * The SSH connection class for the update module.
 */
class SSH extends FileTransfer implements ChmodInterface {

  /**
   * Overrides Drupal\Core\FileTransfer\FileTransfer::__construct().
   */
  function __construct($jail, $username, $password, $hostname = "localhost", $port = 22) {
    $this->username = $username;
    $this->password = $password;
    $this->hostname = $hostname;
    $this->port = $port;
    parent::__construct($jail);
  }

  /**
   * Implements Drupal\Core\FileTransfer\FileTransfer::connect().
   */
  function connect() {
    $this->connection = @ssh2_connect($this->hostname, $this->port);
    if (!$this->connection) {
      throw new FileTransferException('SSH Connection failed to @host:@port', NULL, array('@host' => $this->hostname, '@port' => $this->port));
    }
    if (!@ssh2_auth_password($this->connection, $this->username, $this->password)) {
      throw new FileTransferException('The supplied username/password combination was not accepted.');
    }
  }

  /**
   * Overrides Drupal\Core\FileTransfer\FileTransfer::factory().
   */
  static function factory($jail, $settings) {
    $username = empty($settings['username']) ? '' : $settings['username'];
    $password = empty($settings['password']) ? '' : $settings['password'];
    $hostname = empty($settings['advanced']['hostname']) ? 'localhost' : $settings['advanced']['hostname'];
    $port = empty($settings['advanced']['port']) ? 22 : $settings['advanced']['port'];
    return new SSH($jail, $username, $password, $hostname, $port);
  }

  /**
   * Implements Drupal\Core\FileTransfer\FileTransfer::copyFileJailed().
   */
  protected function copyFileJailed($source, $destination) {
    if (!@ssh2_scp_send($this->connection, $source, $destination)) {
      throw new FileTransferException('Cannot copy @source_file to @destination_file.', NULL, array('@source' => $source, '@destination' => $destination));
    }
  }

  /**
   * Implements Drupal\Core\FileTransfer\FileTransfer::copyDirectoryJailed().
   */
  protected function copyDirectoryJailed($source, $destination) {
    if (@!ssh2_exec($this->connection, 'cp -Rp ' . escapeshellarg($source) . ' ' . escapeshellarg($destination))) {
      throw new FileTransferException('Cannot copy directory @directory.', NULL, array('@directory' => $source));
    }
  }

  /**
   * Implements Drupal\Core\FileTransfer\FileTransfer::createDirectoryJailed().
   */
  protected function createDirectoryJailed($directory) {
    if (@!ssh2_exec($this->connection, 'mkdir ' . escapeshellarg($directory))) {
      throw new FileTransferException('Cannot create directory @directory.', NULL, array('@directory' => $directory));
    }
  }

  /**
   * Implements Drupal\Core\FileTransfer\FileTransfer::removeDirectoryJailed().
   */
  protected function removeDirectoryJailed($directory) {
    if (@!ssh2_exec($this->connection, 'rm -Rf ' . escapeshellarg($directory))) {
      throw new FileTransferException('Cannot remove @directory.', NULL, array('@directory' => $directory));
    }
  }

  /**
   * Implements Drupal\Core\FileTransfer\FileTransfer::removeFileJailed().
   */
  protected function removeFileJailed($destination) {
    if (!@ssh2_exec($this->connection, 'rm ' . escapeshellarg($destination))) {
      throw new FileTransferException('Cannot remove @directory.', NULL, array('@directory' => $destination));
    }
  }

  /**
   * Implements Drupal\Core\FileTransfer\FileTransfer::isDirectory().
   *
   * WARNING: This is untested. It is not currently used, but should do the
   * trick.
   */
  public function isDirectory($path) {
    $directory = escapeshellarg($path);
    $cmd = "[ -d {$directory} ] && echo 'yes'";
    if ($output = @ssh2_exec($this->connection, $cmd)) {
      if ($output == 'yes') {
        return TRUE;
      }
      return FALSE;
    }
    else {
      throw new FileTransferException('Cannot check @path.', NULL, array('@path' => $path));
    }
  }

  /**
   * Implements Drupal\Core\FileTransfer\FileTransfer::isFile().
   */
  public function isFile($path) {
    $file = escapeshellarg($path);
    $cmd = "[ -f {$file} ] && echo 'yes'";
    if ($output = @ssh2_exec($this->connection, $cmd)) {
      if ($output == 'yes') {
        return TRUE;
      }
      return FALSE;
    }
    else {
      throw new FileTransferException('Cannot check @path.', NULL, array('@path' => $path));
    }
  }

  /**
   * Implements Drupal\Core\FileTransfer\ChmodInterface::chmodJailed().
   */
  function chmodJailed($path, $mode, $recursive) {
    $cmd = sprintf("chmod %s%o %s", $recursive ? '-R ' : '', $mode, escapeshellarg($path));
    if (@!ssh2_exec($this->connection, $cmd)) {
      throw new FileTransferException('Cannot change permissions of @path.', NULL, array('@path' => $path));
    }
  }

  /**
   * Overrides Drupal\Core\FileTransfer\FileTransfer::getSettingsForm().
   */
  public function getSettingsForm() {
    $form = parent::getSettingsForm();
    $form['advanced']['port']['#default_value'] = 22;
    return $form;
  }
}