def check(self, tls, targetKeyID, serverName): """Check whether the certificate chain on the TLS connection 'tls' is valid, current, and matches the keyID 'targetKeyID'. If so, return. If not, raise MixProtocolBadAuth. Display all messages using the server 'serverName'. """ # First, make sure the certificate is neither premature nor expired. try: tls.check_cert_alive() except _ml.TLSError, e: s = str(e) skewed = 0 notBefore, notAfter = tls.get_cert_lifetime() # XXXX 'stringContains' is not the best possible check here... if stringContains(s, "expired"): s += " [expired at %s]" % notAfter skewed = 1 elif stringContains(s, "not yet valid"): s += " [not valid until %s]" % notBefore skewed = 1 if skewed: s += " (One of you may have a skewed clock or wrong time zone)" raise MixProtocolBadAuth("Invalid certificate from %s: %s " % (serverName, s))
def check(self, tls, targetKeyID, serverName): """Check whether the certificate chain on the TLS connection 'tls' is valid, current, and matches the keyID 'targetKeyID'. If so, return. If not, raise MixProtocolBadAuth. Display all messages using the server 'serverName'. """ # First, make sure the certificate is neither premature nor expired. try: tls.check_cert_alive() except _ml.TLSError, e: s = str(e) skewed=0 notBefore,notAfter = tls.get_cert_lifetime() # XXXX 'stringContains' is not the best possible check here... if stringContains(s, "expired"): s += " [expired at %s]"%notAfter skewed = 1 elif stringContains(s,"not yet valid"): s += " [not valid until %s]"%notBefore skewed = 1 if skewed: s +=" (One of you may have a skewed clock or wrong time zone)" raise MixProtocolBadAuth("Invalid certificate from %s: %s " % ( serverName, s))
def _parseIntervalList(s): """Validation functions. Parse a list of comma-separated intervals in the form ((every)? INTERVAL for INTERVAL)|INTERVAL into a list of interval lengths in seconds.""" items = s.strip().lower().split(",") ilist = [] for item in items: item = item.strip() if stringContains(item, " for "): if item.startswith("every "): item = item[6:] interval, duration = item.split(" for ", 1) interval = int(_parseInterval(interval)) duration = int(_parseInterval(duration)) if interval < 1: raise ConfigError("Repeated interval too small in %s" % s) ilist += [interval] * ceilDiv(duration, interval) elif item.startswith("every "): raise ConfigError( "Bad syntax on interval %s. (Did you mean %s for X days?)", item, item) else: interval = int(_parseInterval(item)) ilist.append(interval) return ilist
def _parseIntervalList(s): """Validation functions. Parse a list of comma-separated intervals in the form ((every)? INTERVAL for INTERVAL)|INTERVAL into a list of interval lengths in seconds.""" items = s.strip().lower().split(",") ilist = [] for item in items: item = item.strip() if stringContains(item, " for "): if item.startswith("every "): item = item[6:] interval, duration = item.split(" for ", 1) interval = int(_parseInterval(interval)) duration = int(_parseInterval(duration)) if interval < 1: raise ConfigError("Repeated interval too small in %s"%s) ilist += [interval] * ceilDiv(duration, interval) elif item.startswith("every "): raise ConfigError( "Bad syntax on interval %s. (Did you mean %s for X days?)", item, item) else: interval = int(_parseInterval(item)) ilist.append(interval) return ilist
def _readServer(contents): """Read a ServerInfo from the string 'contents', which is either a server descriptor or the name of a file holding a descriptor. Raise MixError on failure.""" if stringContains(contents, "[Server]"): pass else: contents = readPossiblyGzippedFile(contents) # May raise ConfigError, MixError return contents, ServerInfo(string=contents, assumeValid=0)
def clean(self): for fn in os.listdir(self._loc): if len(fn) > self.KEY_LENGTH and stringContains(fn, ".tmp"): os.unlink(os.path.join(self._loc,fn))
def process(self, r, w, x, maxBytes=None): """Given that we've received read/write events as indicated in r/w, advance the state of the connection as much as possible, but try to use no more than 'maxBytes' bytes of bandwidth. Return is as in 'getStatus', with an extra 'bandwidth used' field appended.""" if x and (self.sock is not None): self.__close(gotClose=1) return 0, 0, 0, 0 if not (r or w): return self.wantRead, self.wantWrite, (self.sock is not None), 0 bytesAtStart = bytesNow = self.tls.get_num_bytes_raw() if maxBytes is None: bytesCutoff = sys.maxint maxBytes = sys.maxint - bytesNow else: bytesCutoff = bytesNow + maxBytes try: self.lastActivity = time.time() while bytesNow < bytesCutoff and self.__stateFn(r, w, maxBytes): # If __stateFn returns 1, then the state has changed, and # we should try __stateFn again. if self.tls is not None: bytesNow = self.tls.get_num_bytes_raw() maxBytes = bytesCutoff - bytesNow except _ml.TLSWantRead: self.wantRead = 1 self.wantWrite = 0 except _ml.TLSWantWrite: self.wantRead = 0 if self.__stateFn == self.__connectFn: self.wantWrite = 2 else: self.wantWrite = 1 except _Closing: # state functions that want to close the connection should # raise '_Closing', so we can count the bytes used before we # call 'close'. if self.tls is not None: bytesNow = self.tls.get_num_bytes_raw() self.__close() except _ml.TLSClosed: # We get this error if the socket unexpectedly closes underneath # the TLS connection. self.__close(gotClose=1) except _ml.TLSError, e: if self.tls is not None: bytesNow = self.tls.get_num_bytes_raw() if not (self.__awaitingShutdown or self.__stateFn == self.__shutdownFn): e = str(e) if stringContains(e, 'wrong version number'): e = 'wrong version number (or failed handshake)' LOG.warn("Unexpected TLS error: %s. Closing connection to %s", e, self.address) self.onTLSError() self.startShutdown() else: LOG.warn("Error while shutting down: closing connection to %s", self.address) self.onTLSError() self.__close()
def clean(self): for fn in os.listdir(self._loc): if len(fn) > self.KEY_LENGTH and stringContains(fn, ".tmp"): os.unlink(os.path.join(self._loc, fn))
def process(self, r, w, x, maxBytes=None): """Given that we've received read/write events as indicated in r/w, advance the state of the connection as much as possible, but try to use no more than 'maxBytes' bytes of bandwidth. Return is as in 'getStatus', with an extra 'bandwidth used' field appended.""" if x and (self.sock is not None): self.__close(gotClose=1) return 0,0,0,0 if not (r or w): return self.wantRead, self.wantWrite, (self.sock is not None),0 bytesAtStart = bytesNow = self.tls.get_num_bytes_raw() if maxBytes is None: bytesCutoff = sys.maxint maxBytes = sys.maxint-bytesNow else: bytesCutoff = bytesNow+maxBytes try: self.lastActivity = time.time() while bytesNow < bytesCutoff and self.__stateFn(r, w, maxBytes): # If __stateFn returns 1, then the state has changed, and # we should try __stateFn again. if self.tls is not None: bytesNow = self.tls.get_num_bytes_raw() maxBytes = bytesCutoff-bytesNow except _ml.TLSWantRead: self.wantRead = 1 self.wantWrite = 0 except _ml.TLSWantWrite: self.wantRead = 0 if self.__stateFn == self.__connectFn: self.wantWrite = 2 else: self.wantWrite = 1 except _Closing: # state functions that want to close the connection should # raise '_Closing', so we can count the bytes used before we # call 'close'. if self.tls is not None: bytesNow = self.tls.get_num_bytes_raw() self.__close() except _ml.TLSClosed: # We get this error if the socket unexpectedly closes underneath # the TLS connection. self.__close(gotClose=1) except _ml.TLSError, e: if self.tls is not None: bytesNow = self.tls.get_num_bytes_raw() if not (self.__awaitingShutdown or self.__stateFn == self.__shutdownFn): e = str(e) if stringContains(e, 'wrong version number'): e = 'wrong version number (or failed handshake)' LOG.warn("Unexpected TLS error: %s. Closing connection to %s", e, self.address) self.onTLSError() self.startShutdown() else: LOG.warn("Error while shutting down: closing connection to %s", self.address) self.onTLSError() self.__close()