diff --git a/.github/workflows/bake_to_latest.yml b/.github/workflows/bake_to_latest.yml index 0d5c8c6..c5c0cba 100644 --- a/.github/workflows/bake_to_latest.yml +++ b/.github/workflows/bake_to_latest.yml @@ -21,6 +21,11 @@ jobs: platforms: all - name: Set up Docker Buildx uses: docker/setup-buildx-action@v1.6.0 + - name: Login to DockerHub + uses: docker/login-action@v1.10.0 + with: + username: ${{ secrets.DOCKER_USERNAME }} + password: ${{ secrets.DOCKER_PASSWORD }} - name: Login to GitHub Container Registry uses: docker/login-action@v1.10.0 with: @@ -34,7 +39,7 @@ jobs: file: ./docker/docker-py3-kms/Dockerfile platforms: linux/amd64,linux/386,linux/arm64/v8,linux/arm/v7,linux/arm/v6 push: true - tags: ghcr.io/py-kms-organization/py-kms:python3 + tags: pykmsorg/py-kms:python3,ghcr.io/py-kms-organization/py-kms:python3 build-args: | BUILD_COMMIT=${{ github.sha }} BUILD_BRANCH=${{ github.ref_name }} @@ -45,7 +50,7 @@ jobs: file: ./docker/docker-py3-kms-minimal/Dockerfile platforms: linux/amd64,linux/386,linux/arm64/v8,linux/arm/v7,linux/arm/v6 push: true - tags: ghcr.io/py-kms-organization/py-kms:latest,ghcr.io/py-kms-organization/py-kms:minimal + tags: pykmsorg/py-kms:latest,ghcr.io/py-kms-organization/py-kms:latest,pykmsorg/py-kms:minimal,ghcr.io/py-kms-organization/py-kms:minimal build-args: | BUILD_COMMIT=${{ github.sha }} BUILD_BRANCH=${{ github.ref_name }} diff --git a/.github/workflows/bake_to_next.yml b/.github/workflows/bake_to_next.yml index 5fc1b6c..f605731 100644 --- a/.github/workflows/bake_to_next.yml +++ b/.github/workflows/bake_to_next.yml @@ -21,6 +21,11 @@ jobs: platforms: all - name: Set up Docker Buildx uses: docker/setup-buildx-action@v1.6.0 + - name: Login to DockerHub + uses: docker/login-action@v1.10.0 + with: + username: ${{ secrets.DOCKER_USERNAME }} + password: ${{ secrets.DOCKER_PASSWORD }} - name: Login to GitHub Container Registry uses: docker/login-action@v1.10.0 with: @@ -34,7 +39,7 @@ jobs: file: ./docker/docker-py3-kms/Dockerfile platforms: linux/amd64,linux/386,linux/arm64/v8,linux/arm/v7,linux/arm/v6 push: true - tags: ghcr.io/py-kms-organization/py-kms:python3-next + tags: pykmsorg/py-kms:python3-next,ghcr.io/py-kms-organization/py-kms:python3-next build-args: | BUILD_COMMIT=${{ github.sha }} BUILD_BRANCH=${{ github.ref_name }} @@ -45,7 +50,7 @@ jobs: file: ./docker/docker-py3-kms-minimal/Dockerfile platforms: linux/amd64,linux/386,linux/arm64/v8,linux/arm/v7,linux/arm/v6 push: true - tags: ghcr.io/py-kms-organization/py-kms:latest-next,ghcr.io/py-kms-organization/py-kms:minimal-next + tags: pykmsorg/py-kms:latest-next,ghcr.io/py-kms-organization/py-kms:latest-next,pykmsorg/py-kms:minimal-next,ghcr.io/py-kms-organization/py-kms:minimal-next build-args: | BUILD_COMMIT=${{ github.sha }} BUILD_BRANCH=${{ github.ref_name }} diff --git a/README.md b/README.md index 0ba649e..8eb8138 100644 --- a/README.md +++ b/README.md @@ -2,6 +2,7 @@ ![repo-size](https://img.shields.io/github/repo-size/Py-KMS-Organization/py-kms) ![open-issues](https://img.shields.io/github/issues/Py-KMS-Organization/py-kms) ![last-commit](https://img.shields.io/github/last-commit/Py-KMS-Organization/py-kms/master) +![docker-pulls](https://img.shields.io/docker/pulls/pykmsorg/py-kms) ![read-the-docs](https://img.shields.io/readthedocs/py-kms) *** diff --git a/docs/Getting Started.md b/docs/Getting Started.md index cb1e43e..54d2b08 100644 --- a/docs/Getting Started.md +++ b/docs/Getting Started.md @@ -5,6 +5,9 @@ What follows are some guides how to start the `pykms_Server.py` script, which pr You can simply manage a daemon that runs as a background process. This can be achieved by using any of the notes below or by writing your own solution. ### Docker +![docker-pulls](https://img.shields.io/docker/pulls/pykmsorg/py-kms) +![docker-size](https://img.shields.io/docker/image-size/pykmsorg/py-kms) + If you wish to get _py-kms_ just up and running without installing any dependencies or writing own scripts: Just use Docker ! Docker also solves problems regarding the explicit IPv4 and IPv6 usage (it just supports both). The following command will download, "install" and start _py-kms_ and also keep it alive after any service disruption. diff --git a/py-kms/KmsDataBase.xml b/py-kms/KmsDataBase.xml index 0bc62c6..dbeb7f7 100644 --- a/py-kms/KmsDataBase.xml +++ b/py-kms/KmsDataBase.xml @@ -81,657 +81,657 @@ You can read them using pkeyconfig-gui off MDL forums or Product Key Config. Rea --> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/py-kms/pykms_Client.py b/py-kms/pykms_Client.py index d2fe1b5..142b316 100644 --- a/py-kms/pykms_Client.py +++ b/py-kms/pykms_Client.py @@ -184,7 +184,7 @@ def client_update(): if sName == name + 'Enterprise' or \ sName == name[:6] + 'ProfessionalPlus' + name[6:]: clt_config['KMSClientSkuID'] = skuitem['Id'] - clt_config['RequiredClientCount'] = int(kmsitem['NCountPolicy']) + clt_config['RequiredClientCount'] = int(kmsitem.get('NCountPolicy', 25)) # if not given default to 25 clt_config['KMSProtocolMajorVersion'] = int(float(kmsitem['DefaultKmsProtocol'])) clt_config['KMSProtocolMinorVersion'] = 0 clt_config['KMSClientLicenseStatus'] = 2 diff --git a/py-kms/pykms_PidGenerator.py b/py-kms/pykms_PidGenerator.py index bf84187..f73102a 100644 --- a/py-kms/pykms_PidGenerator.py +++ b/py-kms/pykms_PidGenerator.py @@ -20,7 +20,7 @@ def epidGenerator(kmsId, version, lcid): for csvlkitem in csvlkitems: try: if kmsId in [ uuid.UUID(kmsitem) for kmsitem in csvlkitem['Activate'] ]: - pkeys.append( (csvlkitem['GroupId'], csvlkitem['MinKeyId'], csvlkitem['MaxKeyId'], csvlkitem['InvalidWinBuild']) ) + pkeys.append( (csvlkitem['GroupId'], csvlkitem['MinKeyId'], csvlkitem['MaxKeyId'], csvlkitem.get('InvalidWinBuild', '[]')) ) else: # fallback to Windows Server 2019 parameters. pkeys.append( ('206', '551000000', '570999999', '[0,1,2]') ) @@ -40,10 +40,11 @@ def epidGenerator(kmsId, version, lcid): hosts.append(winbuild) except KeyError: # fallback to Windows Server 2019 parameters. - hosts.append( {'BuildNumber':'17763', 'PlatformId':'3612', 'MinDate':'02/10/2018'} ) + hosts.append( {'BuildNumber':'17763', 'PlatformId':'3612', 'ReleaseDate':'2018-10-02T00:00:00Z'} ) host = random.choice(hosts) - BuildNumber, PlatformId, MinDate = host['BuildNumber'], host['PlatformId'], host['MinDate'] + + BuildNumber, PlatformId, ReleaseDate = host['BuildNumber'], host['PlatformId'], host['ReleaseDate'].rstrip("Z") # Generate Part 3 and Part 4: Product Key ID productKeyID = random.randint(MinKeyId, MaxKeyId) @@ -55,11 +56,11 @@ def epidGenerator(kmsId, version, lcid): languageCode = lcid # (C# CultureInfo.InstalledUICulture.LCID) # Generate Part 8: KMS Host Activation Date - d = datetime.datetime.strptime(MinDate, "%d/%m/%Y") + d = datetime.datetime.fromisoformat(ReleaseDate) minTime = datetime.date(d.year, d.month, d.day) # Generate Year and Day Number - randomDate = datetime.date.fromtimestamp(random.randint(time.mktime(minTime.timetuple()), time.mktime(datetime.datetime.now().timetuple()))) + randomDate = datetime.date.fromtimestamp(random.randint(int(time.mktime(minTime.timetuple())), int(time.mktime(datetime.datetime.now().timetuple())))) firstOfYear = datetime.date(randomDate.year, 1, 1) randomDayNumber = int((time.mktime(randomDate.timetuple()) - time.mktime(firstOfYear.timetuple())) / 86400 + 0.5) diff --git a/py-kms/pykms_WebUI.py b/py-kms/pykms_WebUI.py index 43285a5..06b7d7e 100644 --- a/py-kms/pykms_WebUI.py +++ b/py-kms/pykms_WebUI.py @@ -15,33 +15,34 @@ def _get_serve_count(): return _serve_count _kms_items = None -_kms_items_ignored = None +_kms_items_noglvk = None def _get_kms_items_cache(): - global _kms_items, _kms_items_ignored + global _kms_items, _kms_items_noglvk if _kms_items is None: - _kms_items = {} - _kms_items_ignored = 0 - queue = [kmsDB2Dict()] - while len(queue): - item = queue.pop(0) - if isinstance(item, list): - for i in item: - queue.append(i) - elif isinstance(item, dict): - if 'KmsItems' in item: - queue.append(item['KmsItems']) - elif 'SkuItems' in item: - queue.append(item['SkuItems']) - elif 'Gvlk' in item: - if len(item['Gvlk']): - _kms_items[item['DisplayName']] = item['Gvlk'] - else: - _kms_items_ignored += 1 - #else: - # print(item) - else: - raise NotImplementedError(f'Unknown type: {type(item)}') - return _kms_items, _kms_items_ignored + _kms_items = {} # {group: str -> {product: str -> gvlk: str}} + _kms_items_noglvk = 0 + for section in kmsDB2Dict(): + for element in section: + if "KmsItems" in element: + for product in element["KmsItems"]: + group_name = product["DisplayName"] + items = {} + for item in product["SkuItems"]: + items[item["DisplayName"]] = item["Gvlk"] + if not item["Gvlk"]: + _kms_items_noglvk += 1 + if len(items) == 0: + continue + if group_name not in _kms_items: + _kms_items[group_name] = {} + _kms_items[group_name].update(items) + elif "DisplayName" in element and "BuildNumber" in element and "PlatformId" in element: + pass # these are WinBuilds + elif "DisplayName" in element and "Activate" in element: + pass # these are CsvlkItems + else: + raise NotImplementedError(f'Unknown element: {element}') + return _kms_items, _kms_items_noglvk app = Flask('pykms_webui') app.jinja_env.globals['start_time'] = datetime.datetime.now() @@ -90,7 +91,7 @@ def root(): count_clients=countClients, count_clients_windows=countClientsWindows, count_clients_office=countClientsOffice, - count_projects=len(_get_kms_items_cache()[0]) + count_projects=sum([len(entries) for entries in _get_kms_items_cache()[0].values()]) ), 200 if error is None else 500 @app.route('/readyz') @@ -125,15 +126,15 @@ def license(): @app.route('/products') def products(): _increase_serve_count() - items, ignored = _get_kms_items_cache() - countProducts = len(items) - countProductsWindows = len([i for i in items if 'windows' in i.lower()]) - countProductsOffice = len([i for i in items if 'office' in i.lower()]) + items, noglvk = _get_kms_items_cache() + countProducts = sum([len(entries) for entries in items.values()]) + countProductsWindows = sum([len(entries) for (name, entries) in items.items() if 'windows' in name.lower()]) + countProductsOffice = sum([len(entries) for (name, entries) in items.items() if 'office' in name.lower()]) return render_template( 'products.html', path='/products/', products=items, - filtered=ignored, + filtered=noglvk, count_products=countProducts, count_products_windows=countProductsWindows, count_products_office=countProductsOffice diff --git a/py-kms/templates/products.html b/py-kms/templates/products.html index 9665304..d106ed1 100644 --- a/py-kms/templates/products.html +++ b/py-kms/templates/products.html @@ -32,22 +32,36 @@
+ + +{% for group_name, group_products in products | dictsort %} +

{{ group_name }}

- - + + - {% for name, gvlk in products | dictsort %} - {% if gvlk %} - - - - - {% endif %} - {% endfor %} + {% for name, gvlk in group_products | dictsort %} + + + + + {% endfor %}
NameGVLKNameGVLK
{{ name }}
{{ gvlk }}
{{ name }} + {% if gvlk %} +
{{ gvlk }}
{% endif %} +
-{% endblock %} \ No newline at end of file +{% endfor %} +{% endblock %}