Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
38 commits
Select commit Hold shift + click to select a range
45d7f82
Reformatting and a bit of cleanup
simonmicro Dec 6, 2025
df0b7d3
Moved changelog and added semantic-versioning note into README
simonmicro Dec 6, 2025
99be2c9
Prepare to switch to main as stable branch
simonmicro Dec 6, 2025
565ef8d
Updated a few workflow actions
simonmicro Dec 6, 2025
62508df
Update workflows to also build tagged releases
simonmicro Dec 6, 2025
bc73818
Specify the branch to base on
simonmicro Dec 6, 2025
1621f9a
Use correct non-branch wording
simonmicro Dec 6, 2025
1a9ebe7
Typo
simonmicro Dec 6, 2025
047bff1
Dropped changelog symlink
simonmicro Dec 6, 2025
351edba
Merge pull request #140 from Py-KMS-Organization/feature/semantic_ver…
simonmicro Jan 18, 2026
ecf50e0
fix: windows server 2019 activation failing because of incomplete entry
Rileran Jan 22, 2026
2d72cc8
Replaced dead watchtower with fork, fixes #142
simonmicro Apr 11, 2026
eae3e5f
Cleanup
simonmicro Dec 6, 2025
4c1d7b5
Fix warnings due to deprecation
simonmicro Dec 6, 2025
2baf218
Added lastRequstIP and renamed appId to applicationId
simonmicro Dec 6, 2025
a5502e5
Actually show exceptions during processing
simonmicro Dec 6, 2025
eafe387
Adapt new sqlite-availability check
simonmicro Dec 6, 2025
25679ef
Reformatting and exposed new ip-field
simonmicro Dec 6, 2025
af2527a
Also fix legacy format
simonmicro Dec 6, 2025
cadcb7a
Typos
simonmicro Dec 6, 2025
c8d460f
Corrected parameter bindings
simonmicro Dec 6, 2025
95b4c2e
Add test instructions
simonmicro Dec 6, 2025
ca722bb
Fixed another location of db-ordered fields
simonmicro Dec 6, 2025
dcf9051
Nitpick newline spaces
simonmicro Dec 6, 2025
cd7cbd1
Also test new clients explicitly :/
simonmicro Dec 6, 2025
bb9946b
Enforce correct empty default value
simonmicro Dec 6, 2025
24b2630
Added a simple client test
simonmicro Dec 6, 2025
f8e4253
Removed now useless error-wrapping
simonmicro Dec 6, 2025
9c83557
Prevent unknown column names from being passed to DB
simonmicro Dec 6, 2025
ba9d1f0
Migrated to named columns to prevent any accidential re-order
simonmicro Dec 6, 2025
59aaa13
Merge pull request #141 from Py-KMS-Organization/feature/record_clien…
simonmicro Apr 11, 2026
2d37400
Do not drop permissions, if not needed
simonmicro Apr 11, 2026
e99762f
More logging for issues with permissions
simonmicro Apr 11, 2026
7490ba9
Fixed hardening to allow already dropped users to access the app-dir,…
simonmicro Apr 11, 2026
6790958
Provide ephemeral db-path by default for web-ui container
simonmicro Apr 11, 2026
1f3824a
Merge pull request #146 from Py-KMS-Organization/bug/no_perm_drop_wit…
simonmicro Apr 11, 2026
937bb68
Replace tabs with spaces
simonmicro Apr 11, 2026
8dea676
Merge pull request #143 from Rileran/fix/windows-server-2019
simonmicro Apr 17, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 25 additions & 11 deletions .github/workflows/bake_to_latest.yml
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
name: Build release-tags
name: Build latest/main tags

on:
workflow_dispatch:
push:
branches:
- master
- main

