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