46 throw new \InvalidArgumentException();
49 return self::CHECK_OK;
58 throw new \InvalidArgumentException();
61 $logging = \Plop\Plop::getInstance();
62 $reverse = gethostbyaddr($transport->getAddress());
63 $untrustedHost = rtrim($message->getHostname(),
'.');
65 $cls = $algos->getClass(
'Key', $message->getAlgorithm());
67 if ($cls === null || !$this->store->exists($message->getUserName(), $message->getKey())) {
69 'Rejected host based connection from "%(ruser)s@%(rhost)s" ' .
70 '(%(ruser)s@%(reverse)s [%(address)s]) to "%(luser)s" '.
73 'ruser' => escape($message->getRemoteUser()),
74 'luser' => escape($message->getUserName()),
75 'rhost' => escape($untrustedHost),
76 'reverse' => $reverse,
77 'address' => $transport->getAddress(),
80 return self::AUTH_REMOVE;
83 $decoder = new \fpoirotte\Pssht\Wire\Decoder();
84 $decoder->getBuffer()->push($message->getKey());
85 if ($decoder->decodeString() !== $message->getAlgorithm()) {
87 return self::AUTH_REJECT;
89 $key = $cls::unserialize($decoder);
91 $encoder = new \fpoirotte\Pssht\Wire\Encoder();
92 $encoder->encodeString($context[
'DH']->getExchangeHash());
94 $encoder->encodeString($message->getUserName());
95 $encoder->encodeString($message->getServiceName());
96 $encoder->encodeString(static::getName());
97 $encoder->encodeString($message->getAlgorithm());
98 $encoder->encodeString($message->getKey());
99 $encoder->encodeString($message->getHostname());
100 $encoder->encodeString($message->getRemoteUser());
102 if (!$key->check($encoder->getBuffer()->get(0), $message->getSignature())) {
104 'Rejected host based connection from "%(ruser)s@%(rhost)s" ' .
105 '(%(ruser)s@%(reverse)s [%(address)s]) to "%(luser)s" ' .
106 '(invalid signature)',
108 'ruser' => escape($message->getRemoteUser()),
109 'luser' => escape($message->getUserName()),
110 'rhost' => escape($untrustedHost),
111 'reverse' => $reverse,
112 'address' => $transport->getAddress(),
115 return self::AUTH_REJECT;
118 if ($reverse !== $untrustedHost) {
120 'Ignored reverse lookup mismatch for %(address)s (' .
121 '"%(reverse)s" vs. "%(untrusted)s")',
123 'address' => $transport->getAddress(),
124 'reverse' => $reverse,
125 'untrusted' => escape($untrustedHost),
130 if ($message->getUserName() !== $message->getRemoteUser()) {
132 'Rejected host based connection from "%(ruser)s@%(rhost)s" ' .
133 '(%(ruser)s@%(reverse)s [%(address)s]): ' .
134 'remote user does not match local user (%(luser)s)',
136 'ruser' => escape($message->getRemoteUser()),
137 'luser' => escape($message->getUserName()),
138 'rhost' => escape($untrustedHost),
139 'reverse' => $reverse,
140 'address' => $transport->getAddress(),
143 return self::AUTH_REMOVE;
147 'Accepted host based connection from "%(ruser)s@%(rhost)s" ' .
148 '(%(ruser)s@%(reverse)s [%(address)s]) to "%(luser)s" ' .
149 '(using "%(algorithm)s" algorithm)',
151 'ruser' => escape($message->getRemoteUser()),
152 'luser' => escape($message->getUserName()),
153 'rhost' => escape($untrustedHost),
154 'reverse' => $reverse,
155 'address' => $transport->getAddress(),
156 'algorithm' => escape($message->getAlgorithm()),
159 return self::AUTH_ACCEPT;
__construct(\fpoirotte\Pssht\KeyStore $store)
check(\fpoirotte\Pssht\Messages\USERAUTH\REQUEST\Base $message,\fpoirotte\Pssht\Transport $transport, array &$context)
$store
Store for the host keys.
authenticate(\fpoirotte\Pssht\Messages\USERAUTH\REQUEST\Base $message,\fpoirotte\Pssht\Transport $transport, array &$context)
static getName()
Return the name of the algorithm.