def authenticate(self, password=None): # I'm just implementing the authentication scheme designed in the # protocol. Don't take this as any kind of assurance that it's secure. data = protocol.read(self.f, 9, self.encoding) assert data[:7] == 'PJLINK ' security = data[7] if security == '0': return None data += protocol.read(self.f, 9, self.encoding) assert security == '1' assert data[8] == ' ' salt = data[9:17] assert data[17] == '\r' if password is None: raise RuntimeError('projector needs a password') if callable(password): password = password() pass_data = (salt + password).encode('utf-8') pass_data_md5 = hashlib.md5(pass_data).hexdigest() # we *must* send a command to complete the procedure, # so we just get the power state. cmd_data = protocol.to_binary('POWR', '?') self.f.write(pass_data_md5 + cmd_data) self.f.flush() # read the response, see if it's a failed auth data = protocol.read(self.f, 7, self.encoding) if data == 'PJLINK ': # should be a failed auth if we get that data += protocol.read(self.f, 5, self.encoding) assert data == 'PJLINK ERRA\r' # it definitely is return False # good auth, so we should get a reply to the command we sent body, param = protocol.parse_response(self.f, self.encoding, data) # make sure we got a sensible response back assert body == 'POWR' if param in protocol.ERRORS: raise ProjectorError(protocol.ERRORS[param]) # but we don't care about the value if we did return True
def authenticate(self, password=None): # I'm just implementing the authentication scheme designed in the # protocol. Don't take this as any kind of assurance that it's secure. data = protocol.read(self.f, 9) assert data[:7] == 'PJLINK ' security = data[7] if security == '0': return None data += protocol.read(self.f, 9) assert security == '1' assert data[8] == ' ' salt = data[9:17] assert data[17] == '\r' if password is None: raise RuntimeError('projector needs a password') if callable(password): password = password() pass_data = (salt + password).encode('utf-8') pass_data_md5 = hashlib.md5(pass_data).hexdigest() # we *must* send a command to complete the procedure, # so we just get the power state. cmd_data = protocol.to_binary('POWR', '?') self.f.write(pass_data_md5 + cmd_data) self.f.flush() # read the response, see if it's a failed auth data = protocol.read(self.f, 7) if data == 'PJLINK ': # should be a failed auth if we get that data += protocol.read(self.f, 5) assert data == 'PJLINK ERRA\r' # it definitely is return False # good auth, so we should get a reply to the command we sent body, param = protocol.parse_response(self.f, data) # make sure we got a sensible response back assert body == 'POWR' if param in protocol.ERRORS: raise ProjectorError(protocol.ERRORS[param]) # but we don't care about the value if we did return True