Compare commits

...

35 commits

Author SHA1 Message Date
simonmicro db7409b51a
Merge pull request #136 from Py-KMS-Organization/next
Some checks failed
Build release-tags / bake-latest (push) Has been cancelled
Test-Build Docker Image / bake-test (push) Has been cancelled
Next Release 🚀
2025-11-15 18:07:44 +01:00
simonmicro d006e2e587
Removed duplicate perm-setting (already part of Dockerfile)
Some checks failed
Build next-tags / bake-next (push) Has been cancelled
Test-Build Docker Image / bake-test (push) Has been cancelled
Signed-off-by: simonmicro <simon@simonmicro.de>
2025-11-08 13:41:17 +01:00
simonmicro d166068721
Addressed changed key format, as noted in https://docs.docker.com/go/dockerfile/rule/legacy-key-value-format/
Signed-off-by: simonmicro <simon@simonmicro.de>
2025-11-08 13:39:34 +01:00
simonmicro 6b6fb3513f
Fix RTD
Signed-off-by: simonmicro <simon@simonmicro.de>
2025-11-08 13:15:23 +01:00
simonmicro 7b62439bc3
Merge pull request #137 from Py-KMS-Organization/chore/update-workflows
Update workflows
2025-11-08 13:10:46 +01:00
simonmicro af78d24b94
As the code continues regardless, only show a warning
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-11-08 13:08:32 +01:00
simonmicro 7098a455c3
Typo
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-11-08 13:08:00 +01:00
simonmicro fc4f6b37e0
New job labels
Signed-off-by: simonmicro <simon@simonmicro.de>
2025-11-08 13:04:01 +01:00
simonmicro 88b5bb47c6
Updated all workflow jobs
Signed-off-by: simonmicro <simon@simonmicro.de>
2025-11-08 13:00:55 +01:00
simonmicro c86f243829
Dependency updates
Signed-off-by: simonmicro <simon@simonmicro.de>
2025-11-08 12:56:24 +01:00
simonmicro 94419c1a2f
Added more permission hardening
Signed-off-by: simonmicro <simon@simonmicro.de>
2025-11-08 12:56:11 +01:00
simonmicro a7db498206
Corrected ISO timestamp
Some checks failed
Build next-tags / bake-next (push) Has been cancelled
Test-Build Docker Image / bake-test (push) Has been cancelled
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-10-29 18:25:33 +01:00
simonmicro 2974fc0878
Merge pull request #130 from MrRubberDucky/wip-branch
Update KmsDataBase.xml, add missing entries and SKUs etc.
2025-10-29 18:18:19 +01:00
simonmicro ab5e7fb875
Merge remote-tracking branch 'origin/next' into wip-branch 2025-10-29 18:12:20 +01:00
Mr. Rubber Ducky b6a99091a8
Remove one leftover comment 2025-02-15 00:26:57 +01:00
Mr. Rubber Ducky 86634eee25
Remove missing entry for Office 2016 Pre-Release VL 2025-02-15 00:26:00 +01:00
Mr. Rubber Ducky ef73542ffa
Add Office 2021+2024 preview, re-add Windows Server Next etc. 2025-02-15 00:25:05 +01:00
Mr. Rubber Ducky dfbf68d221
Move Office LTSC 2024 Preview to correct KmsItem 2025-02-12 20:10:40 +01:00
Mr. Rubber Ducky cf706552b0
Revert previous work and go back to my previous KmsDataBase.xml file
For whatever reason the direct slight modification causes OS activation to fail?
2025-02-12 20:03:01 +01:00
Mr. Rubber Ducky f9cb59eb29
Re-add Windows Next entries 2025-02-12 18:40:42 +01:00
Mr. Rubber Ducky 6119d545df
Remove one part that I mistakenly re-added again 2025-02-12 18:35:28 +01:00
Mr. Rubber Ducky 2a3e3fa1fd
Correct PkeyConfig for Server 2022 and 2025 2025-02-12 18:33:28 +01:00
Mr. Rubber Ducky 628fbc448b
Fix small screw ups 2025-02-12 18:28:27 +01:00
Mr. Rubber Ducky 525f8e98f8
Update based on 2024 Hotbird64 KmsDataBase.xml 2025-02-12 17:55:15 +01:00
Mr. Rubber Ducky 1384dc75b8
Add CSVLK for Server 2025, Server 2025 Azure Edition and Internal lab 2025-02-12 16:34:26 +01:00
Mr. Rubber Ducky e1f2409e88
Update KmsDataBase.xml 2025-02-12 16:27:52 +01:00
Mr. Rubber Ducky 9c1a61df19
Update KmsDataBase.xml 2025-02-12 16:27:03 +01:00
simonmicro 465f4d14c7
Merge pull request #119 from zeronounours/fix_epid_gen_on_linux
Fix Epid generation on linux
2024-07-06 09:13:15 +02:00
zeroNounours 71f31d4fd0
Fix Epid generation on linux
Maybe related to #3
2024-06-27 09:47:14 +02:00
simonmicro e60cc1b7e1
Merge pull request #115 from Py-KMS-Organization/feature/newKmsDatabase
New KMS database & website extension
2024-06-10 12:16:54 +02:00
simonmicro 2ef58649f0
Use ReleaseDate instead of MinDate
Made InvalidWinBuild/NCountPolicy optional