jobs:
bake-latest:
Expand All @@ -14,20 +14,20 @@ jobs:
contents: read
steps:
- name: Checkout
uses: actions/checkout@v5
- name: Set up QEMU
uses: actions/checkout@v6
- name: Docker Setup QEMU
uses: docker/setup-qemu-action@v3
with:
platforms: all
- name: Set up Docker Buildx
- name: Docker Setup Buildx
uses: docker/setup-buildx-action@v3
- name: Login to DockerHub
uses: docker/login-action@v1.10.0
uses: docker/login-action@v3
with:
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_PASSWORD }}
- name: Login to GitHub Container Registry
uses: docker/login-action@v1.10.0
uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.actor }}
Expand All @@ -39,18 +39,32 @@ jobs:
file: ./docker/docker-py3-kms/Dockerfile
platforms: linux/amd64,linux/386,linux/arm64/v8,linux/arm/v7,linux/arm/v6
push: true
tags: pykmsorg/py-kms:python3,ghcr.io/py-kms-organization/py-kms:python3
# the tag "python3" is for backward compatibility only
tags: |
pykmsorg/py-kms:main
ghcr.io/py-kms-organization/py-kms:main
pykmsorg/py-kms:main-full
ghcr.io/py-kms-organization/py-kms:main-full
pykmsorg/py-kms:python3
ghcr.io/py-kms-organization/py-kms:python3
build-args: |
BUILD_COMMIT=${{ github.sha }}
BUILD_BRANCH=${{ github.ref_name }}
BUILD_REFERENCE=${{ github.ref_name }}
- name: Build (minimal)
uses: docker/build-push-action@v6
with:
context: .
file: ./docker/docker-py3-kms-minimal/Dockerfile
platforms: linux/amd64,linux/386,linux/arm64/v8,linux/arm/v7,linux/arm/v6
push: true
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
# the tag "minimal" is for backward compatibility only
tags: |
pykmsorg/py-kms:latest
ghcr.io/py-kms-organization/py-kms:latest
pykmsorg/py-kms:main-minimal
ghcr.io/py-kms-organization/py-kms:main-minimal
pykmsorg/py-kms:minimal
ghcr.io/py-kms-organization/py-kms:minimal
build-args: |
BUILD_COMMIT=${{ github.sha }}
BUILD_BRANCH=${{ github.ref_name }}
BUILD_REFERENCE=${{ github.ref_name }}
34 changes: 24 additions & 10 deletions .github/workflows/bake_to_next.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
name: Build next-tags
name: Build next tags

on:
workflow_dispatch:
Expand All @@ -14,20 +14,20 @@ jobs:
contents: read
steps:
- name: Checkout
uses: actions/checkout@v5
- name: Set up QEMU
uses: actions/checkout@v6
- name: Docker Setup QEMU
uses: docker/setup-qemu-action@v3
with:
platforms: all
- name: Set up Docker Buildx
- name: Docker Setup Buildx
uses: docker/setup-buildx-action@v3
- name: Login to DockerHub
uses: docker/login-action@v1.10.0
uses: docker/login-action@v3
with:
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_PASSWORD }}
- name: Login to GitHub Container Registry
uses: docker/login-action@v1.10.0
uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.actor }}
Expand All @@ -39,18 +39,32 @@ jobs:
file: ./docker/docker-py3-kms/Dockerfile
platforms: linux/amd64,linux/386,linux/arm64/v8,linux/arm/v7,linux/arm/v6
push: true
tags: pykmsorg/py-kms:python3-next,ghcr.io/py-kms-organization/py-kms:python3-next
# the tag "python3-next" is for backward compatibility only
tags: |
pykmsorg/py-kms:next
ghcr.io/py-kms-organization/py-kms:next
pykmsorg/py-kms:next-full
ghcr.io/py-kms-organization/py-kms:next-full
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 }}
BUILD_REFERENCE=${{ github.ref_name }}
- name: Build (minimal)
uses: docker/build-push-action@v6
with:
context: .
file: ./docker/docker-py3-kms-minimal/Dockerfile
platforms: linux/amd64,linux/386,linux/arm64/v8,linux/arm/v7,linux/arm/v6
push: true
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
# the tag "latest-next" and "minimal-next" are for backward compatibility only
tags: |
pykmsorg/py-kms:next-minimal
ghcr.io/py-kms-organization/py-kms:next-minimal
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 }}
BUILD_REFERENCE=${{ github.ref_name }}
62 changes: 62 additions & 0 deletions .github/workflows/bake_to_version.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
name: Build version tags

on:
workflow_dispatch:
push:
tags:
- "v*"

