def build_request(self, authtoken=None, contcred=None, streamid=None, requestid=None, reserved=None, credtype=None, dlen=None, cred=None): """Return a packed kXR_auth request.""" if not authtoken and not contcred: print "[!] Can't build kXR_auth request: no auth token or continuation \ credentials supplied" sys.exit(1) credname, credentials, credlen = \ self.getcredentials(authtoken, contcred, self.context['socket'].fileno()) request_struct = getMessageStruct( 'ClientRequestHdr') + getMessageStruct('ClientAuthRequest') params = \ {'streamid' : streamid if streamid else self.context['streamid'], 'requestid' : requestid if requestid else XProtocol.XRequestTypes.kXR_auth, 'reserved' : reserved if reserved else 12 * '\0', 'credtype' : credtype if credtype else credname.ljust(4, '\0'), 'dlen' : dlen if dlen else credlen, 'cred' : cred if cred else credentials} return self.mh.build_message(request_struct, params)
def kXR_open(self, streamid=None, status=None, dlen=None, fhandle=None, cpsize=None , cptype=None, data=None): """Return a packed representation of a kXR_open response.""" responseStruct = getMessageStruct('ServerResponseHeader') + \ getMessageStruct('ServerResponseBody_Open') params = { 'streamid': streamid if streamid else 0, 'status': status if status else getResponseId('kXR_ok'), 'dlen': 0, 'fhandle': fhandle if fhandle else (4 * '\0') } toBeRemoved = [] if cpsize != None: params['cpsize'] = cpsize else: toBeRemoved.append('cpsize') if cptype != None: params['cptype'] = cptype else: toBeRemoved.append('cptype') if data != None: params['data'] = data self.mh.setFieldAttribute( responseStruct, 'data', 'size', len( data ) ) else: toBeRemoved.append('data') responseStruct = self.mh.removeFields( responseStruct, toBeRemoved ) msg = self.mh.buildMessageFormat( responseStruct, params ) msg[1][2] = msg[2] - 8 return self.mh.pack( msg[0], msg[1] )
def kXR_login(self, streamid=None, status=None, dlen=None, sessid=None, sec=None, verifyAuth=False): """Return a packed representation of a kXR_login response. Pass verify_auth=True to enable authentication.""" responseStruct = getMessageStruct('ServerResponseHeader') + \ getMessageStruct('ServerResponseBody_Login') # Check if client needs to authenticate if verifyAuth and not sec: auth = AuthHelper.AuthHelper(self.context) sec = auth.getsectoken() params = { 'streamid': streamid if streamid else 0, 'status' : status if status else getResponseId('kXR_ok'), 'dlen' : dlen if dlen else 0, 'sessid' : sessid if sessid else genSessId() } toBeRemoved = [] if sec != None: params['sec'] = sec self.mh.setFieldAttribute( responseStruct, 'sec', 'size', len( sec ) ) else: responseStruct = self.mh.removeFields( responseStruct, ['sec'] ) msg = self.mh.buildMessageFormat( responseStruct, params ) msg[1][2] = msg[2] - 8 return self.mh.pack( msg[0], msg[1] )
def kXR_waitresp(self, streamid=None, status=None, dlen=None, seconds=None): """Return a packed representation of a kXR_waitresp response.""" responseStruct = getMessageStruct('ServerResponseHeader') + \ getMessageStruct('ServerResponseBody_Waitresp') params = { 'streamid': streamid if streamid else 0, 'status' : status if status else getResponseId('kXR_waitresp'), 'dlen' : dlen if dlen else 4, 'seconds' : seconds if seconds else 0} return self.mh.buildMessage(responseStruct, params)
def kXR_bind( self, streamid=None, status=None, dlen=None, pathid=None ): """Return a packed representation of a kXR_bind response.""" responseStruct = getMessageStruct('ServerResponseHeader') + \ getMessageStruct('ServerResponseBody_Bind') params = { 'streamid': streamid if streamid else 0, 'status' : status if status else getResponseId('kXR_ok'), 'dlen' : dlen if dlen else 1, 'pathid' : pathid if pathid else '\0'} return self.mh.buildMessage(responseStruct, params)
def kXR_attn_asyncwt(self, streamid=None, status=None, dlen=None, actnum=None, wsec=None): """Return a packed representation of a kXR_attn_asyncwt response.""" responseStruct = getMessageStruct('ServerResponseHeader') + \ getMessageStruct('ServerResponseBody_Attn_asyncwt') params = { 'streamid': streamid if streamid else 0, 'status' : status if status else getResponseId('kXR_attn'), 'dlen' : dlen if dlen else 8, 'actnum' : actnum if actnum else get_attncode('kXR_asyncwt'), 'wsec' : wsec if wsec else 0} return self.mh.buildMessage(responseStruct, params)
def handshake( self, streamid=None, status=None, dlen=None, pval=None, flag=None ): """Return a packed representation of a server handshake response.""" responseStruct = getMessageStruct('ServerResponseHeader') \ + getMessageStruct('ServerInitHandShake') params = { 'streamid': streamid if streamid else 0, 'status' : status if status else 0, 'dlen' : dlen if dlen else 8, 'pval' : pval if pval is not None else XProtocol.kXR_PROTOCOLVERSION, 'flag' : flag if flag is not None else XProtocol.kXR_DataServer } return self.mh.buildMessage(responseStruct, params)
def kXR_attn_asynresp(self, payloadLength): """Return a packed representation of a kXR_attn_asynresp response.""" responseStruct = getMessageStruct('ServerResponseHeader') + \ getMessageStruct('ServerResponseBody_Attn') + \ getMessageStruct('ServerResponseBody_Attn_asynresp') params = { 'streamid': 0, 'status' : getResponseId('kXR_attn'), 'dlen' : payloadLength + 8, 'actnum' : getAttnCode('kXR_asynresp'), 'reserved': 4 * '\0' } return self.mh.buildMessage(responseStruct, params)
def kXR_attn_asyncab(self, streamid=None, status=None, dlen=None, actnum=None, msg=None): """Return a packed representation of a kXR_attn_asyncab response.""" responseStruct = getMessageStruct('ServerResponseHeader') + \ getMessageStruct('ServerResponseBody_Attn') if not msg: msg = '' params = { 'streamid': streamid if streamid else 0, 'status' : status if status else getResponseId('kXR_attn'), 'dlen' : dlen if dlen else len(msg) + 4, 'actnum' : actnum if actnum else get_attncode('kXR_asyncab'), 'parms' : msg} return self.mh.buildMessage(responseStruct, params)
def kXR_protocol(self, streamid=None, status=None, dlen=None, pval=None, flags=None): """Return a packed representation of a kXR_protocol response.""" responseStruct = getMessageStruct('ServerResponseHeader') + \ getMessageStruct('ServerResponseBody_Protocol') params = { 'streamid': streamid if streamid else 0, 'status' : status if status else getResponseId('kXR_ok'), 'dlen' : dlen if dlen else 8, 'pval' : pval if pval else XProtocol.kXR_PROTOCOLVERSION, 'flags' : flags if flags else XProtocol.kXR_isServer} return self.mh.buildMessage(responseStruct, params)
def kXR_attn_asyncrd(self, streamid=None, status=None, dlen=None, actnum=None, port=None, host=None, token=None): """Return a packed representation of a kXR_attn_asyncrd response.""" responseStruct = getMessageStruct('ServerResponseHeader') + \ getMessageStruct('ServerResponseBody_Attn_asyncrd') if not host: host = '' else: host += (token if token else '') params = { 'streamid': streamid if streamid else 0, 'status' : status if status else getResponseId('kXR_attn'), 'dlen' : dlen if dlen else len(host), 'actnum' : actnum if actnum else get_attncode('kXR_asyncrd'), 'port' : port if port else 0, 'host' : host} return self.mh.buildMessage(responseStruct, params)
def kXR_error(self, streamid=None, status=None, dlen=None, errnum=None, errmsg=None): """Return a packed representation of a kXR_error response.""" responseStruct = getMessageStruct('ServerResponseHeader') + \ getMessageStruct('ServerResponseBody_Error') if not errmsg: errmsg = '' if not errnum: errnum = XProtocol.XErrorCode.kXR_ArgInvalid params = { 'streamid': streamid if streamid else 0, 'status' : status if status else getResponseId('kXR_error'), 'dlen' : dlen if dlen else len(errmsg + str(errnum)), 'errnum' : errnum, 'errmsg' : errmsg} self.mh.setFieldAttribute( responseStruct, 'errmsg', 'size', len(errmsg) ) return self.mh.buildMessage(responseStruct, params)
def kXR_wait(self, streamid=None, status=None, dlen=None, seconds=None, infomsg=None): """Return a packed representation of a kXR_wait response.""" responseStruct = getMessageStruct('ServerResponseHeader') + \ getMessageStruct('ServerResponseBody_Wait') if not infomsg: infomsg = '' params = { 'streamid': streamid if streamid else 0, 'status' : status if status else getResponseId('kXR_wait'), 'dlen' : dlen if dlen else len(infomsg) + 4, 'seconds' : seconds if seconds else 0, 'infomsg' : infomsg} self.mh.setFieldAttribute( responseStruct, 'infomsg', 'size', len( infomsg ) ) return self.mh.buildMessage(responseStruct, params)
def kXR_ok(self, streamid=None, status=None, dlen=None, data=None): """Return a packed representation of a kXR_ok response.""" responseStruct = getMessageStruct('ServerResponseHeader') + \ getMessageStruct('ServerResponseBody_Buffer') if not data: data = '' params = { 'streamid': streamid if streamid else 0, 'status' : status if status else getResponseId('kXR_ok'), 'dlen' : dlen if dlen else len(data), 'data' : data } self.mh.setFieldAttribute( responseStruct, 'data', 'size', len( data ) ) return self.mh.buildMessage(responseStruct, params)
def kXR_redirect(self, streamid=None, status=None, dlen=None, port=None, host=None, opaque=None, token=None): """Return a packed representation of a kXR_redirect response.""" responseStruct = getMessageStruct('ServerResponseHeader') + \ getMessageStruct('ServerResponseBody_Redirect') if not host: host = '' else: host += (opaque if opaque else '') + (token if token else '') params = { 'streamid': streamid if streamid else 0, 'status' : status if status else getResponseId('kXR_redirect'), 'dlen' : dlen if dlen else len(host) + 4, 'port' : port if port else 0, 'host' : host if host else r''} self.mh.setFieldAttribute( responseStruct, 'host', 'size', len(host) ) return self.mh.buildMessage(responseStruct, params)
def build_response(self, cred=None, streamid=None, status=None, dlen=None): """Return a packed kXR_auth response.""" if cred: self.auth(cred) response_struct = getMessageStruct('ServerResponseHeader') params = \ {'streamid' : streamid if streamid else 0, 'status' : status if status else XProtocol.XResponseType.kXR_ok, 'dlen' : dlen if dlen else 0} return self.mh.build_message(response_struct, params)
def build_request(self, authtoken=None, contcred=None, streamid=None, requestid=None, reserved=None, credtype=None, dlen=None, cred=None): """Return a packed kXR_auth request.""" if not authtoken and not contcred: print "[!] Can't build kXR_auth request: no auth token or continuation \ credentials supplied" sys.exit(1) credname, credentials, credlen = \ self.getcredentials(authtoken, contcred, self.context['socket'].fileno()) request_struct = getMessageStruct('ClientRequestHdr') + getMessageStruct('ClientAuthRequest') params = \ {'streamid' : streamid if streamid else self.context['streamid'], 'requestid' : requestid if requestid else XProtocol.XRequestTypes.kXR_auth, 'reserved' : reserved if reserved else 12 * '\0', 'credtype' : credtype if credtype else credname.ljust(4, '\0'), 'dlen' : dlen if dlen else credlen, 'cred' : cred if cred else credentials} return self.mh.build_message(request_struct, params)
def kXR_readv( self, streamid=None, status=None, dlen=None, data=None, chunks = None ): """ Return a packed representation of a kXR_readv response. chunks is a list of 4-tuples of the following format: (fhandle, length, offset, data) """ if chunks != None: headerFormat = self.mh.getMessageFormat( getMessageStruct( 'read_list' ) ) data = '' for chunk in chunks: data += self.mh.pack( headerFormat, (chunk[0], chunk[1], chunk[2]) ) data += chunk[3] return self.kXR_ok( streamid, status, dlen, data )
def unpackReadVRequest( self, request ): """Unpack the chunks received in the readv request""" data = request[-1] self.logger.debug( 'Unpacking %s worth of readv chunks' % (len(data)) ) if not len(data): return [] readFormat = self.getMessageFormat( getMessageStruct( 'read_list' ) ) readLength = struct.calcsize( readFormat ) chunksRaw = [data[x:x+readLength] for x in range(0, len(data), readLength)] chunkType = namedtuple( 'chunk_request', 'fhandle length offset' ) chunks = [] for chunk in chunksRaw: c = chunkType( *self.unpack( readFormat, chunk ) ) chunks.append( c ) self.logger.debug( 'Unpacked %d chunks: %s' % (len(chunksRaw), str(chunks)) ) return [('chunks', chunks)]
def unpackRequest( self, requestRaw ): """Return an unpacked named tuple representation of a client request.""" if len( requestRaw ) < 20: return None #--------------------------------------------------------------------------- # Figure out the request type and build the map of fields #--------------------------------------------------------------------------- requestId = self.unpack('>H', requestRaw[2:4])[0] self.logger.debug( 'Received request with id %d' % (requestId) ) if requestId == XProtocol.XRequestTypes.handshake: requestStruct = getMessageStruct('ClientInitHandShake') self.logger.debug( 'Mapped request type: handshake' ) else: requestType = XProtocol.XRequestTypes.reverseMapping[requestId] requestTypeName = requestType[4:].title() self.logger.debug( 'Mapped request type: %s %s' % (requestType, requestTypeName) ) requestStruct = getMessageStruct( 'ClientRequestHdr' ) requestStruct += getMessageStruct( 'Client' + requestTypeName + 'Request' ) if requestId == XProtocol.XRequestTypes.kXR_read: requestStruct += getMessageStruct( 'read_args' ) #--------------------------------------------------------------------------- # Build unpacking format string for this message #--------------------------------------------------------------------------- format = '>' for member in requestStruct: if member.has_key('size'): if member['size'] == 'dlen': format += str(len(requestRaw) - formatLength(format)) \ + member['type'] else: format += str(member['size']) + member['type'] else: format += member['type'] self.logger.debug( 'Unpack format is: %s' % (format) ) #--------------------------------------------------------------------------- # Convert the binary message to a named tupple #--------------------------------------------------------------------------- requestTuple = self.unpack(format, requestRaw) # Convert to named tuple requestStruct.insert( 0, {'name': 'type'} ) if requestId == XProtocol.XRequestTypes.handshake: type = 'handshake' else: type = getRequestId( requestId ) #--------------------------------------------------------------------------- extra = [] if requestId == XProtocol.XRequestTypes.kXR_readv: extra = self.unpackReadVRequest( requestTuple ) extraData = [] extraFields = [] for e in extra: extraData.append( e[1] ) extraFields.append( e[0] ) requestTuple += tuple( extraData ) extraFields = ' ' + ' '.join( extraFields ) request = namedtuple('request', ' '.join([m['name'] for m in requestStruct]) + extraFields) return request(type, *requestTuple)
def unpack_response(self, response_raw, request_raw): """Return an unpacked named tuple representation of a server response.""" if not len(response_raw): return '' # Unpack the request that generated this response for reference request = self.unpack_request(request_raw)[0] requestid = get_requestid(request.type) # Unpack the response header to find the status and data length header_struct = getMessageStruct('ServerResponseHeader') format = '>' for member in header_struct: format += member['type'] header = self.unpack(format + (str(len(response_raw) - 8) + 's'), response_raw) streamid = header[0] status = header[1] dlen = header[2] body = header[-1] # Check if this is a handshake response if requestid == XProtocol.XRequestTypes.handshake: body_struct = getMessageStruct('ServerInitHandShake') # Check if this is an asynchronous response elif status == XProtocol.XResponseType.kXR_attn: # Extract the attn code attncode = self.unpack('>H', body[:2])[0] body_struct = getMessageStruct('ServerResponseBody_Attn_' \ + get_attncode(attncode)[4:]) if not body_struct: body_struct = body_struct = getMessageStruct('ServerResponseBody_Attn') # Check if this is more than a simple kXR_ok response elif status != XProtocol.XResponseType.kXR_ok: body_struct = getMessageStruct('ServerResponseBody_' \ + get_responseid(status)[4:].title()) else: body_struct = getMessageStruct('ServerResponseBody_' \ + request.type[4:].title()) if not body_struct: body_struct = list() response_struct = header_struct + body_struct # The number of params in a kXR_open response depends on the options that # were passed in the request. if requestid == XProtocol.XRequestTypes.kXR_open: # Remove members from the response struct if the option was not given in # the request. response_struct[:] = [m for m in response_struct if self.option_included(m, request, response_raw)] # Build complete format string format = '>' for member in response_struct: if member.has_key('size'): if member['size'] == 'dlen': if member.has_key('offset'): format += str(dlen - member['offset']) + member['type'] else: format += str(dlen) + member['type'] else: format += str(member['size']) + member['type'] else: format += member['type'] if len(body_struct) == 0 and dlen > 0: format += (str(dlen) + 's') # Unpack to regular tuple response_tuple = self.unpack(format, response_raw) # Convert to named tuple response_struct.insert(0, {'name': 'type'}) type = get_responseid(status) response = namedtuple('response', ' '.join([m['name'] for m in response_struct])) return response(type, *response_tuple)