modified: spffq.py
[GalaxyCodeBases.git] / etc / Windows / py-kms / kmsBase.py
bloba70995e3326d67f61befc4a4a436d07830cde0d9
1 import binascii
2 import datetime
3 import filetimes
4 import kmsPidGenerator
5 import os
6 import struct
7 import sys
8 import time
9 import uuid
11 from structure import Structure
13 # sqlite3 is optional
14 try:
15 import sqlite3
16 except:
17 pass
19 class UUID(Structure):
20 commonHdr = ()
21 structure = (
22 ('raw', '16s'),
25 def get(self):
26 return uuid.UUID(bytes_le=str(self))
28 class kmsBase:
29 class kmsRequestStruct(Structure):
30 commonHdr = ()
31 structure = (
32 ('versionMinor', '<H'),
33 ('versionMajor', '<H'),
34 ('isClientVm', '<I'),
35 ('licenseStatus', '<I'),
36 ('graceTime', '<I'),
37 ('applicationId', ':', UUID),
38 ('skuId', ':', UUID),
39 ('kmsCountedId' , ':', UUID),
40 ('clientMachineId', ':', UUID),
41 ('requiredClientCount', '<I'),
42 ('requestTime', '<Q'),
43 ('previousClientMachineId', ':', UUID),
44 ('machineName', 'u'),
45 ('_mnPad', '_-mnPad', '126-len(machineName)'),
46 ('mnPad', ':'),
49 def getMachineName(self):
50 return self['machineName'].decode('utf-16le')
52 def getLicenseStatus(self):
53 return kmsBase.licenseStates[self['licenseStatus']] or "Unknown"
55 class kmsResponseStruct(Structure):
56 commonHdr = ()
57 structure = (
58 ('versionMinor', '<H'),
59 ('versionMajor', '<H'),
60 ('epidLen', '<I=len(kmsEpid)+2'),
61 ('kmsEpid', 'u'),
62 ('clientMachineId', ':', UUID),
63 ('responseTime', '<Q'),
64 ('currentClientCount', '<I'),
65 ('vLActivationInterval', '<I'),
66 ('vLRenewalInterval', '<I'),
69 class GenericRequestHeader(Structure):
70 commonHdr = ()
71 structure = (
72 ('bodyLength1', '<I'),
73 ('bodyLength2', '<I'),
74 ('versionMinor', '<H'),
75 ('versionMajor', '<H'),
76 ('remainder', '_'),
79 appIds = {
80 uuid.UUID("55C92734-D682-4D71-983E-D6EC3F16059F") : "Windows",
81 uuid.UUID("59A52881-A989-479D-AF46-F275C6370663") : "Office 14 (2010)",
82 uuid.UUID("0FF1CE15-A989-479D-AF46-F275C6370663") : "Office 15 (2013)",
85 skuIds = {
86 uuid.UUID("ad2542d4-9154-4c6d-8a44-30f11ee96989") : "Windows Server 2008 Standard",
87 uuid.UUID("2401e3d0-c50a-4b58-87b2-7e794b7d2607") : "Windows Server 2008 StandardV",
88 uuid.UUID("68b6e220-cf09-466b-92d3-45cd964b9509") : "Windows Server 2008 Datacenter",
89 uuid.UUID("fd09ef77-5647-4eff-809c-af2b64659a45") : "Windows Server 2008 DatacenterV",
90 uuid.UUID("c1af4d90-d1bc-44ca-85d4-003ba33db3b9") : "Windows Server 2008 Enterprise",
91 uuid.UUID("8198490a-add0-47b2-b3ba-316b12d647b4") : "Windows Server 2008 EnterpriseV",
92 uuid.UUID("ddfa9f7c-f09e-40b9-8c1a-be877a9a7f4b") : "Windows Server 2008 Web",
93 uuid.UUID("7afb1156-2c1d-40fc-b260-aab7442b62fe") : "Windows Server 2008 ComputerCluster",
94 uuid.UUID("68531fb9-5511-4989-97be-d11a0f55633f") : "Windows Server 2008 R2 Standard",
95 uuid.UUID("7482e61b-c589-4b7f-8ecc-46d455ac3b87") : "Windows Server 2008 R2 Datacenter",
96 uuid.UUID("620e2b3d-09e7-42fd-802a-17a13652fe7a") : "Windows Server 2008 R2 Enterprise",
97 uuid.UUID("a78b8bd9-8017-4df5-b86a-09f756affa7c") : "Windows Server 2008 R2 Web",
98 uuid.UUID("cda18cf3-c196-46ad-b289-60c072869994") : "Windows Server 2008 R2 ComputerCluster",
99 uuid.UUID("d3643d60-0c42-412d-a7d6-52e6635327f6") : "Windows Server 2012 Datacenter",
100 uuid.UUID("f0f5ec41-0d55-4732-af02-440a44a3cf0f") : "Windows Server 2012 Standard",
101 uuid.UUID("95fd1c83-7df5-494a-be8b-1300e1c9d1cd") : "Windows Server 2012 MultiPoint Premium",
102 uuid.UUID("7d5486c7-e120-4771-b7f1-7b56c6d3170c") : "Windows Server 2012 MultiPoint Standard",
103 uuid.UUID("00091344-1ea4-4f37-b789-01750ba6988c") : "Windows Server 2012 R2 Datacenter",
104 uuid.UUID("b3ca044e-a358-4d68-9883-aaa2941aca99") : "Windows Server 2012 R2 Standard",
105 uuid.UUID("b743a2be-68d4-4dd3-af32-92425b7bb623") : "Windows Server 2012 R2 Cloud Storage",
106 uuid.UUID("21db6ba4-9a7b-4a14-9e29-64a60c59301d") : "Windows Server Essentials 2012 R2",
107 uuid.UUID("81671aaf-79d1-4eb1-b004-8cbbe173afea") : "Windows 8.1 Enterprise",
108 uuid.UUID("113e705c-fa49-48a4-beea-7dd879b46b14") : "Windows 8.1 EnterpriseN",
109 uuid.UUID("096ce63d-4fac-48a9-82a9-61ae9e800e5f") : "Windows 8.1 Professional WMC",
110 uuid.UUID("c06b6981-d7fd-4a35-b7b4-054742b7af67") : "Windows 8.1 Professional",
111 uuid.UUID("7476d79f-8e48-49b4-ab63-4d0b813a16e4") : "Windows 8.1 ProfessionalN",
112 uuid.UUID("fe1c3238-432a-43a1-8e25-97e7d1ef10f3") : "Windows 8.1 Core",
113 uuid.UUID("78558a64-dc19-43fe-a0d0-8075b2a370a3") : "Windows 8.1 CoreN",
114 uuid.UUID("a00018a3-f20f-4632-bf7c-8daa5351c914") : "Windows 8 Professional WMC",
115 uuid.UUID("a98bcd6d-5343-4603-8afe-5908e4611112") : "Windows 8 Professional",
116 uuid.UUID("ebf245c1-29a8-4daf-9cb1-38dfc608a8c8") : "Windows 8 ProfessionalN",
117 uuid.UUID("458e1bec-837a-45f6-b9d5-925ed5d299de") : "Windows 8 Enterprise",
118 uuid.UUID("e14997e7-800a-4cf7-ad10-de4b45b578db") : "Windows 8 EnterpriseN",
119 uuid.UUID("c04ed6bf-55c8-4b47-9f8e-5a1f31ceee60") : "Windows 8 Core",
120 uuid.UUID("197390a0-65f6-4a95-bdc4-55d58a3b0253") : "Windows 8 CoreN",
121 uuid.UUID("ae2ee509-1b34-41c0-acb7-6d4650168915") : "Windows 7 Enterprise",
122 uuid.UUID("1cb6d605-11b3-4e14-bb30-da91c8e3983a") : "Windows 7 EnterpriseN",
123 uuid.UUID("b92e9980-b9d5-4821-9c94-140f632f6312") : "Windows 7 Professional",
124 uuid.UUID("54a09a0d-d57b-4c10-8b69-a842d6590ad5") : "Windows 7 ProfessionalN",
125 uuid.UUID("cfd8ff08-c0d7-452b-9f60-ef5c70c32094") : "Windows Vista Enterprise",
126 uuid.UUID("d4f54950-26f2-4fb4-ba21-ffab16afcade") : "Windows Vista EnterpriseN",
127 uuid.UUID("4f3d1606-3fea-4c01-be3c-8d671c401e3b") : "Windows Vista Business",
128 uuid.UUID("2c682dc2-8b68-4f63-a165-ae291d4cf138") : "Windows Vista BusinessN",
129 uuid.UUID("aa6dd3aa-c2b4-40e2-a544-a6bbb3f5c395") : "Windows ThinPC",
130 uuid.UUID("db537896-376f-48ae-a492-53d0547773d0") : "Windows Embedded POSReady 7",
131 uuid.UUID("0ab82d54-47f4-4acb-818c-cc5bf0ecb649") : "Windows Embedded Industry 8.1",
132 uuid.UUID("cd4e2d9f-5059-4a50-a92d-05d5bb1267c7") : "Windows Embedded IndustryE 8.1",
133 uuid.UUID("f7e88590-dfc7-4c78-bccb-6f3865b99d1a") : "Windows Embedded IndustryA 8.1",
134 uuid.UUID("8ce7e872-188c-4b98-9d90-f8f90b7aad02") : "Office Access 2010",
135 uuid.UUID("cee5d470-6e3b-4fcc-8c2b-d17428568a9f") : "Office Excel 2010",
136 uuid.UUID("8947d0b8-c33b-43e1-8c56-9b674c052832") : "Office Groove 2010",
137 uuid.UUID("ca6b6639-4ad6-40ae-a575-14dee07f6430") : "Office InfoPath 2010",
138 uuid.UUID("09ed9640-f020-400a-acd8-d7d867dfd9c2") : "Office Mondo 2010",
139 uuid.UUID("ef3d4e49-a53d-4d81-a2b1-2ca6c2556b2c") : "Office Mondo 2010",
140 uuid.UUID("ab586f5c-5256-4632-962f-fefd8b49e6f4") : "Office OneNote 2010",
141 uuid.UUID("ecb7c192-73ab-4ded-acf4-2399b095d0cc") : "Office OutLook 2010",
142 uuid.UUID("45593b1d-dfb1-4e91-bbfb-2d5d0ce2227a") : "Office PowerPoint 2010",
143 uuid.UUID("df133ff7-bf14-4f95-afe3-7b48e7e331ef") : "Office Project Pro 2010",
144 uuid.UUID("5dc7bf61-5ec9-4996-9ccb-df806a2d0efe") : "Office Project Standard 2010",
145 uuid.UUID("b50c4f75-599b-43e8-8dcd-1081a7967241") : "Office Publisher 2010",
146 uuid.UUID("92236105-bb67-494f-94c7-7f7a607929bd") : "Office Visio Premium 2010",
147 uuid.UUID("e558389c-83c3-4b29-adfe-5e4d7f46c358") : "Office Visio Pro 2010",
148 uuid.UUID("9ed833ff-4f92-4f36-b370-8683a4f13275") : "Office Visio Standard 2010",
149 uuid.UUID("2d0882e7-a4e7-423b-8ccc-70d91e0158b1") : "Office Word 2010",
150 uuid.UUID("6f327760-8c5c-417c-9b61-836a98287e0c") : "Office Professional Plus 2010",
151 uuid.UUID("9da2a678-fb6b-4e67-ab84-60dd6a9c819a") : "Office Standard 2010",
152 uuid.UUID("ea509e87-07a1-4a45-9edc-eba5a39f36af") : "Office Small Business Basics 2010",
153 uuid.UUID("6ee7622c-18d8-4005-9fb7-92db644a279b") : "Office Access 2013",
154 uuid.UUID("f7461d52-7c2b-43b2-8744-ea958e0bd09a") : "Office Excel 2013",
155 uuid.UUID("a30b8040-d68a-423f-b0b5-9ce292ea5a8f") : "Office InfoPath 2013",
156 uuid.UUID("1b9f11e3-c85c-4e1b-bb29-879ad2c909e3") : "Office Lync 2013",
157 uuid.UUID("dc981c6b-fc8e-420f-aa43-f8f33e5c0923") : "Office Mondo 2013",
158 uuid.UUID("efe1f3e6-aea2-4144-a208-32aa872b6545") : "Office OneNote 2013",
159 uuid.UUID("771c3afa-50c5-443f-b151-ff2546d863a0") : "Office OutLook 2013",
160 uuid.UUID("8c762649-97d1-4953-ad27-b7e2c25b972e") : "Office PowerPoint 2013",
161 uuid.UUID("4a5d124a-e620-44ba-b6ff-658961b33b9a") : "Office Project Pro 2013",
162 uuid.UUID("427a28d1-d17c-4abf-b717-32c780ba6f07") : "Office Project Standard 2013",
163 uuid.UUID("00c79ff1-6850-443d-bf61-71cde0de305f") : "Office Publisher 2013",
164 uuid.UUID("b13afb38-cd79-4ae5-9f7f-eed058d750ca") : "Office Visio Standard 2013",
165 uuid.UUID("e13ac10e-75d0-4aff-a0cd-764982cf541c") : "Office Visio Pro 2013",
166 uuid.UUID("d9f5b1c6-5386-495a-88f9-9ad6b41ac9b3") : "Office Word 2013",
167 uuid.UUID("b322da9c-a2e2-4058-9e4e-f59a6970bd69") : "Office Professional Plus 2013",
168 uuid.UUID("b13afb38-cd79-4ae5-9f7f-eed058d750ca") : "Office Standard 2013",
171 licenseStates = {
172 0 : "Unlicensed",
173 1 : "Activated",
174 2 : "Grace Period",
175 3 : "Out-of-Tolerance Grace Period",
176 4 : "Non-Genuine Grace Period",
177 5 : "Notifications Mode",
178 6 : "Extended Grace Period",
181 licenseStatesEnum = {
182 'unlicensed' : 0,
183 'licensed' : 1,
184 'oobGrace' : 2,
185 'ootGrace' : 3,
186 'nonGenuineGrace' : 4,
187 'notification' : 5,
188 'extendedGrace' : 6
191 errorCodes = {
192 'SL_E_VL_NOT_WINDOWS_SLP' : 0xC004F035,
193 'SL_E_VL_NOT_ENOUGH_COUNT' : 0xC004F038,
194 'SL_E_VL_BINDING_SERVICE_NOT_ENABLED' : 0xC004F039,
195 'SL_E_VL_INFO_PRODUCT_USER_RIGHT' : 0x4004F040,
196 'SL_I_VL_OOB_NO_BINDING_SERVER_REGISTRATION' : 0x4004F041,
197 'SL_E_VL_KEY_MANAGEMENT_SERVICE_ID_MISMATCH' : 0xC004F042,
198 'SL_E_VL_MACHINE_NOT_BOUND' : 0xC004F056
201 def __init__(self, data, config):
202 self.data = data
203 self.config = config
205 def getConfig(self):
206 return self.config
208 def getOptions(self):
209 return self.config
211 def getData(self):
212 return self.data
214 def getResponse(self):
215 return ''
217 def getResponsePadding(self, bodyLength):
218 if bodyLength % 8 == 0:
219 paddingLength = 0
220 else:
221 paddingLength = 8 - bodyLength % 8
222 padding = bytearray(paddingLength)
223 return padding
225 def serverLogic(self, kmsRequest):
226 if self.config['sqlite'] and self.config['dbSupport']:
227 self.dbName = 'clients.db'
228 if not os.path.isfile(self.dbName):
229 # Initialize the database.
230 con = None
231 try:
232 con = sqlite3.connect(self.dbName)
233 cur = con.cursor()
234 cur.execute("CREATE TABLE clients(clientMachineId TEXT, machineName TEXT, applicationId TEXT, skuId TEXT, licenseStatus TEXT, lastRequestTime INTEGER, kmsEpid TEXT, requestCount INTEGER)")
236 except sqlite3.Error, e:
237 print "Error %s:" % e.args[0]
238 sys.exit(1)
240 finally:
241 if con:
242 con.commit()
243 con.close()
245 if self.config['debug']:
246 print "KMS Request Bytes:", binascii.b2a_hex(str(kmsRequest))
247 print "KMS Request:", kmsRequest.dump()
249 clientMachineId = kmsRequest['clientMachineId'].get()
250 applicationId = kmsRequest['applicationId'].get()
251 skuId = kmsRequest['skuId'].get()
252 requestDatetime = filetimes.filetime_to_dt(kmsRequest['requestTime'])
254 # Try and localize the request time, if pytz is available
255 try:
256 import timezones
257 from pytz import utc
258 local_dt = utc.localize(requestDatetime).astimezone(timezones.localtz())
259 except ImportError:
260 local_dt = requestDatetime
262 infoDict = {
263 "machineName" : kmsRequest.getMachineName(),
264 "clientMachineId" : str(clientMachineId),
265 "appId" : self.appIds.get(applicationId, str(applicationId)),
266 "skuId" : self.skuIds.get(skuId, str(skuId)),
267 "licenseStatus" : kmsRequest.getLicenseStatus(),
268 "requestTime" : int(time.time()),
269 "kmsEpid" : None
272 #print infoDict
274 if self.config['verbose']:
275 print " Machine Name: %s" % infoDict["machineName"]
276 print "Client Machine ID: %s" % infoDict["clientMachineId"]
277 print " Application ID: %s" % infoDict["appId"]
278 print " SKU ID: %s" % infoDict["skuId"]
279 print " Licence Status: %s" % infoDict["licenseStatus"]
280 print " Request Time: %s" % local_dt.strftime('%Y-%m-%d %H:%M:%S %Z (UTC%z)')
282 if self.config['sqlite'] and self.config['dbSupport']:
283 con = None
284 try:
285 con = sqlite3.connect(self.dbName)
286 cur = con.cursor()
287 cur.execute("SELECT * FROM clients WHERE clientMachineId=:clientMachineId;", infoDict)
288 try:
289 data = cur.fetchone()
290 if not data:
291 #print "Inserting row..."
292 cur.execute("INSERT INTO clients (clientMachineId, machineName, applicationId, skuId, licenseStatus, lastRequestTime, requestCount) VALUES (:clientMachineId, :machineName, :appId, :skuId, :licenseStatus, :requestTime, 1);", infoDict)
293 else:
294 #print "Data:", data
295 if data[1] != infoDict["machineName"]:
296 cur.execute("UPDATE clients SET machineName=:machineName WHERE clientMachineId=:clientMachineId;", infoDict)
297 if data[2] != infoDict["appId"]:
298 cur.execute("UPDATE clients SET applicationId=:appId WHERE clientMachineId=:clientMachineId;", infoDict)
299 if data[3] != infoDict["skuId"]:
300 cur.execute("UPDATE clients SET skuId=:skuId WHERE clientMachineId=:clientMachineId;", infoDict)
301 if data[4] != infoDict["licenseStatus"]:
302 cur.execute("UPDATE clients SET licenseStatus=:licenseStatus WHERE clientMachineId=:clientMachineId;", infoDict)
303 if data[5] != infoDict["requestTime"]:
304 cur.execute("UPDATE clients SET lastRequestTime=:requestTime WHERE clientMachineId=:clientMachineId;", infoDict)
305 # Increment requestCount
306 cur.execute("UPDATE clients SET requestCount=requestCount+1 WHERE clientMachineId=:clientMachineId;", infoDict)
308 except sqlite3.Error, e:
309 print "Error %s:" % e.args[0]
311 except sqlite3.Error, e:
312 print "Error %s:" % e.args[0]
313 sys.exit(1)
315 finally:
316 if con:
317 con.commit()
318 con.close()
320 return self.createKmsResponse(kmsRequest)
322 def createKmsResponse(self, kmsRequest):
323 response = self.kmsResponseStruct()
324 response['versionMinor'] = kmsRequest['versionMinor']
325 response['versionMajor'] = kmsRequest['versionMajor']
327 if not self.config["epid"]:
328 response["kmsEpid"] = kmsPidGenerator.epidGenerator(kmsRequest['applicationId'], kmsRequest['versionMajor'], self.config["lcid"]).encode('utf-16le')
329 else:
330 response["kmsEpid"] = self.config["epid"].encode('utf-16le')
331 response['clientMachineId'] = kmsRequest['clientMachineId']
332 response['responseTime'] = kmsRequest['requestTime']
333 response['currentClientCount'] = self.config["CurrentClientCount"]
334 response['vLActivationInterval'] = self.config["VLActivationInterval"]
335 response['vLRenewalInterval'] = self.config["VLRenewalInterval"]
337 if self.config['sqlite'] and self.config['dbSupport']:
338 con = None
339 try:
340 con = sqlite3.connect(self.dbName)
341 cur = con.cursor()
342 cur.execute("SELECT * FROM clients WHERE clientMachineId=?;", [str(kmsRequest['clientMachineId'].get())])
343 try:
344 data = cur.fetchone()
345 #print "Data:", data
346 if data[6]:
347 response["kmsEpid"] = data[6].encode('utf-16le')
348 else:
349 cur.execute("UPDATE clients SET kmsEpid=? WHERE clientMachineId=?;", (str(response["kmsEpid"].decode('utf-16le')), str(kmsRequest['clientMachineId'].get())))
351 except sqlite3.Error, e:
352 print "Error %s:" % e.args[0]
354 except sqlite3.Error, e:
355 print "Error %s:" % e.args[0]
356 sys.exit(1)
358 finally:
359 if con:
360 con.commit()
361 con.close()
363 if self.config['verbose']:
364 print " Server ePID: %s" % response["kmsEpid"].decode('utf-16le')
365 return response
367 import kmsRequestV4, kmsRequestV5, kmsRequestV6, kmsRequestUnknown
369 def generateKmsResponseData(data, config):
370 version = kmsBase.GenericRequestHeader(data)['versionMajor']
371 currentDate = datetime.datetime.now().ctime()
373 if version == 4:
374 print "Received V%d request on %s." % (version, currentDate)
375 messagehandler = kmsRequestV4.kmsRequestV4(data, config)
376 messagehandler.executeRequestLogic()
377 elif version == 5:
378 print "Received V%d request on %s." % (version, currentDate)
379 messagehandler = kmsRequestV5.kmsRequestV5(data, config)
380 messagehandler.executeRequestLogic()
381 elif version == 6:
382 print "Received V%d request on %s." % (version, currentDate)
383 messagehandler = kmsRequestV6.kmsRequestV6(data, config)
384 messagehandler.executeRequestLogic()
385 else:
386 print "Unhandled KMS version.", version
387 messagehandler = kmsRequestUnknown.kmsRequestUnknown(data, config)
388 return messagehandler.getResponse()