new file: pixi.toml
[GalaxyCodeBases.git] / etc / Windows / py-kms / server.py
blobc86fbac735fed7f958abb7f27f4490a2e2b461a3
1 import argparse
2 import binascii
3 import hashlib
4 import random
5 import re
6 import socket
7 import SocketServer
8 import struct
9 import uuid
10 import rpcBind, rpcRequest
12 from dcerpc import MSRPCHeader
13 from rpcBase import rpcBase
15 config = {}
17 def main():
18 parser = argparse.ArgumentParser()
19 parser.add_argument("ip", nargs="?", action="store", default="0.0.0.0", help="The IP address to listen on. The default is \"0.0.0.0\" (all interfaces).", type=str)
20 parser.add_argument("port", nargs="?", action="store", default=1688, help="The network port to listen on. The default is \"1688\".", type=int)
21 parser.add_argument("-e", "--epid", dest="epid", default=None, help="Use this flag to manually specify an ePID to use. If no ePID is specified, a random ePID will be generated.", type=str)
22 parser.add_argument("-l", "--lcid", dest="lcid", default=1033, help="Use this flag to manually specify an LCID for use with randomly generated ePIDs. If an ePID is manually specified, this setting is ignored.", type=int)
23 parser.add_argument("-c", "--client-count", dest="CurrentClientCount", default=26, help="Use this flag to specify the current client count. Default is 26. A number >25 is required to enable activation.", type=int)
24 parser.add_argument("-a", "--activation-interval", dest="VLActivationInterval", default=120, help="Use this flag to specify the activation interval (in minutes). Default is 120 minutes (2 hours).", type=int)
25 parser.add_argument("-r", "--renewal-interval", dest="VLRenewalInterval", default=1440 * 7, help="Use this flag to specify the renewal interval (in minutes). Default is 10080 minutes (7 days).", type=int)
26 parser.add_argument("-v", "--verbose", dest="verbose", action="store_const", const=True, default=False, help="Use this flag to enable verbose output.")
27 parser.add_argument("-d", "--debug", dest="debug", action="store_const", const=True, default=False, help="Use this flag to enable debug output. Implies \"-v\".")
28 parser.add_argument("-s", "--sqlite", dest="sqlite", action="store_const", const=True, default=False, help="Use this flag to store request information from unique clients in an SQLite database.")
29 parser.add_argument("-o", "--log", dest="log", action="store_const", const=True, default=False, help="Use this flag to enable logging to a file.")
30 parser.add_argument("-w", "--hwid", dest="hwid", action="store", default='364F463A8863D35F', help="Use this flag to specify a HWID. The HWID must be an 16-character string of hex characters. The default is \"364F463A8863D35F\".")
31 config.update(vars(parser.parse_args()))
32 # Sanitize HWID
33 try:
34 config['hwid'] = binascii.a2b_hex(re.sub(r'[^0-9a-fA-F]', '', config['hwid'].strip('0x')))
35 if len(binascii.b2a_hex(config['hwid'])) < 16:
36 print "Error: HWID \"%s\" is invalid. Hex string is too short." % binascii.b2a_hex(config['hwid'])
37 return
38 elif len(binascii.b2a_hex(config['hwid'])) > 16:
39 print "Error: HWID \"%s\" is invalid. Hex string is too long." % binascii.b2a_hex(config['hwid'])
40 return
41 except TypeError:
42 print "Error: HWID \"%s\" is invalid. Odd-length hex string." % binascii.b2a_hex(config['hwid'])
43 return
44 if config['debug']:
45 config['verbose'] = True
46 try:
47 import sqlite3
48 config['dbSupport'] = True
49 except:
50 print "Warning: Module \"sqlite3\" is not installed--database support disabled."
51 config['dbSupport'] = False
52 server = SocketServer.TCPServer((config['ip'], config['port']), kmsServer)
53 server.timeout = 5
54 print "TCP server listening at %s on port %d." % (config['ip'],config['port'])
55 server.serve_forever()
57 class kmsServer(SocketServer.BaseRequestHandler):
58 def setup(self):
59 self.connection = self.request
60 print "Connection accepted: %s:%d" % (self.client_address[0],self.client_address[1])
62 def handle(self):
63 while True:
64 # self.request is the TCP socket connected to the client
65 try:
66 self.data = self.connection.recv(1024)
67 except socket.error, e:
68 if e[0] == 104:
69 print "Error: Connection reset by peer."
70 break
71 else:
72 raise
73 if self.data == '' or not self.data:
74 print "No data received!"
75 break
76 # self.data = bytearray(self.data.strip())
77 # print binascii.b2a_hex(str(self.data))
78 packetType = MSRPCHeader(self.data)['type']
79 if packetType == rpcBase.packetType['bindReq']:
80 if config['verbose']:
81 print "RPC bind request received."
82 handler = rpcBind.handler(self.data, config)
83 elif packetType == rpcBase.packetType['request']:
84 if config['verbose']:
85 print "Received activation request."
86 handler = rpcRequest.handler(self.data, config)
87 else:
88 print "Error: Invalid RPC request type", packetType
89 break
91 handler.populate()
92 res = str(handler.getResponse())
93 self.connection.send(res)
95 if packetType == rpcBase.packetType['bindReq']:
96 if config['verbose']:
97 print "RPC bind acknowledged."
98 elif packetType == rpcBase.packetType['request']:
99 if config['verbose']:
100 print "Responded to activation request."
101 break
103 def finish(self):
104 self.connection.close()
105 print "Connection closed: %s:%d" % (self.client_address[0],self.client_address[1])
107 if __name__ == "__main__":
108 main()