jobs:
bake-latest:
runs-on: ubuntu-latest
permissions:
packages: write
contents: read
steps:
- name: Checkout
uses: actions/checkout@v6
- name: Docker Setup QEMU
uses: docker/setup-qemu-action@v3
with:
platforms: all
- name: Docker Setup Buildx
uses: docker/setup-buildx-action@v3
- name: Login to DockerHub
uses: docker/login-action@v3
with:
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_PASSWORD }}
- name: Login to GitHub Container Registry
uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Build (full)
uses: docker/build-push-action@v6
with:
context: .
file: ./docker/docker-py3-kms/Dockerfile
platforms: linux/amd64,linux/386,linux/arm64/v8,linux/arm/v7,linux/arm/v6
push: true
tags: |
pykmsorg/py-kms:${{ github.ref_name }}-full
ghcr.io/py-kms-organization/py-kms:${{ github.ref_name }}-full
build-args: |
BUILD_COMMIT=${{ github.sha }}
BUILD_REFERENCE=${{ github.ref_name }}
- name: Build (minimal)
uses: docker/build-push-action@v6
with:
context: .
file: ./docker/docker-py3-kms-minimal/Dockerfile
platforms: linux/amd64,linux/386,linux/arm64/v8,linux/arm/v7,linux/arm/v6
push: true
tags: |
pykmsorg/py-kms:${{ github.ref_name }}
ghcr.io/py-kms-organization/py-kms:${{ github.ref_name }}
pykmsorg/py-kms:${{ github.ref_name }}-minimal
ghcr.io/py-kms-organization/py-kms:${{ github.ref_name }}-minimal
build-args: |
BUILD_COMMIT=${{ github.sha }}
BUILD_REFERENCE=${{ github.ref_name }}
27 changes: 27 additions & 0 deletions .github/workflows/test_basic_client.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
name: "Test: Basic Client"

on:
workflow_dispatch:
push:

jobs:
run-test:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v5
- name: Set up Python
uses: actions/setup-python@v6
with:
python-version: "3.11"
- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install -r requirements.txt
- name: Run tests
run: |
cd py-kms; timeout 30 python3 pykms_Server.py -F STDOUT -s ./pykms_database.db &
sleep 5
python3 pykms_Client.py -F STDOUT # fresh client
python3 pykms_Client.py -F STDOUT -c 174f5409-0624-4ce3-b209-adde1091956b # (maybe) existing client
python3 pykms_Client.py -F STDOUT -c 174f5409-0624-4ce3-b209-adde1091956b # now-for-sure existing client
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
name: Test-Build Docker Image
name: "Test: Build Docker Image"