Signed-off-by: simonmicro <simon@simonmicro.de>
2024-05-28 23:28:55 +02:00
simonmicro a639486121
Added groups to product page
Signed-off-by: simonmicro <simon@simonmicro.de>
2024-05-28 22:53:54 +02:00
simonmicro 0f58e9bb6f
Added KmsDataBase.xml from @nliaudat
He mentioned the new version being available at https://raw.githubusercontent.com/TheFlightSims/windowsserver-mgmttools/2dde6021fb3d0c0d5c76ef2b17315535c67dc62d/vlmcsd-beta/license-manager/KmsDataBase.xml

Signed-off-by: simonmicro <simon@simonmicro.de>
2024-05-28 22:00:11 +02:00
simonmicro 4f0b10c704
Formatting
Signed-off-by: simonmicro <simon@simonmicro.de>
2024-05-28 20:41:04 +02:00
simonmicro 644d7be16c
Revert "Removed all references to Docker Hub after their removal of "Free Team Organizations" -> https://web.docker.com/rs/790-SSB-375/images/privatereposfaq.pdf"
This reverts commit 81e9973a40, because they changed their minds. For now...
2024-05-28 20:23:06 +02:00
15 changed files with 683 additions and 913 deletions

View file

@ -14,38 +14,43 @@ jobs:
contents: read contents: read
steps: steps:
- name: Checkout - name: Checkout
uses: actions/checkout@v2.3.4 uses: actions/checkout@v5
- name: Set up QEMU - name: Set up QEMU
uses: docker/setup-qemu-action@v1 uses: docker/setup-qemu-action@v3
with: with:
platforms: all platforms: all
- name: Set up Docker Buildx - name: Set up Docker Buildx
uses: docker/setup-buildx-action@v1.6.0 uses: docker/setup-buildx-action@v3
- 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 - name: Login to GitHub Container Registry
uses: docker/login-action@v1.10.0 uses: docker/login-action@v1.10.0
with: with:
registry: ghcr.io registry: ghcr.io
username: ${{ github.actor }} username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }} password: ${{ secrets.GITHUB_TOKEN }}
- name: Build - name: Build (full)
uses: docker/build-push-action@v2 uses: docker/build-push-action@v6
with: with:
context: . context: .
file: ./docker/docker-py3-kms/Dockerfile file: ./docker/docker-py3-kms/Dockerfile
platforms: linux/amd64,linux/386,linux/arm64/v8,linux/arm/v7,linux/arm/v6 platforms: linux/amd64,linux/386,linux/arm64/v8,linux/arm/v7,linux/arm/v6
push: true 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-args: |
BUILD_COMMIT=${{ github.sha }} BUILD_COMMIT=${{ github.sha }}
BUILD_BRANCH=${{ github.ref_name }} BUILD_BRANCH=${{ github.ref_name }}
- name: Build - name: Build (minimal)
uses: docker/build-push-action@v2 uses: docker/build-push-action@v6
with: with:
context: . context: .
file: ./docker/docker-py3-kms-minimal/Dockerfile file: ./docker/docker-py3-kms-minimal/Dockerfile
platforms: linux/amd64,linux/386,linux/arm64/v8,linux/arm/v7,linux/arm/v6 platforms: linux/amd64,linux/386,linux/arm64/v8,linux/arm/v7,linux/arm/v6
push: true 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-args: |
BUILD_COMMIT=${{ github.sha }} BUILD_COMMIT=${{ github.sha }}
BUILD_BRANCH=${{ github.ref_name }} BUILD_BRANCH=${{ github.ref_name }}

