Source code for paradrop.core.agent.wamp_session

'''
The WAMP session of the paradrop daemon
'''
import six

from twisted.internet.defer import inlineCallbacks
from autobahn.wamp import auth

from paradrop.lib.misc import pdinstall
from paradrop.base.output import out
from paradrop.base import nexus
from paradrop.base.cxbr import BaseSession


[docs]class WampSession(BaseSession): # Make this a class variable because a new WampSession object is created # whenever the WAMP connection resets, but we only call set_update_fetcher # on program initialization. update_fetcher = None def __init__(self, *args, **kwargs): self.uriPrefix = 'org.paradrop.' super(WampSession, self).__init__(*args, **kwargs)
[docs] def onConnect(self): out.info('Router session connected.') if (nexus.core.info.pdid and nexus.core.getKey('apitoken')): out.info('Starting WAMP-CRA authentication on realm "{}" as user "{}"...'\ .format(self.config.realm, nexus.core.info.pdid)) self.join(self.config.realm, [u'wampcra'], six.u(nexus.core.info.pdid))
[docs] def onChallenge(self, challenge): if challenge.method == u"wampcra": out.verbose("WAMP-CRA challenge received: {}".format(challenge)) wampPassword = nexus.core.getKey('apitoken') if u'salt' in challenge.extra: # salted secret key = auth.derive_key(wampPassword, challenge.extra['salt'], challenge.extra['iterations'], challenge.extra['keylen']) else: # plain, unsalted secret key = wampPassword # compute signature for challenge, using the key signature = auth.compute_wcs(key, challenge.extra['challenge']) # return the signature to the router for verification return signature else: raise Exception("Invalid authmethod {}".format(challenge.method))
[docs] @inlineCallbacks def onJoin(self, details): out.info('Router session joined') yield self.subscribe(self.updatesPending, self.uriPrefix + 'updatesPending') yield self.register(self.update, self.uriPrefix + 'update') yield BaseSession.onJoin(self, details)
[docs] def onLeave(self, details): out.info("Router session left: {}".format(details)) nexus.core.wamp_connected = False self.disconnect()
[docs] def onDisconnect(self): out.info("Router session disconnected.")
[docs] def update(self, pdid, data): print("Sending command {} to pdinstall".format(data['command'])) success = pdinstall.sendCommand(data['command'], data) # NOTE: If successful, this process will probably be going down soon. if success: return "Sent command to pdinstall" else: return "Sending command to pdinstall failed"
[docs] @classmethod def set_update_fetcher(cls, update_fetcher): WampSession.update_fetcher = update_fetcher
[docs] @inlineCallbacks def updatesPending(self, pdid): out.info('Notified of updates...') if WampSession.update_fetcher is not None: out.info('Pulling updates from the server...') yield WampSession.update_fetcher.pull_update()