Python to VB.NET

Having a bit of a problem converting some python to vb.net.  One other person requested a single function be converted from the same python program but I actually have that one converted.  It's the support functions and main program I am having difficulty with.

Basically, the python program encrypts a packet to send to a server.  It receives a packet back with the same encryption and is decrypted and displayed.

My problem I believe is the actual encryption of the packet.  What I do understand of python tells me that it's using little endian int32's...  which I think is what vb.net uses if I just use bitconverter.getbytes()...  But for some reason I just can't get the server to talk to me (it won't throw errors at all, and only tosses a blank string or null if your packet is malformed).

I don't think I need any network code...  just something to actually create a packet (array of bytes I would imagine).


The following is the packet format from the docs, what little of them there are...

Packet format
int32 32-bit unsigned integer
1 byte bits 7..0 of value
1 byte bits 15..8 of value
1 byte bits 23..16 of value
1 byte bits 31..24 of value

Word
int32 Size Number of bytes in word, excluding trailing null
byte char[] Content Word contents -- must not contain any null bytes char
Terminator Trailing null byte

Packet
int32 Sequence Bit 31: 0 = The command in this command/response pair originated on the server 1 = The command in this command/response pair originated on the client
Bit 30: 0 = Request, 1 = Response
Bits 29..0: Sequence number (this is used to match requests/responses in a full duplex transmission)
int32 Size Total size of packet, in bytes
int32 NumWords Number of words following the packet header
Word[N] Words N words

A packet cannot be more than 4096 bytes in size.



Any help would be greatly appreciated...  I wouldn't even need the python code converted if I could just get something that can create said packet.   :)

Thanks much.
#!/usr/local/bin/python
from struct import *
import binascii
import socket
import sys
import shlex
import string
import threading
import md5
import os


def EncodeHeader(isFromServer, isResponse, sequence):
	header = sequence & 0x3fffffff
	if isFromServer:
		header += 0x80000000
	if isResponse:
		header += 0x40000000
	return pack('<I', header)

def DecodeHeader(data):
	[header] = unpack('<I', data[0 : 4])
	return [header & 0x80000000, header & 0x40000000, header & 0x3fffffff]

def EncodeInt32(size):
	return pack('<I', size)

def DecodeInt32(data):
	return unpack('<I', data[0 : 4])[0]
	
	
def EncodeWords(words):
	size = 0
	encodedWords = ''
	for word in words:
		strWord = str(word)
		encodedWords += EncodeInt32(len(strWord))
		encodedWords += strWord
		encodedWords += '\x00'
		size += len(strWord) + 5
	
	return size, encodedWords
	
def DecodeWords(size, data):
	numWords = DecodeInt32(data[0:])
	words = []
	offset = 0
	while offset < size:
		wordLen = DecodeInt32(data[offset : offset + 4])		
		word = data[offset + 4 : offset + 4 + wordLen]
		words.append(word)
		offset += wordLen + 5

	return words

def EncodePacket(isFromServer, isResponse, sequence, words):
	encodedHeader = EncodeHeader(isFromServer, isResponse, sequence)
	encodedNumWords = EncodeInt32(len(words))
	[wordsSize, encodedWords] = EncodeWords(words)
	encodedSize = EncodeInt32(wordsSize + 12)
	return encodedHeader + encodedSize + encodedNumWords + encodedWords

# Decode a request or response packet
# Return format is:
# [isFromServer, isResponse, sequence, words]
# where
#	isFromServer = the command in this command/response packet pair originated on the server
#   isResponse = True if this is a response, False otherwise
#   sequence = sequence number
#   words = list of words
	
def DecodePacket(data):
	[isFromServer, isResponse, sequence] = DecodeHeader(data)
	wordsSize = DecodeInt32(data[4:8]) - 12
	words = DecodeWords(wordsSize, data[12:])
	return [isFromServer, isResponse, sequence, words]

###############################################################################

clientSequenceNr = 0

# Encode a request packet

def EncodeClientRequest(words):
	global clientSequenceNr
	packet = EncodePacket(False, False, clientSequenceNr, words)
	clientSequenceNr = (clientSequenceNr + 1) & 0x3fffffff
	return packet

# Encode a response packet
	
def EncodeClientResponse(sequence, words):
	return EncodePacket(False, True, sequence, words)

###################################################################################

# Display contents of packet in user-friendly format, useful for debugging purposes
	
