def __init__(self, sasl_client_factory, mechanism, trans): """ @param sasl_client_factory: a callable that returns a new sasl.Client object @param mechanism: the SASL mechanism (e.g. "GSSAPI") @param trans: the underlying transport over which to communicate. """ self._trans = trans self.sasl_client_factory = sasl_client_factory self.sasl = None self.mechanism = mechanism self.__wbuf = StringIO() self.__rbuf = StringIO() self.opened = False self.encode = None
def cstringio_refill(self, prefix, reqlen): # self.__rbuf will already be empty here because fastbinary doesn't # ask for a refill until the previous buffer is empty. Therefore, # we can start reading new frames immediately. while len(prefix) < reqlen: self._read_frame() prefix += self.__rbuf.getvalue() self.__rbuf = StringIO(prefix) return self.__rbuf
def _read_frame(self): header = read_all_compat(self._trans, 4) (length,) = struct.unpack(">I", header) if self.encode: # If the frames are encoded (i.e. you're using a QOP of auth-int or # auth-conf), then make sure to include the header in the bytes you send to # sasl.decode() encoded = header + read_all_compat(self._trans, length) success, decoded = self.sasl.decode(encoded) if not success: raise TTransportException(type=TTransportException.UNKNOWN, message=self.sasl.getError()) else: # If the frames are not encoded, just pass it through decoded = read_all_compat(self._trans, length) self.__rbuf = StringIO(decoded)
def flush(self): buffer = self.__wbuf.getvalue() # The first time we flush data, we send it to sasl.encode() # If the length doesn't change, then we must be using a QOP # of auth and we should no longer call sasl.encode(), otherwise # we encode every time. if self.encode == None: success, encoded = self.sasl.encode(buffer) if not success: raise TTransportException(type=TTransportException.UNKNOWN, message=self.sasl.getError()) if (len(encoded)==len(buffer)): self.encode = False self._flushPlain(buffer) else: self.encode = True self._trans.write(encoded) elif self.encode: self._flushEncoded(buffer) else: self._flushPlain(buffer) self._trans.flush() self.__wbuf = StringIO()