Beispiel #1
0
    def link(self, credentials=None):
        """Executes the linking of the client.

        You can pass a credentials dictionary with username and password.
        Without credentials Linker will ask the credentials using the
        available UI.
        """
        if self._check_linking():
            self.logger.debug(
                u"Client already linked with id %s" % self.client_id)
            return True

        self.logger.info(
            u"This client must be linked to the server. "
            u"Starting the linking procedure...")

        linked = False
        pub_key = None
        pvt_key = None

        if credentials is None:
            credentials = {
                u'username': self.cfg.get(u'User', u'username'),
                u'password': u''
            }
            self.logger.debug(u"credentials from config are %r", credentials)
            credentials = self._ask_for_credentials(True, credentials)
            self.logger.debug(u"user specified credentials ")
        else:
            self.logger.debug(u"caller passed credentials ")


        while credentials['provided'] and not linked \
        and credentials['provided'] is not None:
            username = credentials['username']
            password = credentials['password']

            system = platform.system()
            hostname = platform.node()

            if pub_key is None:
                self._ui_controller.update_linking_status(LinkingStatus.SENDING)
                self.logger.info(u'Generating your public/private keys...')
                pub_key, pvt_key = self._generate_keys()
                self.logger.info(u'Public key generated...\n %s' % pub_key)

            authentication_digest = \
                self._generate_authDigest(username,  password)

            enc_key = CryptoUtils.generate_encryption_key()
            enc_mk = CryptoUtils.enckey_to_encmk(enc_key, username, password)

            try:
                self._ui_controller.update_linking_status(LinkingStatus.SENDING)

                data = json.dumps(dict(
                    authentication_digest=authentication_digest,
                    pub_key=pub_key,
                    platform=system,
                    hostname=hostname,
                    proposed_encryption_key=hexlify(enc_mk)
                ))

                # Note: We can't use requests yet because of the proxy patch
                # on httplib. Keep using httplib for now.
                # url = "https://%s/user/%s/client/link" % (self.host, username)
                # response = requests.post(url=url, data=data)

                conn = httplib.HTTPSConnection(self.host)
                #conn.set_debuglevel(1)
                target = urllib.quote("/user/%s/client/link" % username)
                conn.request("POST", target, data)
                response = conn.getresponse()

                if response.status == 200:
                    response_obj = json.loads(response.read())
                    self._on_success(response_obj, username, password, pvt_key)
                    linkstatus = LinkingStatus.SUCCESS
                    linked = True
                else:
                    self.logger.error(u"Linking error, status: %s, body: %s"
                                      % (response.status, response.read()))

                    error_table = {
                        # Unauthorized.
                        # It means: invalid authentication_digest
                        401: LinkingStatus.WRONG_CREDENTIALS,

                        # Not found.
                        # It means: unknown username
                        404: LinkingStatus.MALFORMED_USERNAME,

                        # Precondition failed.
                        # It means: there are already too many linked clients
                        412: LinkingStatus.LINKING_FAILED,

                        # Temporary unavailable.
                        503: LinkingStatus.SERVER_ERROR,

                        # Internal server error.
                        500: LinkingStatus.SERVER_ERROR
                    }

                    try:
                        linkstatus = error_table[response.status]
                    except KeyError:
                        linkstatus = LinkingStatus.UNKNOW_ERROR

                self._ui_controller.update_linking_status(linkstatus)
                credentials = self._ask_for_credentials(True, credentials)
                if credentials['provided'] is None:
                    break

            except (ConnectionException, BrokenPipeException, ProtocolException):
                self._ui_controller.update_linking_status(LinkingStatus.SERVER_UNREACHABLE)
                credentials = self._ask_for_credentials(True, credentials)

        if credentials['provided'] is None:
            return None

        if linked:
            self.logger.debug("Link done!!!")
        else:
            self.logger.debug("Link not done!!!")

        return linked
    def link(self, credentials=None):
        """Executes the linking of the client.

        You can pass a credentials dictionary with username and password.
        Without credentials Linker will ask the credentials using the
        available UI.
        """
        if self._check_linking():
            self.logger.debug(
                u"Client already linked with id %s" % self.client_id)
            return True

        self.logger.info(
            u"This client must be linked to the server. "
            u"Starting the linking procedure...")

        linked = False
        pub_key = None
        pvt_key = None

        if credentials is None:
            credentials = {
                u'username': self.cfg.get(u'User', u'username'),
                u'password': u''
            }
            self.logger.debug(u"credentials from config are %r", credentials)
            credentials = self._ask_for_credentials(True, credentials)
            self.logger.debug(u"user specified credentials ")
        else:
            self.logger.debug(u"caller passed credentials ")


        while credentials['provided'] and not linked \
        and credentials['provided'] is not None:
            username = credentials['username']
            password = credentials['password']

            system = platform.system()
            hostname = platform.node()

            if pub_key == None:
                self._ui_controller.update_linking_status(LinkingStatus.SENDING)
                self.logger.info(u'Generating your public/private keys...')
                pub_key, pvt_key = self._generate_keys()
                self.logger.info(u'Public key generated...\n %s' % pub_key)

            authentication_digest = \
                self._generate_authDigest(username,  password)

            enc_key = CryptoUtils.generate_encryption_key()
            enc_mk = CryptoUtils.enckey_to_encmk(enc_key, username, password)

            request = self._generate_request(
                username, authentication_digest, pub_key, system,
                hostname, enc_mk)
            try:
                self._ui_controller.update_linking_status(LinkingStatus.SENDING)
                response = self._communicate(request)
                result = response.getParameter("result")
                self.logger.debug(u"transaction result is %r" % linked)

                linkstatus = LinkingStatus.UNKNOW_ERROR
                if result:
                    self._on_success(response, username, password, pvt_key)
                    linkstatus = LinkingStatus.SUCCESS
                    linked = True
                else:
                    result_code = response.getParameter('result_code')
                    message = response.getParameter('message')
                    self.logger.error(u"ERROR: Result Code: %r Message: %r"
                        % (result_code, message))
                    responseCode = response.getParameter('result_code')
                    if responseCode in [
                            LinkingServiceCodes.UNSUPPORTED_MESSAGE_TYPE,
                            LinkingServiceCodes.UNSUPPORTED_PROTOCOL_VERSION,
                            LinkingServiceCodes.TOO_MANY_BUCKET
                        ]:
                        linkstatus = LinkingStatus.SERVER_ERROR
                    elif responseCode == LinkingServiceCodes.LINKING_FAILED:
                        linkstatus = LinkingStatus.LINKING_FAILED
                    elif responseCode == LinkingServiceCodes.BAD_USERNAME:
                        linkstatus = LinkingStatus.MALFORMED_USERNAME
                    elif responseCode == LinkingServiceCodes.INVALID_USER_CREDENTIAL:
                        linkstatus = LinkingStatus.WRONG_CREDENTIALS

                    #self.logger.debug(u"username %s, password %s"
                    #    % (credentials['username'], credentials['password']))
                self._ui_controller.update_linking_status(linkstatus)
                credentials = self._ask_for_credentials(True, credentials)
                if credentials['provided'] is None:
                    break

            except (ConnectionException, BrokenPipeException, ProtocolException):
                self._ui_controller.update_linking_status(LinkingStatus.SERVER_UNREACHABLE)
                credentials = self._ask_for_credentials(True, credentials)

        if credentials['provided'] is None:
            return None

        if linked:
            self.logger.debug("Link done!!!")
        else:
            self.logger.debug("Link not done!!!")

        return linked