View file

@ -14,38 +14,43 @@ jobs:
contents: read contents: read
steps: steps:
- name: Checkout - name: Checkout
uses: actions/checkout@v2.3.4 uses: actions/checkout@v5
- name: Set up QEMU - name: Set up QEMU
uses: docker/setup-qemu-action@v1 uses: docker/setup-qemu-action@v3
with: with:
platforms: all platforms: all
- name: Set up Docker Buildx - name: Set up Docker Buildx
uses: docker/setup-buildx-action@v1.6.0 uses: docker/setup-buildx-action@v3
- 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 - name: Login to GitHub Container Registry
uses: docker/login-action@v1.10.0 uses: docker/login-action@v1.10.0
with: with:
registry: ghcr.io registry: ghcr.io
username: ${{ github.actor }} username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }} password: ${{ secrets.GITHUB_TOKEN }}
- name: Build - name: Build (full)
uses: docker/build-push-action@v2 uses: docker/build-push-action@v6
with: with:
context: . context: .
file: ./docker/docker-py3-kms/Dockerfile file: ./docker/docker-py3-kms/Dockerfile
platforms: linux/amd64,linux/386,linux/arm64/v8,linux/arm/v7,linux/arm/v6 platforms: linux/amd64,linux/386,linux/arm64/v8,linux/arm/v7,linux/arm/v6
push: true 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-args: |
BUILD_COMMIT=${{ github.sha }} BUILD_COMMIT=${{ github.sha }}
BUILD_BRANCH=${{ github.ref_name }} BUILD_BRANCH=${{ github.ref_name }}
- name: Build - name: Build (minimal)
uses: docker/build-push-action@v2 uses: docker/build-push-action@v6
with: with:
context: . context: .
file: ./docker/docker-py3-kms-minimal/Dockerfile file: ./docker/docker-py3-kms-minimal/Dockerfile
platforms: linux/amd64,linux/386,linux/arm64/v8,linux/arm/v7,linux/arm/v6 platforms: linux/amd64,linux/386,linux/arm64/v8,linux/arm/v7,linux/arm/v6
push: true 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-args: |
BUILD_COMMIT=${{ github.sha }} BUILD_COMMIT=${{ github.sha }}
BUILD_BRANCH=${{ github.ref_name }} BUILD_BRANCH=${{ github.ref_name }}

View file

@ -9,15 +9,15 @@ jobs:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- name: Checkout - name: Checkout
uses: actions/checkout@v2.3.4 uses: actions/checkout@v5
- name: Set up QEMU - name: Set up QEMU
uses: docker/setup-qemu-action@v1 uses: docker/setup-qemu-action@v3
with: with:
platforms: all platforms: all
- name: Set up Docker Buildx - name: Set up Docker Buildx
uses: docker/setup-buildx-action@v1.6.0 uses: docker/setup-buildx-action@v3
- name: Build - name: Build (full)
uses: docker/build-push-action@v2 uses: docker/build-push-action@v6
with: with:
context: . context: .
file: ./docker/docker-py3-kms/Dockerfile file: ./docker/docker-py3-kms/Dockerfile
@ -26,8 +26,8 @@ jobs:
build-args: | build-args: |
BUILD_COMMIT=${{ github.sha }} BUILD_COMMIT=${{ github.sha }}
BUILD_BRANCH=${{ github.ref_name }} BUILD_BRANCH=${{ github.ref_name }}
- name: Build - name: Build (minimal)
uses: docker/build-push-action@v2 uses: docker/build-push-action@v6
with: with:
context: . context: .
file: ./docker/docker-py3-kms-minimal/Dockerfile file: ./docker/docker-py3-kms-minimal/Dockerfile
@ -35,4 +35,4 @@ jobs:
push: false push: false
build-args: | build-args: |
BUILD_COMMIT=${{ github.sha }} BUILD_COMMIT=${{ github.sha }}
BUILD_BRANCH=${{ github.ref_name }} BUILD_BRANCH=${{ github.ref_name }}

View file

@ -1,12 +1,15 @@
version: 2 version: 2
build: build:
os: "ubuntu-22.04" os: "ubuntu-24.04"
tools: tools:
python: "3.10" python: "3.12"
python: python:
install: install:
- requirements: docs/requirements.txt - requirements: docs/requirements.txt
sphinx:
configuration: docs/conf.py
formats: all formats: all

