pssht  latest
SSH server library written in PHP
PublicKey.php
1 <?php
2 
3 /*
4 * This file is part of pssht.
5 *
6 * (c) François Poirotte <clicky@erebot.net>
7 *
8 * For the full copyright and license information, please view the LICENSE
9 * file that was distributed with this source code.
10 */
11 
13 
15 
20 {
22  protected $store;
23 
30  public function __construct(\fpoirotte\Pssht\KeyStore $store)
31  {
32  $this->store = $store;
33  }
34 
35  public static function getName()
36  {
37  return 'publickey';
38  }
39 
40  public function check(
41  \fpoirotte\Pssht\Messages\USERAUTH\REQUEST\Base $message,
42  \fpoirotte\Pssht\Transport $transport,
43  array &$context
44  ) {
45  if (!($message instanceof \fpoirotte\Pssht\Messages\USERAUTH\REQUEST\PublicKey)) {
46  throw new \InvalidArgumentException();
47  }
48 
49  if ($message->getSignature() !== null) {
50  return self::CHECK_OK;
51  }
52 
54  if ($algos->getClass('Key', $message->getAlgorithm()) !== null &&
55  $this->store->exists($message->getUserName(), $message->getKey())) {
56  $response = new \fpoirotte\Pssht\Messages\USERAUTH\PK\OK(
57  $message->getAlgorithm(),
58  $message->getKey()
59  );
60  $transport->writeMessage($response);
61  return self::CHECK_IGNORE;
62  }
63  return self::CHECK_REJECT;
64  }
65 
66  public function authenticate(
67  \fpoirotte\Pssht\Messages\USERAUTH\REQUEST\Base $message,
68  \fpoirotte\Pssht\Transport $transport,
69  array &$context
70  ) {
71  if (!($message instanceof \fpoirotte\Pssht\Messages\USERAUTH\REQUEST\PublicKey)) {
72  throw new \InvalidArgumentException();
73  }
74 
75 
76  if ($message->getSignature() === null) {
77  return self::AUTH_REJECT;
78  }
79 
80  $logging = \Plop\Plop::getInstance();
81  $reverse = gethostbyaddr($transport->getAddress());
83  $cls = $algos->getClass('Key', $message->getAlgorithm());
84  if ($cls === null || !$this->store->exists($message->getUserName(), $message->getKey())) {
85  $logging->info(
86  'Rejected public key connection from remote host ' .
87  '"%(reverse)s" (%(address)s) to "%(luser)s": ' .
88  'unsupported key',
89  array(
90  'luser' => escape($message->getUserName()),
91  'reverse' => $reverse,
92  'address' => $transport->getAddress(),
93  )
94  );
95  return self::AUTH_REJECT;
96  }
97 
98  $decoder = new \fpoirotte\Pssht\Wire\Decoder();
99  $decoder->getBuffer()->push($message->getKey());
100  if ($decoder->decodeString() !== $message->getAlgorithm()) {
101  // The key is not of the type claimed.
102  return self::AUTH_REJECT;
103  }
104  $key = $cls::unserialize($decoder);
105 
106  $encoder = new \fpoirotte\Pssht\Wire\Encoder();
107  $encoder->encodeString($context['DH']->getExchangeHash());
108  $encoder->encodeBytes(chr(\fpoirotte\Pssht\Messages\USERAUTH\REQUEST\Base::getMessageId()));
109  $encoder->encodeString($message->getUserName());
110  $encoder->encodeString($message->getServiceName());
111  $encoder->encodeString(static::getName());
112  $encoder->encodeBoolean(true);
113  $encoder->encodeString($message->getAlgorithm());
114  $encoder->encodeString($message->getKey());
115 
116  if ($key->check($encoder->getBuffer()->get(0), $message->getSignature())) {
117  $logging->info(
118  'Accepted public key connection from remote host '.
119  '"%(reverse)s" (%(address)s) to "%(luser)s" ' .
120  '(using "%(algorithm)s" algorithm)',
121  array(
122  'luser' => escape($message->getUserName()),
123  'reverse' => $reverse,
124  'algorithm' => escape($message->getAlgorithm()),
125  'address' => $transport->getAddress(),
126  )
127  );
128  return self::AUTH_ACCEPT;
129  }
130 
131  $logging->info(
132  'Rejected public key connection from remote host ' .
133  '"%(reverse)s" (%(address)s) to "%(luser)s": '.
134  'invalid signature',
135  array(
136  'luser' => escape($message->getUserName()),
137  'reverse' => $reverse,
138  'address' => $transport->getAddress(),
139  )
140  );
141  return self::AUTH_REJECT;
142  }
143 }
__construct(\fpoirotte\Pssht\KeyStore $store)
Definition: PublicKey.php:30
static getName()
Return the name of the algorithm.
Definition: PublicKey.php:35
check(\fpoirotte\Pssht\Messages\USERAUTH\REQUEST\Base $message,\fpoirotte\Pssht\Transport $transport, array &$context)
Definition: PublicKey.php:40
authenticate(\fpoirotte\Pssht\Messages\USERAUTH\REQUEST\Base $message,\fpoirotte\Pssht\Transport $transport, array &$context)
Definition: PublicKey.php:66
$store
Store for the public keys.
Definition: PublicKey.php:22