class XpraClientBase(gobject.GObject): """Base class for Xpra clients. Provides the glue code for: * sending packets via Protocol * handling packets received via _process_packet """ __gsignals__ = {"handshake-complete": n_arg_signal(0), "received-gibberish": n_arg_signal(1)} def __init__(self, opts): gobject.GObject.__init__(self) self.exit_code = None self.password_file = opts.password_file self.encoding = opts.encoding self.jpegquality = opts.jpegquality self._protocol = None self.server_capabilities = {} self.init_packet_handlers() def ready(self, conn): log.debug("ready(%s)", conn) self._protocol = Protocol(conn, self.process_packet) ClientSource(self._protocol) self._protocol.start() def init_packet_handlers(self): self._packet_handlers = { "challenge": self._process_challenge, "disconnect": self._process_disconnect, "hello": self._process_hello, "set_deflate": self._process_set_deflate, Protocol.CONNECTION_LOST: self._process_connection_lost, Protocol.GIBBERISH: self._process_gibberish, } def send_hello(self, challenge_response=None): hello = self.make_hello(challenge_response) log.debug("send_hello(%s) packet=%s", challenge_response, hello) self.send(["hello", hello]) def make_hello(self, challenge_response=None): capabilities = {"version": xpra.__version__} if challenge_response: capabilities["challenge_response"] = challenge_response if self.encoding: capabilities["encoding"] = self.encoding capabilities["encodings"] = ENCODINGS if self.jpegquality: capabilities["jpeg"] = self.jpegquality capabilities["platform"] = sys.platform capabilities["raw_packets"] = True capabilities["server-window-resize"] = True capabilities["randr_notify"] = False # only client.py cares about this return capabilities def send(self, packet): if self._protocol and self._protocol.source: self._protocol.source.queue_ordinary_packet(packet) def send_now(self, packet): if self._protocol and self._protocol.source: self._protocol.source.queue_priority_packet(packet) def cleanup(self): if self._protocol: self._protocol.close() self._protocol = None def run(self): raise Exception("override me!") def quit(self, exit_code=0): if self.exit_code is None: self.exit_code = exit_code raise Exception("override me!") def _process_disconnect(self, packet): log.error("server requested disconnect: %s", packet[1:]) self.quit(0) def _process_connection_lost(self, packet): log.error("Connection lost") self.quit(1) def _process_challenge(self, packet): if not self.password_file: log.error("password is required by the server") self.quit(2) return import hmac try: passwordFile = open(self.password_file, "rU") password = passwordFile.read() passwordFile.close() while password.endswith("\n") or password.endswith("\r"): password = password[:-1] except IOError, e: log.error("failed to open password file %s: %s", self.password_file, e) self.quit(3) return salt = packet[1] challenge_response = hmac.HMAC(password, salt) self.send_hello(challenge_response.hexdigest())
class XpraClientBase(gobject.GObject): """Base class for Xpra clients. Provides the glue code for: * sending packets via Protocol * handling packets received via _process_packet """ __gsignals__ = { "handshake-complete": n_arg_signal(0), "received-gibberish": n_arg_signal(1), } def __init__(self, opts): gobject.GObject.__init__(self) self.password_file = opts.password_file self.encoding = opts.encoding self.jpegquality = opts.jpegquality self._protocol = None self.init_packet_handlers() def ready(self, conn): log.debug("ready(%s)", conn) self._protocol = Protocol(conn, self.process_packet) ClientSource(self._protocol) def init_packet_handlers(self): self._packet_handlers = { "challenge": self._process_challenge, "disconnect": self._process_disconnect, "hello": self._process_hello, "set_deflate": self._process_set_deflate, Protocol.CONNECTION_LOST: self._process_connection_lost, Protocol.GIBBERISH: self._process_gibberish, } def send_hello(self, challenge_response=None): hello = self.make_hello(challenge_response) log.debug("send_hello(%s) packet=%s", challenge_response, hello) self.send(["hello", hello]) def make_hello(self, challenge_response=None): capabilities = {"__prerelease_version": xpra.__version__} capabilities["version"] = xpra.__version__ if challenge_response: capabilities["challenge_response"] = challenge_response capabilities["dynamic_compression"] = True capabilities["packet_size"] = True if self.encoding: capabilities["encoding"] = self.encoding capabilities["encodings"] = ENCODINGS if self.jpegquality: capabilities["jpeg"] = self.jpegquality return capabilities def send(self, packet): self._protocol.source.queue_ordinary_packet(packet) def send_now(self, packet): self._protocol.source.queue_priority_packet(packet) def cleanup(self): if self._protocol: self._protocol.close() self._protocol = None def run(self): raise Exception("override me!") def quit(self, *args): raise Exception("override me!") def _process_disconnect(self, packet): log.error("server requested disconnect: %s" % str(packet)) self.quit() return def _process_challenge(self, packet): if not self.password_file: log.error("password is required by the server") self.quit() return import hmac passwordFile = open(self.password_file, "rU") password = passwordFile.read() salt = packet[1] challenge_response = hmac.HMAC(password, salt) self.send_hello(challenge_response.hexdigest()) def _process_hello(self, packet): pass def _process_set_deflate(self, packet): #this tell us the server has set its compressor #(the decompressor has been enabled - see protocol) log.debug("set_deflate: %s", packet[1:]) def _process_connection_lost(self, packet): log.error("Connection lost") self.quit() def _process_gibberish(self, packet): (_, data) = packet log.info("Received uninterpretable nonsense: %s", repr(data)) self.emit("received-gibberish", data) def process_packet(self, proto, packet): packet_type = packet[0] self._packet_handlers[packet_type](packet)
class XpraClientBase(gobject.GObject): """Base class for Xpra clients. Provides the glue code for: * sending packets via Protocol * handling packets received via _process_packet """ __gsignals__ = { "handshake-complete": n_arg_signal(0), "received-gibberish": n_arg_signal(1), } def __init__(self, opts): gobject.GObject.__init__(self) self.exit_code = None self.password_file = opts.password_file self.encoding = opts.encoding self.jpegquality = opts.jpegquality self._protocol = None self.server_capabilities = {} self.init_packet_handlers() def ready(self, conn): log.debug("ready(%s)", conn) self._protocol = Protocol(conn, self.process_packet) ClientSource(self._protocol) self._protocol.start() def init_packet_handlers(self): self._packet_handlers = { "challenge": self._process_challenge, "disconnect": self._process_disconnect, "hello": self._process_hello, "set_deflate": self._process_set_deflate, Protocol.CONNECTION_LOST: self._process_connection_lost, Protocol.GIBBERISH: self._process_gibberish, } def send_hello(self, challenge_response=None): hello = self.make_hello(challenge_response) log.debug("send_hello(%s) packet=%s", challenge_response, hello) self.send(["hello", hello]) def make_hello(self, challenge_response=None): capabilities = {} add_version_info(capabilities) if challenge_response: capabilities["challenge_response"] = challenge_response if self.encoding: capabilities["encoding"] = self.encoding capabilities["encodings"] = ENCODINGS if self.jpegquality: capabilities["jpeg"] = self.jpegquality capabilities["platform"] = sys.platform capabilities["raw_packets"] = True capabilities["chunked_compression"] = True capabilities["rencode"] = has_rencode capabilities["server-window-resize"] = True capabilities["randr_notify"] = False #only client.py cares about this return capabilities def send(self, packet): if self._protocol and self._protocol.source: self._protocol.source.queue_ordinary_packet(packet) def send_now(self, packet): if self._protocol and self._protocol.source: self._protocol.source.queue_priority_packet(packet) def cleanup(self): if self._protocol: self._protocol.close() self._protocol = None def run(self): raise Exception("override me!") def quit(self, exit_code=0): if self.exit_code is None: self.exit_code = exit_code raise Exception("override me!") def _process_disconnect(self, packet): log.error("server requested disconnect: %s", packet[1:]) self.quit(0) def _process_connection_lost(self, packet): log.error("Connection lost") self.quit(1) def _process_challenge(self, packet): if not self.password_file: log.error("password is required by the server") self.quit(2) return import hmac try: passwordFile = open(self.password_file, "rU") password = passwordFile.read() passwordFile.close() while password.endswith("\n") or password.endswith("\r"): password = password[:-1] except IOError, e: log.error("failed to open password file %s: %s", self.password_file, e) self.quit(3) return salt = packet[1] challenge_response = hmac.HMAC(password, salt) self.send_hello(challenge_response.hexdigest())
class XpraClientBase(gobject.GObject): """Base class for Xpra clients. Provides the glue code for: * sending packets via Protocol * handling packets received via _process_packet """ __gsignals__ = { "handshake-complete": n_arg_signal(0), "first-ui-received" : n_arg_signal(0), "received-gibberish": n_arg_signal(1), } def __init__(self, opts): gobject.GObject.__init__(self) self.exit_code = None self.compression_level = opts.compression_level self.password = None self.password_file = opts.password_file self.encoding = opts.encoding self.quality = opts.quality self._protocol = None self.server_capabilities = {} self._remote_version = None self._remote_revision = None self.init_packet_handlers() def ready(self, conn): log.debug("ready(%s)", conn) self._protocol = Protocol(conn, self.process_packet) self._protocol.set_compression_level(self.compression_level) ClientSource(self._protocol) self._protocol.start() def init_packet_handlers(self): self._packet_handlers = {} self._ui_packet_handlers = { "challenge": self._process_challenge, "disconnect": self._process_disconnect, "hello": self._process_hello, "set_deflate": self._process_set_deflate, Protocol.CONNECTION_LOST: self._process_connection_lost, Protocol.GIBBERISH: self._process_gibberish, } def send_hello(self, challenge_response=None): hello = self.make_hello(challenge_response) log.debug("send_hello(%s) packet=%s", challenge_response, hello) self.send(["hello", hello]) def make_hello(self, challenge_response=None): capabilities = {} add_version_info(capabilities) if challenge_response: capabilities["challenge_response"] = challenge_response if self.encoding: capabilities["encoding"] = self.encoding capabilities["encodings"] = ENCODINGS if self.quality>=0: capabilities["jpeg"] = self.quality capabilities["quality"] = self.quality capabilities["platform"] = sys.platform capabilities["client_type"] = "Python/Gobject" capabilities["raw_packets"] = True capabilities["chunked_compression"] = True capabilities["rencode"] = has_rencode capabilities["server-window-resize"] = True u = hashlib.sha512() u.update(str(get_machine_id())) if os.name=="posix": u.update("/") u.update(str(os.getuid())) u.update("/") u.update(str(os.getgid())) capabilities["uuid"] = u.hexdigest() capabilities["randr_notify"] = False #only client.py cares about this capabilities["windows"] = False #only client.py cares about this return capabilities def idle_send(self, packet): gobject.idle_add(self.send, packet) def send(self, packet): if self._protocol and self._protocol.source: self._protocol.source.queue_ordinary_packet(packet) def send_now(self, packet): if self._protocol and self._protocol.source: self._protocol.source.queue_priority_packet(packet) def cleanup(self): if self._protocol: self._protocol.close() self._protocol = None def run(self): raise Exception("override me!") def quit(self, exit_code=0): if self.exit_code is None: self.exit_code = exit_code raise Exception("override me!") def warn_and_quit(self, exit_code, warning): log.warn(warning) self.quit(exit_code) def _process_disconnect(self, packet): if len(packet)==2: info = packet[1] else: info = packet[1:] self.warn_and_quit(EXIT_OK, "server requested disconnect: %s" % info) def _process_connection_lost(self, packet): self.warn_and_quit(EXIT_CONNECTION_LOST, "Connection lost") def _process_challenge(self, packet): if not self.password_file and not self.password: self.warn_and_quit(EXIT_PASSWORD_REQUIRED, "password is required by the server") return if not self.password: self.load_password() log("password read from file %s is %s", self.password_file, self.password) if self.password: salt = packet[1] import hmac challenge_response = hmac.HMAC(self.password, salt) self.send_hello(challenge_response.hexdigest()) def load_password(self): try: passwordFile = open(self.password_file, "rU") self.password = passwordFile.read() passwordFile.close() while self.password.endswith("\n") or self.password.endswith("\r"): self.password = self.password[:-1] except IOError, e: self.warn_and_quit(EXIT_PASSWORD_FILE_ERROR, "failed to open password file %s: %s" % (self.password_file, e))
class XpraClientBase(gobject.GObject): """Base class for Xpra clients. Provides the glue code for: * sending packets via Protocol * handling packets received via _process_packet """ __gsignals__ = { "handshake-complete": n_arg_signal(0), "received-gibberish": n_arg_signal(1), } def __init__(self, opts): gobject.GObject.__init__(self) self.password_file = opts.password_file self.encoding = opts.encoding self.jpegquality = opts.jpegquality self._protocol = None self.init_packet_handlers() def ready(self, conn): log.debug("ready(%s)", conn) self._protocol = Protocol(conn, self.process_packet) ClientSource(self._protocol) def init_packet_handlers(self): self._packet_handlers = { "challenge": self._process_challenge, "disconnect": self._process_disconnect, "hello": self._process_hello, "set_deflate": self._process_set_deflate, Protocol.CONNECTION_LOST: self._process_connection_lost, Protocol.GIBBERISH: self._process_gibberish, } def send_hello(self, challenge_response=None): hello = self.make_hello(challenge_response) log.debug("send_hello(%s) packet=%s", challenge_response, hello) self.send(["hello", hello]) def make_hello(self, challenge_response=None): capabilities = {"version": xpra.__version__} if challenge_response: capabilities["challenge_response"] = challenge_response if self.encoding: capabilities["encoding"] = self.encoding capabilities["encodings"] = ENCODINGS if self.jpegquality: capabilities["jpeg"] = self.jpegquality capabilities["packet_size"] = True #will be removed (only for compatibility with old versions): capabilities["dynamic_compression"] = True capabilities["__prerelease_version"] = xpra.__version__ return capabilities def send(self, packet): self._protocol.source.queue_ordinary_packet(packet) def send_now(self, packet): self._protocol.source.queue_priority_packet(packet) def cleanup(self): if self._protocol: self._protocol.close() self._protocol = None def run(self): raise Exception("override me!") def quit(self, *args): raise Exception("override me!") def _process_disconnect(self, packet): log.error("server requested disconnect: %s", packet[1:]) self.quit() return def _process_challenge(self, packet): if not self.password_file: log.error("password is required by the server") self.quit() return import hmac try: passwordFile = open(self.password_file, "rU") password = passwordFile.read() except IOError, e: log.error("failed to open password file %s: %s", self.password_file, e) self.quit() return salt = packet[1] challenge_response = hmac.HMAC(password, salt) self.send_hello(challenge_response.hexdigest())
class XpraClientBase(gobject.GObject): """Base class for Xpra clients. Provides the glue code for: * sending packets via Protocol * handling packets received via _process_packet """ __gsignals__ = { "handshake-complete": n_arg_signal(0), "first-ui-received": n_arg_signal(0), "received-gibberish": n_arg_signal(1), } def __init__(self, opts): gobject.GObject.__init__(self) self.exit_code = None self.compression_level = opts.compression_level self.password = None self.password_file = opts.password_file self.encoding = opts.encoding self.quality = opts.quality self._protocol = None self.server_capabilities = {} self._remote_version = None self._remote_revision = None self.init_packet_handlers() def ready(self, conn): log.debug("ready(%s)", conn) self._protocol = Protocol(conn, self.process_packet) self._protocol.set_compression_level(self.compression_level) ClientSource(self._protocol) self._protocol.start() def init_packet_handlers(self): self._packet_handlers = {} self._ui_packet_handlers = { "challenge": self._process_challenge, "disconnect": self._process_disconnect, "hello": self._process_hello, "set_deflate": self._process_set_deflate, Protocol.CONNECTION_LOST: self._process_connection_lost, Protocol.GIBBERISH: self._process_gibberish, } def send_hello(self, challenge_response=None): hello = self.make_hello(challenge_response) log.debug("send_hello(%s) packet=%s", challenge_response, hello) self.send(["hello", hello]) def make_hello(self, challenge_response=None): capabilities = {} add_version_info(capabilities) if challenge_response: capabilities["challenge_response"] = challenge_response if self.encoding: capabilities["encoding"] = self.encoding capabilities["encodings"] = ENCODINGS if self.quality >= 0: capabilities["jpeg"] = self.quality capabilities["quality"] = self.quality capabilities["platform"] = sys.platform capabilities["client_type"] = "Python/Gobject" capabilities["raw_packets"] = True capabilities["chunked_compression"] = True capabilities["rencode"] = has_rencode capabilities["server-window-resize"] = True u = hashlib.sha512() u.update(str(get_machine_id())) if os.name == "posix": u.update("/") u.update(str(os.getuid())) u.update("/") u.update(str(os.getgid())) capabilities["uuid"] = u.hexdigest() capabilities["randr_notify"] = False #only client.py cares about this capabilities["windows"] = False #only client.py cares about this return capabilities def idle_send(self, packet): gobject.idle_add(self.send, packet) def send(self, packet): if self._protocol and self._protocol.source: self._protocol.source.queue_ordinary_packet(packet) def send_now(self, packet): if self._protocol and self._protocol.source: self._protocol.source.queue_priority_packet(packet) def cleanup(self): if self._protocol: self._protocol.close() self._protocol = None def run(self): raise Exception("override me!") def quit(self, exit_code=0): if self.exit_code is None: self.exit_code = exit_code raise Exception("override me!") def warn_and_quit(self, exit_code, warning): log.warn(warning) self.quit(exit_code) def _process_disconnect(self, packet): if len(packet) == 2: info = packet[1] else: info = packet[1:] self.warn_and_quit(EXIT_OK, "server requested disconnect: %s" % info) def _process_connection_lost(self, packet): self.warn_and_quit(EXIT_CONNECTION_LOST, "Connection lost") def _process_challenge(self, packet): if not self.password_file and not self.password: self.warn_and_quit(EXIT_PASSWORD_REQUIRED, "password is required by the server") return if not self.password: self.load_password() log("password read from file %s is %s", self.password_file, self.password) if self.password: salt = packet[1] import hmac challenge_response = hmac.HMAC(self.password, salt) self.send_hello(challenge_response.hexdigest()) def load_password(self): try: passwordFile = open(self.password_file, "rU") self.password = passwordFile.read() passwordFile.close() while self.password.endswith("\n") or self.password.endswith("\r"): self.password = self.password[:-1] except IOError, e: self.warn_and_quit( EXIT_PASSWORD_FILE_ERROR, "failed to open password file %s: %s" % (self.password_file, e))
class XpraClientBase(gobject.GObject): """Base class for Xpra clients. Provides the glue code for: * sending packets via Protocol * handling packets received via _process_packet """ __gsignals__ = { "handshake-complete": n_arg_signal(0), "first-ui-received" : n_arg_signal(0), "received-gibberish": n_arg_signal(1), } def __init__(self, opts): gobject.GObject.__init__(self) self.exit_code = None self.compression_level = opts.compression_level self.password = None self.password_file = opts.password_file self.password_sent = False self.encoding = opts.encoding self.encryption = opts.encryption self.quality = opts.quality self.min_quality = opts.min_quality self.speed = opts.speed self.min_speed = opts.min_speed #protocol stuff: self._protocol = None self._priority_packets = [] self._ordinary_packets = [] self._mouse_position = None #server state and caps: self.server_capabilities = {} self._remote_version = None self._remote_revision = None self.make_uuid() self.init_packet_handlers() def ready(self, conn): log.debug("ready(%s)", conn) self._protocol = Protocol(conn, self.process_packet, self.next_packet) self._protocol.large_packets.append("keymap-changed") self._protocol.large_packets.append("server-settings") self._protocol.set_compression_level(self.compression_level) self._protocol.start() self.have_more = self._protocol.source_has_more def init_packet_handlers(self): self._packet_handlers = { "hello": self._process_hello, } self._ui_packet_handlers = { "challenge": self._process_challenge, "disconnect": self._process_disconnect, "set_deflate": self._process_set_deflate, Protocol.CONNECTION_LOST: self._process_connection_lost, Protocol.GIBBERISH: self._process_gibberish, } def send_hello(self, challenge_response=None): hello = self.make_hello(challenge_response) log.debug("send_hello(%s) packet=%s", challenge_response, hello) self.send("hello", hello) def make_hello(self, challenge_response=None): capabilities = {} add_version_info(capabilities) if challenge_response: assert self.password capabilities["challenge_response"] = challenge_response if self.encryption: assert self.encryption in ENCRYPTION_CIPHERS capabilities["cipher"] = self.encryption iv = uuid.uuid4().hex[:16] capabilities["cipher.iv"] = iv key_salt = uuid.uuid4().hex capabilities["cipher.key_salt"] = key_salt iterations = 1000 capabilities["cipher.key_stretch_iterations"] = iterations self._protocol.set_cipher_in(self.encryption, iv, self.get_password(), key_salt, iterations) if self.encoding: capabilities["encoding"] = self.encoding capabilities["encodings"] = ENCODINGS if self.quality>0: capabilities["jpeg"] = self.quality capabilities["quality"] = self.quality capabilities["encoding.quality"] = self.quality if self.min_quality>0: capabilities["encoding.min-quality"] = self.min_quality if self.speed>=0: capabilities["speed"] = self.speed capabilities["encoding.speed"] = self.speed if self.min_speed>=0: capabilities["encoding.min-speed"] = self.min_speed capabilities["platform"] = sys.platform capabilities["client_type"] = "Python/Gobject" capabilities["raw_packets"] = True capabilities["chunked_compression"] = True capabilities["rencode"] = has_rencode capabilities["server-window-resize"] = True capabilities["hostname"] = socket.gethostname() capabilities["uuid"] = self.uuid capabilities["randr_notify"] = False #only client.py cares about this capabilities["windows"] = False #only client.py cares about this return capabilities def make_uuid(self): try: import hashlib u = hashlib.sha1() except: #try python2.4 variant: import sha u = sha.new() def uupdate(ustr): u.update(ustr.encode("utf-8")) uupdate(get_machine_id()) if os.name=="posix": uupdate(u"/") uupdate(str(os.getuid())) uupdate(u"/") uupdate(str(os.getgid())) self.uuid = u.hexdigest() def send(self, *parts): self._ordinary_packets.append(parts) self.have_more() def send_now(self, *parts): self._priority_packets.append(parts) self.have_more() def send_positional(self, packet): self._ordinary_packets.append(packet) self._mouse_position = None self.have_more() def send_mouse_position(self, packet): self._mouse_position = packet self.have_more() def have_more(self): #this function is overridden in ready() p = self._protocol if p and p.source: p.source_has_more() def next_packet(self): if self._priority_packets: packet = self._priority_packets.pop(0) elif self._ordinary_packets: packet = self._ordinary_packets.pop(0) elif self._mouse_position is not None: packet = self._mouse_position self._mouse_position = None else: packet = None has_more = packet is not None and \ (bool(self._priority_packets) or bool(self._ordinary_packets) \ or self._mouse_position is not None) return packet, None, None, has_more def cleanup(self): if self._protocol: self._protocol.close() self._protocol = None def run(self): raise Exception("override me!") def quit(self, exit_code=0): if self.exit_code is None: self.exit_code = exit_code raise Exception("override me!") def warn_and_quit(self, exit_code, warning): log.warn(warning) self.quit(exit_code) def _process_disconnect(self, packet): if len(packet)==2: info = packet[1] else: info = packet[1:] self.warn_and_quit(EXIT_OK, "server requested disconnect: %s" % info) def _process_connection_lost(self, packet): self.warn_and_quit(EXIT_CONNECTION_LOST, "Connection lost") def _process_challenge(self, packet): if not self.password_file and not self.password: self.warn_and_quit(EXIT_PASSWORD_REQUIRED, "password is required by the server") return if not self.password: self.load_password() assert self.password salt = packet[1] if self.encryption: assert len(packet)>=3, "challenge does not contain encryption details to use for the response" server_cipher = packet[2] self.set_server_encryption(server_cipher) import hmac challenge_response = hmac.HMAC(self.password, salt) password_hash = challenge_response.hexdigest() self.password_sent = True self.send_hello(password_hash) def set_server_encryption(self, props): cipher = props.get("cipher") cipher_iv = props.get("cipher.iv") key_salt = props.get("cipher.key_salt") iterations = props.get("cipher.key_stretch_iterations") if not cipher or not cipher_iv: self.warn_and_quit(EXIT_ENCRYPTION, "the server does not use or support encryption/password, cannot continue with %s cipher" % self.encryption) return False if cipher not in ENCRYPTION_CIPHERS: self.warn_and_quit(EXIT_ENCRYPTION, "unsupported server cipher: %s, allowed ciphers: %s" % (cipher, ", ".join(ENCRYPTION_CIPHERS))) return False self._protocol.set_cipher_out(cipher, cipher_iv, self.get_password(), key_salt, iterations) def get_password(self): if self.password is None: self.load_password() return self.password def load_password(self): try: passwordFile = open(self.password_file, "rU") self.password = passwordFile.read() passwordFile.close() while self.password.endswith("\n") or self.password.endswith("\r"): self.password = self.password[:-1] except IOError, e: self.warn_and_quit(EXIT_PASSWORD_FILE_ERROR, "failed to open password file %s: %s" % (self.password_file, e)) log("password read from file %s is %s", self.password_file, self.password)