def printPacket(packet):

	if (packet[0]):
		print "IsFromServer, ",
	else:
		print "IsFromClient, ",
	
	if (packet[1]):
		print "Response, ",
	else:
		print "Request, ",

	print "Sequence: " + str(packet[2]),

	if packet[3]:
		print " Words:",
		for word in packet[3]:
			print "\"" + word + "\"",

	print ""

###################################################################################

def generatePasswordHash(salt, password):
	m = md5.new()
	m.update(salt)
	m.update(password)
	return m.digest()


###################################################################################
# Example program

if __name__ == '__main__':
	from getopt import getopt
	import sys

	global running

	print "Remote administration console for BFBC2"
#	history_file = os.path.join( os.environ["HOME"], ".bfbc2_rcon_history" )

	host = raw_input('Enter game server host IP/name: ')
	port = int(raw_input('Enter host port: '))
	pw = raw_input('Enter password: ')

	serverSocket = None
	running = True

	opts, args = getopt(sys.argv[1:], 'h:p:a:')
	for k, v in opts:
		if k == '-h':
			host = v
		elif k == '-p':
			port = int(v)
		elif k == '-a':
			pw = v

	try:
		try:
			serverSocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

			print 'Connecting to port: %s:%d...' % ( host, port )
			serverSocket.connect( ( host, port ) )
			serverSocket.setblocking(1)

			if pw is not None:
				print 'Logging in - 1: retrieving salt...'

				# Retrieve this connection's 'salt' (magic value used when encoding password) from server
				getPasswordSaltRequest = EncodeClientRequest( [ "login.hashed" ] )
				serverSocket.send(getPasswordSaltRequest)

				getPasswordSaltResponse = serverSocket.recv(4096)
				printPacket(DecodePacket(getPasswordSaltResponse))

				[isFromServer, isResponse, sequence, words] = DecodePacket(getPasswordSaltResponse)

				# if the server doesn't understand "login.hashed" command, abort
				if words[0] != "OK":
					sys.exit(0);

				print 'Received salt: ' + words[1]

				# Given the salt and the password, combine them and compute hash value
				salt = words[1].decode("hex")
				passwordHash = generatePasswordHash(salt, pw)
				passwordHashHexString = string.upper(passwordHash.encode("hex"))

				print 'Computed password hash: ' + passwordHashHexString
				
				# Send password hash to server
				print 'Logging in - 2: sending hash...'

				loginRequest = EncodeClientRequest( [ "login.hashed", passwordHashHexString ] )
				serverSocket.send(loginRequest)

				loginResponse = serverSocket.recv(4096)	
				printPacket(DecodePacket(loginResponse))

				[isFromServer, isResponse, sequence, words] = DecodePacket(loginResponse)

				# if the server didn't like our password, abort
				if words[0] != "OK":
					sys.exit(0);

			while running:
				command = raw_input( "> " )
				words = shlex.split(command)

				if len(words) >= 1:

					if "quit" == words[0]:
						running = False

					# Send request to server on command channel
					request = EncodeClientRequest(words)
					serverSocket.send(request)

					# Wait for response from server
					packet = serverSocket.recv(4096)	

					[isFromServer, isResponse, sequence, words] = DecodePacket(packet)

					# The packet from the server should 
					# For now, we always respond with an "OK"
					if not isResponse:
						print 'Received an unexpected request packet from server, ignored:'

					printPacket(DecodePacket(packet))
					

		except socket.error, detail:
			print 'Network error:', detail[1]

		except EOFError, KeyboardInterrupt:
			pass

		except:
			raise

	finally:
		try:
			if serverSocket is not None:
				serverSocket.close()

			print "Done"
		except:
			raise

	sys.exit( 0 )

Open in new window

LiberationSoftAsked:
Who is Participating?

[Webinar] Streamline your web hosting managementRegister Today

x
 
Jorge PaulinoConnect With a Mentor IT Pro/DeveloperCommented:
That's not a easy job and also not the propose of this page (like others on web).
If you use VS2010 you can take a look into dynamic support and use python on VB.NET (Ironpython). That way you can maybe use that code (maybe!).
It's better to create a new topic asking what you want to do and someone could provide you a solution, not a complete conversion.
0
 
LiberationSoftAuthor Commented:
Anybody?  I'm attempting to muddle my way through the python but this is literally the first time I've looked at python...  and it's kickin my butt.   :)
0
 
LiberationSoftAuthor Commented:
Thanks.  I've managed, I think, to muddle my way through it.  I'll know when I send my first packet and get a valid response.   Or not.   :)
0
 
LiberationSoftAuthor Commented:
Not what I was hoping for but...  It'll do.
0
All Courses

From novice to tech pro — start learning today.