Esempio n. 1
0
    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))
Esempio n. 2
0
    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))
Esempio n. 3
0
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
Esempio n. 4
0
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
Esempio n. 5
0
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)
Esempio n. 6
0
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)
Esempio n. 7
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))
Esempio n. 8
0
    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()
Esempio n. 9
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))
Esempio n. 10
0
    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()