/** * Handle process on close transport * * @param \React\Socket\Connection $conn */ public function handleClose(Connection $conn) { Logger::debug($this, "Raw socket closed " . $conn->getRemoteAddress()); $session = $this->sessions[$conn]; $this->sessions->detach($conn); $this->router->getEventDispatcher()->dispatch('connection_close', new ConnectionCloseEvent($session)); }
/** * Start transport provider * * @param \Thruway\Peer\ClientInterface $client * @param \React\EventLoop\LoopInterface $loop */ public function startTransportProvider(ClientInterface $client, LoopInterface $loop) { Logger::info($this, "Starting Transport"); $this->client = $client; $this->loop = $loop; $this->connector = new Factory($this->loop); $this->connector->__invoke($this->URL, ['wamp.2.json'])->then(function (WebSocket $conn) { Logger::info($this, "Pawl has connected"); $transport = new PawlTransport($conn, $this->loop); $transport->setSerializer(new JsonSerializer()); $this->client->onOpen($transport); $conn->on('message', function ($msg) use($transport) { Logger::debug($this, "Received: {$msg}"); try { $this->client->onMessage($transport, $transport->getSerializer()->deserialize($msg)); } catch (DeserializationException $e) { Logger::warning($this, "Deserialization exception occurred."); } catch (\Exception $e) { Logger::warning($this, "Exception occurred during onMessage: " . $e->getMessage()); } }); $conn->on('close', function ($conn) { Logger::info($this, "Pawl has closed"); $this->client->onClose('close'); }); $conn->on('pong', function ($frame, $ws) use($transport) { $transport->onPong($frame, $ws); }); }, function ($e) { $this->client->onClose('unreachable'); Logger::info($this, "Could not connect: {$e->getMessage()}"); // $this->loop->stop(); }); }
/** * Handles session start * * @param \Thruway\AbstractSession $session * @param \Thruway\Transport\TransportProviderInterface $transport */ public function onSessionStart($session, $transport) { $this->getCallee()->register($session, "thruway.auth.{$this->getMethodName()}.onhello", [$this, 'processHello'], ["replace_orphaned_session" => "yes"])->then(function () use($session) { $this->getCallee()->register($session, "thruway.auth.{$this->getMethodName()}.onauthenticate", [$this, 'preProcessAuthenticate'], ["replace_orphaned_session" => "yes"])->then(function () use($session) { $this->getCaller()->call($session, 'thruway.auth.registermethod', [$this->getMethodName(), ["onhello" => "thruway.auth.{$this->getMethodName()}.onhello", "onauthenticate" => "thruway.auth.{$this->getMethodName()}.onauthenticate"], $this->getAuthRealms()])->then(function ($args) { Logger::debug($this, "Authentication Method Registration Successful: {$this->getMethodName()}"); }); }); }); }
/** * Handles session start * * @param \Thruway\ClientSession $session * @param \Thruway\Transport\TransportProviderInterface $transport */ public function onSessionStart($session, $transport) { $session->register("thruway.auth.{$this->getMethodName()}.onhello", [$this, 'processHello'], ["replace_orphaned_session" => "yes"])->then(function () use($session) { $session->register("thruway.auth.{$this->getMethodName()}.onauthenticate", [$this, 'preProcessAuthenticate'], ["replace_orphaned_session" => "yes"])->then(function () use($session) { $registrations = new \stdClass(); $registrations->onhello = "thruway.auth.{$this->getMethodName()}.onhello"; $registrations->onauthenticate = "thruway.auth.{$this->getMethodName()}.onauthenticate"; $session->call('thruway.auth.registermethod', [$this->getMethodName(), $registrations, $this->getAuthRealms()])->then(function ($args) { Logger::debug($this, "Authentication Method Registration Successful: {$this->getMethodName()}"); }); }); }); }
/** * Get Authenticate message from challenge message * * @param \Thruway\Message\ChallengeMessage $msg * @return \Thruway\Message\AuthenticateMessage|boolean */ public function getAuthenticateFromChallenge(ChallengeMessage $msg) { Logger::info($this, "Got challenge"); Logger::debug($this, "Challenge Message: " . json_encode($msg)); if (!in_array($msg->getAuthMethod(), $this->getAuthMethods())) { //throw new \Exception("method isn't in methods"); return false; } if (!is_array($msg->getDetails())) { Logger::info($this, "No details sent with challenge"); return false; } $challenge = ''; if (isset($msg->getDetails()['challenge'])) { $challenge = $msg->getDetails()['challenge']; } else { Logger::info($this, "No challenge for wampcra?"); return false; } $keyToUse = $this->key; if (isset($msg->getDetails()['salt'])) { // we need a salted key $salt = $msg->getDetails()['salt']; $keyLen = 32; if (isset($msg->getDetails()['keylen'])) { if (is_numeric($msg->getDetails()['keylen'])) { $keyLen = $msg->getDetails()['keylen']; } else { Logger::error($this, "keylen is not numeric."); } } $iterations = 1000; if (isset($msg->getDetails()['iterations'])) { if (is_numeric($msg->getDetails()['iterations'])) { $iterations = $msg->getDetails()['iterations']; } else { Logger::error($this, "iterations is not numeric."); } } $keyToUse = $this->getDerivedKey($this->key, $salt, $iterations, $keyLen); } $token = base64_encode(hash_hmac('sha256', $challenge, $keyToUse, true)); $authMessage = new AuthenticateMessage($token); Logger::debug($this, "returning: " . json_encode($authMessage)); return $authMessage; }
/** * Add new realm * * @param \Thruway\Realm $realm * @throws \Thruway\Exception\InvalidRealmNameException * @throws \Exception */ public function addRealm(Realm $realm) { $realmName = $realm->getRealmName(); if (!static::validRealmName($realm->getRealmName())) { throw new InvalidRealmNameException(); } if (array_key_exists($realm->getRealmName(), $this->realms)) { throw new \Exception("There is already a realm \"" . $realm->getRealmName() . "\""); } Logger::debug($this, "Adding realm \"" . $realmName . "\""); $this->realms[$realm->getRealmName()] = $realm; $this->router->getEventDispatcher()->dispatch('new_realm', new NewRealmEvent($realm)); }
/** * Process on session leave * * @param \Thruway\Session $session */ public function leave(Session $session) { Logger::debug($this, "Leaving realm {$session->getRealm()->getRealmName()}"); $this->sessions->detach($session); }
/** * Process on session leave * * @param \Thruway\Session $session */ public function leave(Session $session) { Logger::debug($this, "Leaving realm {$session->getRealm()->getRealmName()}"); if ($this->getAuthenticationManager() !== null) { $this->getAuthenticationManager()->onSessionClose($session); } foreach ($this->roles as $role) { $role->leave($session); } $this->sessions->detach($session); }
/** * Add new realm * * @param \Thruway\Realm $realm * @throws \Thruway\Exception\InvalidRealmNameException * @throws \Exception */ public function addRealm(Realm $realm) { $realmName = $realm->getRealmName(); if (!static::validRealmName($realm->getRealmName())) { throw new InvalidRealmNameException(); } if (array_key_exists($realm->getRealmName(), $this->realms)) { throw new \Exception("There is already a realm \"" . $realm->getRealmName() . "\""); } Logger::debug($this, "Adding realm \"" . $realmName . "\""); if ($realm->getManager() instanceof ManagerDummy) { /** remind people that we don't setup the manager for them if they * are creating their own realms */ Logger::info($this, "Realm \"" . $realmName . "\" is using ManagerDummy"); } $this->realms[$realm->getRealmName()] = $realm; $this->router->getEventDispatcher()->dispatch('new_realm', new NewRealmEvent($realm)); }
/** * Handle close transport * * @param \Thruway\Transport\TransportInterface $transport */ public function onClose(TransportInterface $transport) { Logger::debug($this, "onClose from " . json_encode($transport->getTransportDetails())); /* @var $session \Thruway\Session */ $session = $this->sessions[$transport]; $session->onClose(); $this->sessions->detach($transport); }
/** @inheritdoc */ public function onMessage(ConnectionInterface $from, $msg) { Logger::debug($this, "onMessage: ({$msg})"); /** @var Session $session */ $session = $this->sessions[$from]; try { //$this->router->onMessage($transport, $transport->getSerializer()->deserialize($msg)); $msg = $session->getTransport()->getSerializer()->deserialize($msg); if ($msg instanceof HelloMessage) { $details = $msg->getDetails(); $details->transport = (object) $session->getTransport()->getTransportDetails(); $msg->setDetails($details); } $session->dispatchMessage($msg); } catch (DeserializationException $e) { Logger::alert($this, "Deserialization exception occurred."); } catch (\Exception $e) { Logger::alert($this, "Exception occurred during onMessage: " . $e->getMessage()); } }
/** * Triggered when a client sends data through the socket * * @param \Ratchet\ConnectionInterface $from The socket/connection that sent the message to your application * @param string $msg The message received * @throws \Exception */ public function onMessage(ConnectionInterface $from, $msg) { Logger::debug($this, "onMessage: ({$msg})"); /** @var TransportInterface $transport */ $transport = $this->transports[$from]; try { $this->peer->onMessage($transport, $transport->getSerializer()->deserialize($msg)); } catch (DeserializationException $e) { Logger::alert($this, "Deserialization exception occurred."); } catch (\Exception $e) { Logger::alert($this, "Exception occurred during onMessage: " . $e->getMessage()); } }
/** * Process a session leave * * @todo make this better * @param \Thruway\Session $session */ public function leave(Session $session) { $this->subscriptions->rewind(); while ($this->subscriptions->valid()) { /* @var $subscription \Thruway\Subscription */ $subscription = $this->subscriptions->current(); $this->subscriptions->next(); if ($subscription->getSession() == $session) { Logger::debug($this, "Leaving and unsubscribing: {$subscription->getTopic()}"); $this->subscriptions->detach($subscription); } } foreach ($this->topics as $topicName => $subscribers) { foreach ($subscribers as $key => $subscriber) { if ($session == $subscriber) { unset($subscribers[$key]); Logger::debug($this, "Removing session from topic list: {$topicName}"); } } } }
/** * @param Session $session * @param SubscribeMessage $msg * @return Subscription */ public function processSubscribe(Session $session, SubscribeMessage $msg) { $subscription = Subscription::createSubscriptionFromSubscribeMessage($session, $msg); $this->addSubscription($subscription); $subscription->setSubscriptionGroup($this); Logger::debug($this, "Added subscription to \"" . $this->getMatchType() . "\":\"" . $this->getUri() . "\""); $session->sendMessage(new SubscribedMessage($msg->getRequestId(), $subscription->getId())); return $subscription; }
/** * Handle process message * * @param \Thruway\Transport\TransportInterface $transport * @param \Thruway\Message\Message $msg */ public function onMessage(TransportInterface $transport, Message $msg) { Logger::debug($this, "Client onMessage: {$msg}"); $session = $this->session; if ($msg instanceof WelcomeMessage) { $this->processWelcome($session, $msg); } elseif ($msg instanceof AbortMessage) { $this->processAbort($session, $msg); } elseif ($msg instanceof GoodbyeMessage) { $this->processGoodbye($session, $msg); } elseif ($msg instanceof ChallengeMessage) { $this->processChallenge($session, $msg); } else { $this->processOther($session, $msg); } }
/** * Handle close transport * * @param \Thruway\Transport\TransportInterface $transport */ public function onClose(TransportInterface $transport) { Logger::debug($this, "onClose from " . json_encode($transport->getTransportDetails())); $this->sessions->detach($transport); }
/** * Handle process on close transport * * @param \React\Socket\Connection $conn */ public function handleClose(Connection $conn) { Logger::debug($this, "Raw socket closed " . $conn->getRemoteAddress()); $transport = $this->transports[$conn]; $this->transports->detach($conn); $this->peer->onClose($transport); }