View file

@ -2,6 +2,7 @@
![repo-size](https://img.shields.io/github/repo-size/Py-KMS-Organization/py-kms) ![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) ![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) ![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) ![read-the-docs](https://img.shields.io/readthedocs/py-kms)
*** ***

View file

@ -1,19 +1,19 @@
# This is a minimized version from docker/docker-py3-kms/Dockerfile without SQLite support to further reduce image size # This is a minimized version from docker/docker-py3-kms/Dockerfile without SQLite support to further reduce image size
FROM alpine:3.15 FROM alpine:3.22
ENV IP :: ENV IP=::
ENV DUALSTACK 1 ENV DUALSTACK=1
ENV PORT 1688 ENV PORT=1688
ENV EPID "" ENV EPID=""
ENV LCID 1033 ENV LCID=1033
ENV CLIENT_COUNT 26 ENV CLIENT_COUNT=26
ENV ACTIVATION_INTERVAL 120 ENV ACTIVATION_INTERVAL=120
ENV RENEWAL_INTERVAL 10080 ENV RENEWAL_INTERVAL=10080
ENV HWID RANDOM ENV HWID RANDOM
ENV LOGLEVEL INFO ENV LOGLEVEL=INFO
ENV LOGFILE STDOUT ENV LOGFILE=STDOUT
ENV LOGSIZE "" ENV LOGSIZE=""
ENV WEBUI 0 ENV WEBUI=0
COPY docker/docker-py3-kms-minimal/requirements.txt /home/py-kms/requirements.txt COPY docker/docker-py3-kms-minimal/requirements.txt /home/py-kms/requirements.txt
RUN apk add --no-cache --update \ RUN apk add --no-cache --update \
@ -23,7 +23,7 @@ bash \
ca-certificates \ ca-certificates \
shadow \ shadow \
tzdata \ tzdata \
&& pip3 install --no-cache-dir -r /home/py-kms/requirements.txt \ && pip3 install --break-system-packages --no-cache-dir -r /home/py-kms/requirements.txt \
&& adduser -S py-kms -G users -s /bin/bash \ && adduser -S py-kms -G users -s /bin/bash \
&& chown py-kms:users /home/py-kms \ && chown py-kms:users /home/py-kms \
# Fix undefined timezone, in case the user did not mount the /etc/localtime # Fix undefined timezone, in case the user did not mount the /etc/localtime
@ -35,6 +35,13 @@ COPY docker/healthcheck.py /usr/bin/healthcheck.py
COPY docker/start.py /usr/bin/start.py COPY docker/start.py /usr/bin/start.py
RUN chmod 555 /usr/bin/entrypoint.py /usr/bin/healthcheck.py /usr/bin/start.py RUN chmod 555 /usr/bin/entrypoint.py /usr/bin/healthcheck.py /usr/bin/start.py
# Additional permission hardening: All files read-only for the executing user
RUN chown root: -R /home/py-kms && \
chmod 444 -R /home/py-kms && \
chown py-kms: /home/py-kms && \
chmod 700 /home/py-kms && \
find /home/py-kms -type d -print -exec chmod +x {} ';'
WORKDIR /home/py-kms WORKDIR /home/py-kms
EXPOSE ${PORT}/tcp EXPOSE ${PORT}/tcp

View file

@ -1,23 +1,23 @@
# Switch to the target image # Switch to the target image
FROM alpine:3.15 FROM alpine:3.22
ARG BUILD_COMMIT=unknown ARG BUILD_COMMIT=unknown
ARG BUILD_BRANCH=unknown ARG BUILD_BRANCH=unknown
ENV IP :: ENV IP=::
ENV DUALSTACK 1 ENV DUALSTACK=1
ENV PORT 1688 ENV PORT=1688
ENV EPID "" ENV EPID=""
ENV LCID 1033 ENV LCID=1033
ENV CLIENT_COUNT 26 ENV CLIENT_COUNT=26
ENV ACTIVATION_INTERVAL 120 ENV ACTIVATION_INTERVAL=120
ENV RENEWAL_INTERVAL 10080 ENV RENEWAL_INTERVAL=10080
ENV HWID RANDOM ENV HWID=RANDOM
ENV LOGLEVEL INFO ENV LOGLEVEL=INFO
ENV LOGFILE STDOUT ENV LOGFILE=STDOUT
ENV LOGSIZE "" ENV LOGSIZE=""
ENV TZ America/Chicago ENV TZ=America/Chicago
ENV WEBUI 1 ENV WEBUI=1
COPY docker/docker-py3-kms/requirements.txt /home/py-kms/ COPY docker/docker-py3-kms/requirements.txt /home/py-kms/
RUN apk add --no-cache --update \ RUN apk add --no-cache --update \
@ -28,7 +28,7 @@ RUN apk add --no-cache --update \
ca-certificates \ ca-certificates \
tzdata \ tzdata \
shadow \ shadow \
&& pip3 install --no-cache-dir -r /home/py-kms/requirements.txt \ && pip3 install --break-system-packages --no-cache-dir -r /home/py-kms/requirements.txt \
&& mkdir /db/ \ && mkdir /db/ \
&& adduser -S py-kms -G users -s /bin/bash \ && adduser -S py-kms -G users -s /bin/bash \
&& chown py-kms:users /home/py-kms \ && chown py-kms:users /home/py-kms \
@ -41,6 +41,13 @@ COPY docker/healthcheck.py /usr/bin/healthcheck.py
COPY docker/start.py /usr/bin/start.py COPY docker/start.py /usr/bin/start.py
RUN chmod 555 /usr/bin/entrypoint.py /usr/bin/healthcheck.py /usr/bin/start.py RUN chmod 555 /usr/bin/entrypoint.py /usr/bin/healthcheck.py /usr/bin/start.py
# Additional permission hardening: All files read-only for the executing user
RUN chown root: -R /home/py-kms && \
chmod 444 -R /home/py-kms && \
chown py-kms: /home/py-kms && \
chmod 700 /home/py-kms && \
find /home/py-kms -type d -print -exec chmod +x {} ';'
# Web-interface specifics # Web-interface specifics
COPY LICENSE /LICENSE COPY LICENSE /LICENSE
RUN echo "$BUILD_COMMIT" > /VERSION && echo "$BUILD_BRANCH" >> /VERSION RUN echo "$BUILD_COMMIT" > /VERSION && echo "$BUILD_BRANCH" >> /VERSION

View file

@ -1,5 +1,5 @@
dnspython==2.6.1 dnspython==2.8.0
tzlocal==4.2 tzlocal==5.3.1
Flask==2.3.2 Flask==3.1.2
gunicorn==22.0.0 gunicorn==23.0.0

View file

@ -25,29 +25,34 @@ def change_uid_grp(logger):
new_gid = int(os.getenv('GID', str(gid))) new_gid = int(os.getenv('GID', str(gid)))
new_uid = int(os.getenv('UID', str(uid))) new_uid = int(os.getenv('UID', str(uid)))
os.chown("/home/py-kms", new_uid, new_gid) os.chown("/home/py-kms", new_uid, new_gid)
os.chown("/usr/bin/start.py", new_uid, new_gid) os.chmod("/home/py-kms", 0o700)
if os.path.isdir(dbPath): if os.path.isdir(dbPath):
# Corret permissions recursively, as to access the database file, also its parent folder must be accessible # Correct permissions recursively, as to access the database file, also its parent folder must be accessible
logger.debug(f'Correcting owner permissions on {dbPath}.') logger.debug(f'Correcting owner permissions on {dbPath}')
os.chown(dbPath, new_uid, new_gid) os.chown(dbPath, new_uid, new_gid)
os.chmod(dbPath, 0o700) # executable bit on dirs to allow interaction
for root, dirs, files in os.walk(dbPath): for root, dirs, files in os.walk(dbPath):
for dName in dirs: for dName in dirs:
dPath = os.path.join(root, dName) dPath = os.path.join(root, dName)
logger.debug(f'Correcting owner permissions on {dPath}.') logger.debug(f'Correcting owner permissions on {dPath}')
os.chown(dPath, new_uid, new_gid) os.chown(dPath, new_uid, new_gid)
os.chmod(dPath, 0o700) # executable bit on dirs to allow interaction
for fName in files: for fName in files:
fPath = os.path.join(root, fName) fPath = os.path.join(root, fName)
logger.debug(f'Correcting owner permissions on {fPath}.') logger.debug(f'Correcting owner permissions on {fPath}')
os.chown(fPath, new_uid, new_gid) os.chown(fPath, new_uid, new_gid)
os.chmod(fPath, 0o600)
logger.debug(subprocess.check_output(['ls', '-la', dbPath]).decode()) logger.debug(subprocess.check_output(['ls', '-la', dbPath]).decode())
else:
logger.warning(f'Database path {dbPath} is not a directory, will not correct owner permissions.')
if 'LOGFILE' in os.environ and os.path.exists(os.environ['LOGFILE']): if 'LOGFILE' in os.environ and os.path.exists(os.environ['LOGFILE']):
# Oh, the user also wants a custom log file -> make sure start.py can access it by setting the correct permissions (777) # Oh, the user also wants a custom log file -> make sure start.py can access it by setting the correct permissions (777)
os.chmod(os.environ['LOGFILE'], 0o777) os.chmod(os.environ['LOGFILE'], 0o777)
logger.error(str(subprocess.check_output(['ls', '-la', os.environ['LOGFILE']]))) logger.error(str(subprocess.check_output(['ls', '-la', os.environ['LOGFILE']])))
logger.info("Setting gid to '%s'." % str(new_gid)) # Drop actual permissions
logger.info(f"Setting gid to {new_gid}")
os.setgid(new_gid) os.setgid(new_gid)
logger.info(f"Setting uid to {new_uid}")
logger.info("Setting uid to '%s'." % str(new_uid))
os.setuid(new_uid) os.setuid(new_uid)
def change_tz(logger): def change_tz(logger):

View file

@ -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. 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
![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 ! 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 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. command will download, "install" and start _py-kms_ and also keep it alive after any service disruption.

File diff suppressed because it is too large Load diff

View file

@ -184,7 +184,7 @@ def client_update():
if sName == name + 'Enterprise' or \ if sName == name + 'Enterprise' or \
sName == name[:6] + 'ProfessionalPlus' + name[6:]: sName == name[:6] + 'ProfessionalPlus' + name[6:]:
clt_config['KMSClientSkuID'] = skuitem['Id'] 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['KMSProtocolMajorVersion'] = int(float(kmsitem['DefaultKmsProtocol']))
clt_config['KMSProtocolMinorVersion'] = 0 clt_config['KMSProtocolMinorVersion'] = 0
clt_config['KMSClientLicenseStatus'] = 2 clt_config['KMSClientLicenseStatus'] = 2

View file

@ -20,7 +20,7 @@ def epidGenerator(kmsId, version, lcid):
for csvlkitem in csvlkitems: for csvlkitem in csvlkitems:
try: try:
if kmsId in [ uuid.UUID(kmsitem) for kmsitem in csvlkitem['Activate'] ]: 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: else:
# fallback to Windows Server 2019 parameters. # fallback to Windows Server 2019 parameters.
pkeys.append( ('206', '551000000', '570999999', '[0,1,2]') ) pkeys.append( ('206', '551000000', '570999999', '[0,1,2]') )
@ -40,10 +40,11 @@ def epidGenerator(kmsId, version, lcid):
hosts.append(winbuild) hosts.append(winbuild)
except KeyError: except KeyError:
# fallback to Windows Server 2019 parameters. # 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) 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 # Generate Part 3 and Part 4: Product Key ID
productKeyID = random.randint(MinKeyId, MaxKeyId) productKeyID = random.randint(MinKeyId, MaxKeyId)
@ -55,11 +56,11 @@ def epidGenerator(kmsId, version, lcid):
languageCode = lcid # (C# CultureInfo.InstalledUICulture.LCID) languageCode = lcid # (C# CultureInfo.InstalledUICulture.LCID)
# Generate Part 8: KMS Host Activation Date # 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) minTime = datetime.date(d.year, d.month, d.day)
# Generate Year and Day Number # 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) firstOfYear = datetime.date(randomDate.year, 1, 1)
randomDayNumber = int((time.mktime(randomDate.timetuple()) - time.mktime(firstOfYear.timetuple())) / 86400 + 0.5) randomDayNumber = int((time.mktime(randomDate.timetuple()) - time.mktime(firstOfYear.timetuple())) / 86400 + 0.5)

View file

@ -15,33 +15,34 @@ def _get_serve_count():
return _serve_count return _serve_count
_kms_items = None _kms_items = None
_kms_items_ignored = None _kms_items_noglvk = None
def _get_kms_items_cache(): def _get_kms_items_cache():
global _kms_items, _kms_items_ignored global _kms_items, _kms_items_noglvk
if _kms_items is None: if _kms_items is None:
_kms_items = {} _kms_items = {} # {group: str -> {product: str -> gvlk: str}}
_kms_items_ignored = 0 _kms_items_noglvk = 0
queue = [kmsDB2Dict()] for section in kmsDB2Dict():
while len(queue): for element in section:
item = queue.pop(0) if "KmsItems" in element:
if isinstance(item, list): for product in element["KmsItems"]:
for i in item: group_name = product["DisplayName"]
queue.append(i) items = {}
elif isinstance(item, dict): for item in product["SkuItems"]:
if 'KmsItems' in item: items[item["DisplayName"]] = item["Gvlk"]
queue.append(item['KmsItems']) if not item["Gvlk"]:
elif 'SkuItems' in item: _kms_items_noglvk += 1
queue.append(item['SkuItems']) if len(items) == 0:
elif 'Gvlk' in item: continue
if len(item['Gvlk']): if group_name not in _kms_items:
_kms_items[item['DisplayName']] = item['Gvlk'] _kms_items[group_name] = {}
else: _kms_items[group_name].update(items)
_kms_items_ignored += 1 elif "DisplayName" in element and "BuildNumber" in element and "PlatformId" in element:
#else: pass # these are WinBuilds
# print(item) elif "DisplayName" in element and "Activate" in element:
else: pass # these are CsvlkItems
raise NotImplementedError(f'Unknown type: {type(item)}') else:
return _kms_items, _kms_items_ignored raise NotImplementedError(f'Unknown element: {element}')
return _kms_items, _kms_items_noglvk
app = Flask('pykms_webui') app = Flask('pykms_webui')
app.jinja_env.globals['start_time'] = datetime.datetime.now() app.jinja_env.globals['start_time'] = datetime.datetime.now()
@ -90,7 +91,7 @@ def root():
count_clients=countClients, count_clients=countClients,
count_clients_windows=countClientsWindows, count_clients_windows=countClientsWindows,
count_clients_office=countClientsOffice, 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 ), 200 if error is None else 500
@app.route('/readyz') @app.route('/readyz')
@ -125,15 +126,15 @@ def license():
@app.route('/products') @app.route('/products')
def products(): def products():
_increase_serve_count() _increase_serve_count()
items, ignored = _get_kms_items_cache() items, noglvk = _get_kms_items_cache()
countProducts = len(items) countProducts = sum([len(entries) for entries in items.values()])
countProductsWindows = len([i for i in items if 'windows' in i.lower()]) countProductsWindows = sum([len(entries) for (name, entries) in items.items() if 'windows' in name.lower()])
countProductsOffice = len([i for i in items if 'office' in i.lower()]) countProductsOffice = sum([len(entries) for (name, entries) in items.items() if 'office' in name.lower()])
return render_template( return render_template(
'products.html', 'products.html',
path='/products/', path='/products/',
products=items, products=items,
filtered=ignored, filtered=noglvk,
count_products=countProducts, count_products=countProducts,
count_products_windows=countProductsWindows, count_products_windows=countProductsWindows,
count_products_office=countProductsOffice count_products_office=countProductsOffice

View file

@ -32,22 +32,36 @@
<hr> <hr>
<style scoped>
td.glvk {
width: 24rem;
}
pre.glvk {
width: min-content;
}
</style>
{% for group_name, group_products in products | dictsort %}
<h1 class="title">{{ group_name }}</h1>
<table class="table is-bordered is-striped is-hoverable is-fullwidth"> <table class="table is-bordered is-striped is-hoverable is-fullwidth">
<thead> <thead>
<tr> <tr>
<th>Name</th> <th>Name</th>
<th><abbr title="Group Volume License Key">GVLK</abbr></th> <th class="glvk"><abbr title="Group Volume License Key">GVLK</abbr></th>
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
{% for name, gvlk in products | dictsort %} {% for name, gvlk in group_products | dictsort %}
{% if gvlk %} <tr>
<tr> <td>{{ name }}</td>
<td>{{ name }}</td> <td class="glvk">
<td><pre>{{ gvlk }}</pre></td> {% if gvlk %}
</tr> <pre class="glvk">{{ gvlk }}</pre>{% endif %}
{% endif %} </td>
{% endfor %} </tr>
{% endfor %}
</tbody> </tbody>
</table> </table>
{% endblock %} {% endfor %}
{% endblock %}