on:
workflow_dispatch:
Expand All @@ -9,12 +9,12 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v5
- name: Set up QEMU
uses: actions/checkout@v6
- name: Docker Setup QEMU
uses: docker/setup-qemu-action@v3
with:
platforms: all
- name: Set up Docker Buildx
- name: Docker Setup Buildx
uses: docker/setup-buildx-action@v3
- name: Build (full)
uses: docker/build-push-action@v6
Expand All @@ -25,7 +25,7 @@ jobs:
push: false
build-args: |
BUILD_COMMIT=${{ github.sha }}
BUILD_BRANCH=${{ github.ref_name }}
BUILD_REFERENCE=${{ github.ref_name }}
- name: Build (minimal)
uses: docker/build-push-action@v6
with:
Expand All @@ -35,4 +35,4 @@ jobs:
push: false
build-args: |
BUILD_COMMIT=${{ github.sha }}
BUILD_BRANCH=${{ github.ref_name }}
BUILD_REFERENCE=${{ github.ref_name }}
42 changes: 15 additions & 27 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,48 +1,36 @@
# Readme
# 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)
![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/main)
![docker-pulls](https://img.shields.io/docker/pulls/pykmsorg/py-kms)
![read-the-docs](https://img.shields.io/readthedocs/py-kms)
***

_Keep in mind that this project is not intended for production use. Feel free to use it to test your own systems or maybe even learn something from the protocol structure. :)_
_Keep in mind that this project is not intended for production use. Feel free to use it to test your own systems or maybe even learn something from the protocol structure._ 😉

## History
_py-kms_ is a port of node-kms created by [cyrozap](http://forums.mydigitallife.info/members/183074-markedsword), which is a port of either the C#, C++, or .NET implementations of KMS Emulator. The original version was written by [CODYQX4](http://forums.mydigitallife.info/members/89933-CODYQX4) and is derived from the reverse-engineered code of Microsoft's official KMS.
This version of _py-kms_ is for itself a fork of the original implementation by [SystemRage](https://github.com/SystemRage/py-kms), which was abandoned early 2021.

### What is with version `1.0.0`?
Semantic versioning is now being used in this project, so checkout the [GitHub Releases](https://github.com/Py-KMS-Organization/py-kms/releases). Before, a `CHANGELOG.md` file was used to track changes, but got abandoned over time. Its content got moved into the [Historic Releases](docs/Historic%20Releases.md) document for reference.

## Features
- Responds to `v4`, `v5`, and `v6` KMS requests.
- Supports activating:
- Windows Vista
- Windows 7
- Windows 8
- Windows 8.1
- Windows 10 ( 1511 / 1607 / 1703 / 1709 / 1803 / 1809 )
- Windows 10 ( 1903 / 1909 / 20H1, 20H2, 21H1, 21H2 )
- Windows 11 ( 21H2 )
- Windows Server 2008
- Windows Server 2008 R2
- Windows Server 2012
- Windows Server 2012 R2
- Windows Server 2016
- Windows Server 2019
- Windows Server 2022
- Microsoft Office 2010 ( Volume License )
- Microsoft Office 2013 ( Volume License )
- Microsoft Office 2016 ( Volume License )
- Microsoft Office 2019 ( Volume License )
- Microsoft Office 2021 ( Volume License )
- It's written in Python (tested with Python 3.10.1).
- Supports activating [a lot of products](docs/Keys.md), so checkout the docs for more information.
- It's written in Python.
- Supports execution by `Docker`, `systemd` and many more...
- Uses `sqlite` for persistent data storage (with a simple web-based explorer).

## Documentation
The wiki has been completly reworked and is now available on [readthedocs.io](https://py-kms.readthedocs.io/en/latest/). It should provide you all the necessary information about how to setup and to use _py-kms_ , all without clumping this readme. The documentation also houses more details about activation with _py-kms_ and how to get GVLK keys.
The wiki has been completely reworked and is now available on [readthedocs.io](https://py-kms.readthedocs.io/en/latest/). It should provide you all the necessary information about how to setup and to use _py-kms_, all without clumping this readme. The documentation also houses more details about the activation procedure with _py-kms_ and how to get GVLK keys.

## Quick start
- To start the server, execute `python3 pykms_Server.py [IPADDRESS] [PORT]`, the default _IPADDRESS_ is `::` ( all interfaces ) and the default _PORT_ is `1688`. Note that both the address and port are optional. It's allowed to use IPv4 and IPv6 addresses. If you have a IPv6-capable dual-stack OS, a dual-stack socket is created when using a IPv6 address. **In case your OS does not support IPv6, make sure to explicitly specify the legacy IPv4 of `0.0.0.0`!**
- To start the server, execute `python3 pykms_Server.py [IPADDRESS] [PORT]`, the default _IPADDRESS_ is `::` ( all interfaces ) and the default _PORT_ is `1688`.
- Note that both the address and port are optional.
- It's allowed to use IPv4 and IPv6 addresses.
- If you have an IPv6-capable dual-stack OS, a dual-stack socket is created when using a IPv6 address.
- **[In case your OS does not support IPv6](https://github.com/Py-KMS-Organization/py-kms/issues/108), make sure to explicitly specify the legacy IPv4 of `0.0.0.0`!**
- To start the server automatically using Docker, execute `docker run -d --name py-kms --restart always -p 1688:1688 ghcr.io/py-kms-organization/py-kms`.
- To show the help pages type: `python3 pykms_Server.py -h` and `python3 pykms_Client.py -h`.

Expand Down
11 changes: 5 additions & 6 deletions docker/docker-py3-kms-minimal/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ ENV LCID=1033
ENV CLIENT_COUNT=26
ENV ACTIVATION_INTERVAL=120
ENV RENEWAL_INTERVAL=10080
ENV HWID RANDOM
ENV HWID=RANDOM
ENV LOGLEVEL=INFO
ENV LOGFILE=STDOUT
ENV LOGSIZE=""
Expand All @@ -36,11 +36,10 @@ COPY docker/start.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 {} ';'
RUN find /home/py-kms -type f -print -exec chmod 444 {} ';' && \
find /home/py-kms -type d -print -exec chmod 555 {} ';' && \
chown root: -R /home/py-kms && \
chown py-kms: /home/py-kms

WORKDIR /home/py-kms

Expand Down
Loading
Loading