Merge branch 'master' into feature/helm-chart

This commit is contained in:
Matthew Beckett 2021-10-22 13:08:10 +01:00
commit b51a17a17f
13 changed files with 148 additions and 143 deletions

View file

@ -19,7 +19,7 @@ This version of _py-kms_ is for itself a fork of the original implementation by
- Windows 8 - Windows 8
- Windows 8.1 - Windows 8.1
- Windows 10 ( 1511 / 1607 / 1703 / 1709 / 1803 / 1809 ) - Windows 10 ( 1511 / 1607 / 1703 / 1709 / 1803 / 1809 )
- Windows 10 ( 1903 / 1909 / 20H1 ) - Windows 10 ( 1903 / 1909 / 20H1, 20H2, 21H1 )
- Windows Server 2008 - Windows Server 2008
- Windows Server 2008 R2 - Windows Server 2008 R2
- Windows Server 2012 - Windows Server 2012
@ -41,7 +41,7 @@ The wiki has been completly reworked and is now available on [readthedocs.com](h
## Quick start ## Quick start
- To start the server, execute `python3 pykms_Server.py [IPADDRESS] [PORT]`, the default _IPADDRESS_ is `0.0.0.0` ( 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. - To start the server, execute `python3 pykms_Server.py [IPADDRESS] [PORT]`, the default _IPADDRESS_ is `0.0.0.0` ( 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.
- To start the server automatically using Docker, execute `docker run -d --name py-kms --restart always -p 1688:1688 pykmsorg/py-kms`. - 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`. - To show the help pages type: `python3 pykms_Server.py -h` and `python3 pykms_Client.py -h`.
- For launching _py-kms_ GUI make the file `pykms_Server.py` executable with `chmod +x /path/to/folder/py-kms/pykms_Server.py`, then simply run `pykms_Server.py` by double-clicking. - For launching _py-kms_ GUI make the file `pykms_Server.py` executable with `chmod +x /path/to/folder/py-kms/pykms_Server.py`, then simply run `pykms_Server.py` by double-clicking.

View file

@ -2,17 +2,17 @@
FROM alpine:3.12 FROM alpine:3.12
ENV IP 0.0.0.0 ENV IP 0.0.0.0
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 /var/log/pykms_logserver.log ENV LOGFILE /dev/stdout
ENV LOGSIZE "" ENV LOGSIZE ""
COPY ./py-kms /home/py-kms COPY ./py-kms /home/py-kms
@ -25,12 +25,18 @@ RUN apk add --no-cache --update \
python3-tkinter \ python3-tkinter \
sqlite-libs \ sqlite-libs \
py3-pip \ py3-pip \
tzdata \
build-base python3-dev && \ build-base python3-dev && \
pip3 install peewee tzlocal && \ pip3 install peewee tzlocal pytz && \
apk del git build-base python3-dev apk del git build-base python3-dev
# Fix undefined timezone, in case the user did not mount the /etc/localtime
RUN cp /usr/share/zoneinfo/UTC /etc/localtime
WORKDIR /home/py-kms WORKDIR /home/py-kms
EXPOSE ${PORT}/tcp EXPOSE ${PORT}/tcp
ENTRYPOINT /usr/bin/python3 pykms_Server.py ${IP} ${PORT} -l ${LCID} -c ${CLIENT_COUNT} -a ${ACTIVATION_INTERVAL} -r ${RENEWAL_INTERVAL} -w ${HWID} -V ${LOGLEVEL} -F ${LOGFILE} COPY docker/entrypoint.py /usr/bin/entrypoint.py
RUN chmod a+x /usr/bin/entrypoint.py
ENTRYPOINT ["/usr/bin/python3", "/usr/bin/entrypoint.py"]

View file

@ -1,19 +1,19 @@
FROM alpine:3.12 FROM alpine:3.12
ENV IP 0.0.0.0 ENV IP 0.0.0.0
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 SQLITE false ENV SQLITE true
ENV HWID "364F463A8863D35F" ENV SQLITE_PORT 8080
ENV LOGLEVEL ERROR ENV HWID RANDOM
ENV LOGFILE /var/log/pykms_logserver.log ENV LOGLEVEL INFO
ENV LOGSIZE "" ENV LOGFILE /dev/stdout
ENV LOGSIZE ""
COPY docker/docker-py3-kms/start.sh /usr/bin/start.sh
COPY ./py-kms /home/py-kms COPY ./py-kms /home/py-kms
RUN apk add --no-cache --update \ RUN apk add --no-cache --update \
@ -25,16 +25,25 @@ RUN apk add --no-cache --update \
python3-tkinter \ python3-tkinter \
sqlite-libs \ sqlite-libs \
py3-pip \ py3-pip \
tzdata \
build-base python3-dev && \ build-base python3-dev && \
git clone https://github.com/coleifer/sqlite-web.git /tmp/sqlite_web && \ git clone https://github.com/coleifer/sqlite-web.git /tmp/sqlite_web && \
cd /tmp/sqlite_web && \
git checkout 2e7c85da3d37f80074ed3ae39b5851069b4f301c && \
cd / && \
mv /tmp/sqlite_web/sqlite_web /home/ && \ mv /tmp/sqlite_web/sqlite_web /home/ && \
rm -rf /tmp/sqlite_web && \ rm -rf /tmp/sqlite_web && \
pip3 install peewee tzlocal pysqlite3 && \ pip3 install peewee tzlocal pytz pysqlite3 && \
chmod a+x /usr/bin/start.sh && \
apk del git build-base python3-dev apk del git build-base python3-dev
# Fix undefined timezone, in case the user did not mount the /etc/localtime
RUN cp /usr/share/zoneinfo/UTC /etc/localtime
WORKDIR /home/py-kms WORKDIR /home/py-kms
EXPOSE ${SQLITE_PORT}/tcp
EXPOSE ${PORT}/tcp EXPOSE ${PORT}/tcp
ENTRYPOINT ["/usr/bin/start.sh"] COPY docker/entrypoint.py /usr/bin/entrypoint.py
RUN chmod a+x /usr/bin/entrypoint.py
ENTRYPOINT ["/usr/bin/python3", "/usr/bin/entrypoint.py"]

View file

@ -1 +0,0 @@
docker build -t pykms/pykms:py3-kms ../../ --file ./Dockerfile

View file

@ -1,16 +0,0 @@
docker stop py3-kms
docker rm py3-kms
docker run -d --name py3-kms \
-t \
-p 8080:8080 \
-p 1688:1688 \
-e IP=0.0.0.0 \
-e PORT=1688 \
-e SQLITE=true \
-e HWID=RANDOM \
-e LOGLEVEL=INFO \
-e LOGFILE=/var/log/pykms_logserver.log \
-e LOGSIZE=2 \
-v /etc/localtime:/etc/localtime:ro \
-v /var/log:/var/log:rw \
--restart unless-stopped pykms/pykms:py3-kms

View file

@ -1,50 +0,0 @@
#!/bin/bash
cd /home/py-kms
if [ "$SQLITE" == false ];
then
if [ "$EPID" == "" ];
then
if [ "$LOGSIZE" == "" ];
then
/usr/bin/python3 pykms_Server.py ${IP} ${PORT} -l ${LCID} -c ${CLIENT_COUNT} -a ${ACTIVATION_INTERVAL} -r ${RENEWAL_INTERVAL} -w ${HWID} -V ${LOGLEVEL} -F ${LOGFILE}
else
/usr/bin/python3 pykms_Server.py ${IP} ${PORT} -l ${LCID} -c ${CLIENT_COUNT} -a ${ACTIVATION_INTERVAL} -r ${RENEWAL_INTERVAL} -w ${HWID} -V ${LOGLEVEL} -F ${LOGFILE} -S ${LOGSIZE}
fi
else
if [ "$LOGSIZE" == "" ];
then
/usr/bin/python3 pykms_Server.py ${IP} ${PORT} -e ${EPID} -l ${LCID} -c ${CLIENT_COUNT} -a ${ACTIVATION_INTERVAL} -r ${RENEWAL_INTERVAL} -w ${HWID} -V ${LOGLEVEL} -F ${LOGFILE}
else
/usr/bin/python3 pykms_Server.py ${IP} ${PORT} -e ${EPID} -l ${LCID} -c ${CLIENT_COUNT} -a ${ACTIVATION_INTERVAL} -r ${RENEWAL_INTERVAL} -w ${HWID} -V ${LOGLEVEL} -F ${LOGFILE} -S ${LOGSIZE}
fi
fi
else
if [ "$EPID" == "" ];
then
if [ "$LOGSIZE" == "" ];
then
/bin/bash -c "/usr/bin/python3 pykms_Server.py ${IP} ${PORT} -l ${LCID} -c ${CLIENT_COUNT} -a ${ACTIVATION_INTERVAL} -r ${RENEWAL_INTERVAL} -s ${PWD}/pykms_database.db -w ${HWID} -V ${LOGLEVEL} -F ${LOGFILE} &"
sleep 5
/usr/bin/python3 pykms_Client.py ${IP} ${PORT} -m Windows10 &
/usr/bin/python3 /home/sqlite_web/sqlite_web.py -H ${IP} -x ${PWD}/pykms_database.db --read-only
else
/bin/bash -c "/usr/bin/python3 pykms_Server.py ${IP} ${PORT} -l ${LCID} -c ${CLIENT_COUNT} -a ${ACTIVATION_INTERVAL} -r ${RENEWAL_INTERVAL} -s ${PWD}/pykms_database.db -w ${HWID} -V ${LOGLEVEL} -F ${LOGFILE} -S ${LOGSIZE} &"
sleep 5
/usr/bin/python3 pykms_Client.py ${IP} ${PORT} -m Windows10 &
/usr/bin/python3 /home/sqlite_web/sqlite_web.py -H ${IP} -x ${PWD}/pykms_database.db --read-only
fi
else
if [ "$LOGSIZE" == "" ];
then
/bin/bash -c "/usr/bin/python3 pykms_Server.py ${IP} ${PORT} -e ${EPID} -l ${LCID} -c ${CLIENT_COUNT} -a ${ACTIVATION_INTERVAL} -r ${RENEWAL_INTERVAL} -s ${PWD}/pykms_database.db -w ${HWID} -V ${LOGLEVEL} -F ${LOGFILE} &"
sleep 5
/usr/bin/python3 pykms_Client.py ${IP} ${PORT} -m Windows10 &
/usr/bin/python3 /home/sqlite_web/sqlite_web.py -H ${IP} -x ${PWD}/pykms_database.db --read-only
else
/bin/sh -c "/usr/bin/python3 pykms_Server.py ${IP} ${PORT} -e ${EPID} -l ${LCID} -c ${CLIENT_COUNT} -a ${ACTIVATION_INTERVAL} -r ${RENEWAL_INTERVAL} -s ${PWD}/pykms_database.db -w ${HWID} -V ${LOGLEVEL} -F ${LOGFILE} -S ${LOGSIZE} &"
sleep 5
/usr/bin/python3 pykms_Client.py ${IP} ${PORT} -m Windows10 &
/usr/bin/python3 /home/sqlite_web/sqlite_web.py -H ${IP} -x ${PWD}/pykms_database.db --read-only
fi
fi
fi

57
docker/entrypoint.py Executable file
View file

@ -0,0 +1,57 @@
#!/usr/bin/python3
# This replaces the old start.sh and ensures all arguments are bound correctly from the environment variables...
import os
import time
import subprocess
argumentVariableMapping = {
'-l': 'LCID',
'-c': 'CLIENT_COUNT',
'-a': 'ACTIVATION_INTERVAL',
'-r': 'RENEWAL_INTERVAL',
'-w': 'HWID',
'-V': 'LOGLEVEL',
'-F': 'LOGFILE',
'-S': 'LOGSIZE',
'-e': 'EPID'
}
sqliteWebPath = '/home/sqlite_web/sqlite_web.py'
# Build the command to execute
listenIP = os.environ.get('IP', '0.0.0.0')
listenPort = os.environ.get('PORT', '1688')
command = ['/usr/bin/python3', 'pykms_Server.py', listenIP, listenPort]
for (arg, env) in argumentVariableMapping.items():
if env in os.environ and os.environ.get(env) != '':
command.append(arg)
command.append(os.environ.get(env))
enableSQLITE = os.path.isfile(sqliteWebPath) and os.environ.get('SQLITE', 'false').lower() == 'true'
if enableSQLITE:
print('Storing database file to ' + dbPath)
dbPath = os.path.join('db', 'pykms_database.db')
os.makedirs('db', exist_ok=True)
command.append('-s')
command.append(dbPath)
pykmsProcess = subprocess.Popen(command)
# In case SQLITE is defined: Start the web interface
if enableSQLITE:
time.sleep(5) # The server may take a while to start
if not os.path.isfile(dbPath):
# Start a dummy activation to ensure the database file is created
subprocess.run(['/usr/bin/python3', 'pykms_Client.py', listenIP, listenPort, '-m', 'Windows10', '-n', 'DummyClient', '-c', 'ae3a27d1-b73a-4734-9878-70c949815218'])
sqliteProcess = subprocess.Popen(['/usr/bin/python3', sqliteWebPath, '-H', listenIP, '--read-only', '-x', dbPath, '-p', os.environ.get('SQLITE_PORT', 8080)])
try:
pykmsProcess.wait()
except:
# In case of any error - just shut down
pass
if enableSQLITE:
sqliteProcess.terminate()
pykmsProcess.terminate()

View file

@ -15,10 +15,10 @@ If you wish to get _py-kms_ just up and running without installing any dependenc
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.
```bash ```bash
docker run -d --name py-kms --restart always -p 1688:1688 pykmsorg/py-kms docker run -d --name py-kms --restart always -p 1688:1688 -v /etc/localtime:/etc/localtime:ro ghcr.io/py-kms-organization/py-kms
``` ```
If you just want to use the image and don't want to build them yourself, you can always use the official image at the [Docker Hub](https://hub.docker.com/r/pykmsorg/py-kms) (`pykmsorg/py-kms`). To ensure that you are using always the If you just want to use the image and don't want to build them yourself, you can always use the official image at the [Docker Hub](https://hub.docker.com/r/pykmsorg/py-kms) (`pykmsorg/py-kms`) or [GitHub Container Registry](https://github.com/Py-KMS-Organization/py-kms/pkgs/container/py-kms) (`ghcr.io/py-kms-organization/py-kms`). To ensure that you are using always the
latest version you should check something like [watchtower](https://github.com/containrrr/watchtower) out ! latest version you should check something like [watchtower](https://github.com/containrrr/watchtower) out!
#### Tags #### Tags
There are currently three tags of the image available (select one just by appending `:<tag>` to the image from above): There are currently three tags of the image available (select one just by appending `:<tag>` to the image from above):
@ -37,43 +37,37 @@ _Please note that any architecture other than the classic `amd64` is slightly bi
#### Docker Compose #### Docker Compose
You can use `docker-compose` instead of building and running the Dockerfile, so you do not need to respecify your settings again and again. The following Docker Compose file will deploy the `latest` image with the log into your local directory. You can use `docker-compose` instead of building and running the Dockerfile, so you do not need to respecify your settings again and again. The following Docker Compose file will deploy the `latest` image with the log into your local directory.
Make sure to take a look into the `entrypoint.py` script to see all supported variable mappings!
```yaml ```yaml
version: '3' version: '3'
services: services:
kms: kms:
image: pykmsorg/py-kms:latest image: ghcr.io/py-kms-organization/py-kms:python3
ports: ports:
- 1688:1688 - 1688:1688
- 8080:8080
environment: environment:
- IP=0.0.0.0 - IP=0.0.0.0
- SQLITE=true - SQLITE=true
- HWID=RANDOM - HWID=RANDOM
- LOGLEVEL=INFO - LOGLEVEL=INFO
- LOGSIZE=2 - LOGFILE=/dev/stdout
- LOGFILE=/var/log/pykms_logserver.log
restart: always restart: always
volumes: volumes:
- ./db:/home/py-kms/db
- /etc/localtime:/etc/localtime:ro - /etc/localtime:/etc/localtime:ro
- ./logs:/var/log:rw
``` ```
#### Parameters #### Parameters
Below is a fully expanded run command, detailing all the different supported environment variables to set. For further reference see the [start parameters](Usage.html#docker-environment) for the docker environment. Below is a little bit more extended run command, detailing all the different supported environment variables to set. For further reference see the [start parameters](Usage.html#docker-environment) for the docker environment.
```bash ```bash
docker run -it -d --name py3-kms \ docker run -it -d --name py3-kms \
-p 8080:8080 \ -p 8080:8080 \
-p 1688:1688 \ -p 1688:1688 \
-e IP=0.0.0.0 \
-e PORT=1688 \
-e SQLITE=true \ -e SQLITE=true \
-e HWID=RANDOM \
-e LOGLEVEL=INFO \
-e LOGSIZE=2 \
-e LOGFILE=/var/log/pykms_logserver.log \
-v /etc/localtime:/etc/localtime:ro \ -v /etc/localtime:/etc/localtime:ro \
-v ./logs:/var/log:rw \ --restart unless-stopped ghcr.io/py-kms-organization/py-kms:[TAG]
--restart unless-stopped pykmsorg/py-kms:[TAG]
``` ```
You can omit the `-e SQLITE=...` and `-p 8080:8080` option if you plan to use the `minimal` or `latest` image, which does not include the respective module support. You can omit the `-e SQLITE=...` and `-p 8080:8080` option if you plan to use the `minimal` or `latest` image, which does not include the respective module support.

View file

@ -39,37 +39,37 @@ sometimes even reject it by itself (often due too many uses - in that case try t
| Windows Server 2016 Cloud Storage | `QN4C6-GBJD2-FB422-GHWJK-GJG2R` | | Windows Server 2016 Cloud Storage | `QN4C6-GBJD2-FB422-GHWJK-GJG2R` |
| Windows Server 2016 Azure Core | `VP34G-4NPPG-79JTQ-864T4-R3MQX`<br>`WNCYY-GFBH2-M4WTT-XQ2FP-PG2K9` | | Windows Server 2016 Azure Core | `VP34G-4NPPG-79JTQ-864T4-R3MQX`<br>`WNCYY-GFBH2-M4WTT-XQ2FP-PG2K9` |
### Windows 10 ### Windows 10 & Windows 11
| Product | GVLK | | Product | GVLK |
| --- | --- | | --- | --- |
| Windows 10 Professional Workstation | `NRG8B-VKK3Q-CXVCJ-9G2XF-6Q84J` | | Windows 10/11 Professional Workstation | `NRG8B-VKK3Q-CXVCJ-9G2XF-6Q84J` |
| Windows 10 Professional Workstation N | `9FNHH-K3HBT-3W4TD-6383H-6XYWF` | | Windows 10/11 Professional Workstation N | `9FNHH-K3HBT-3W4TD-6383H-6XYWF` |
| Windows 10 Enterprise G | `YYVX9-NTFWV-6MDM3-9PT4T-4M68B` | | Windows 10/11 Enterprise G | `YYVX9-NTFWV-6MDM3-9PT4T-4M68B` |
| Windows 10 Enterprise G N | `44RPN-FTY23-9VTTB-MP9BX-T84FV` | | Windows 10/11 Enterprise G N | `44RPN-FTY23-9VTTB-MP9BX-T84FV` |
| Windows 10 Enterprise LTSC 2019 | `M7XTQ-FN8P6-TTKYV-9D4CC-J462D` | | Windows 10 Enterprise LTSC 2019 | `M7XTQ-FN8P6-TTKYV-9D4CC-J462D` |
| Windows 10 Enterprise LTSC 2019 N | `92NFX-8DJQP-P6BBQ-THF9C-7CG2H` | | Windows 10 Enterprise LTSC 2019 N | `92NFX-8DJQP-P6BBQ-THF9C-7CG2H` |
| Windows 10 Remote Server | `7NBT4-WGBQX-MP4H7-QXFF8-YP3KX` | | Windows 10/11 Remote Server | `7NBT4-WGBQX-MP4H7-QXFF8-YP3KX` |
| Windows 10 Enterprise for Remote Sessions | `CPWHC-NT2C7-VYW78-DHDB2-PG3GK` | | Windows 10/11 Enterprise for Remote Sessions | `CPWHC-NT2C7-VYW78-DHDB2-PG3GK` |
| Windows 10 S (Lean) | `NBTWJ-3DR69-3C4V8-C26MC-GQ9M6` | | Windows 10 S (Lean) | `NBTWJ-3DR69-3C4V8-C26MC-GQ9M6` |
| Windows 10 Professional | `W269N-WFGWX-YVC9B-4J6C9-T83GX` | | Windows 10/11 Professional | `W269N-WFGWX-YVC9B-4J6C9-T83GX` |
| Windows 10 Professional N | `MH37W-N47XK-V7XM9-C7227-GCQG9`<br>`HMNWJ-V69R6-B2CDC-8P7VT-2373K` | | Windows 10/11 Professional N | `MH37W-N47XK-V7XM9-C7227-GCQG9`<br>`HMNWJ-V69R6-B2CDC-8P7VT-2373K` |
| Windows 10 Professional Education | `6TP4R-GNPTD-KYYHQ-7B7DP-J447Y` | | Windows 10/11 Professional Education | `6TP4R-GNPTD-KYYHQ-7B7DP-J447Y` |
| Windows 10 Professional Education N | `YVWGF-BXNMC-HTQYQ-CPQ99-66QFC` | | Windows 10/11 Professional Education N | `YVWGF-BXNMC-HTQYQ-CPQ99-66QFC` |
| Windows 10 Education | `NW6C2-QMPVW-D7KKK-3GKT6-VCFB2`<br>`F48BJ-8NX82-MRVY9-PF8BW-HMHY2` | | Windows 10/11 Education | `NW6C2-QMPVW-D7KKK-3GKT6-VCFB2`<br>`F48BJ-8NX82-MRVY9-PF8BW-HMHY2` |
| Windows 10 Education N | `2WH4N-8QGBV-H22JP-CT43Q-MDWWJ`<br>`PPWGW-8NW9C-J77Q9-8WHB9-QV64W` | | Windows 10/11 Education N | `2WH4N-8QGBV-H22JP-CT43Q-MDWWJ`<br>`PPWGW-8NW9C-J77Q9-8WHB9-QV64W` |
| Windows 10 Enterprise | `NPPR9-FWDCX-D2C8J-H872K-2YT43`<br>`96YNV-9X4RP-2YYKB-RMQH4-6Q72D`<br>`TN6CM-KCVXP-VVP8X-YVCF7-R9BDH`<br>`3PMKQ-YNVGT-HFJGG-2F4FQ-9D6T7` | | Windows 10/11 Enterprise | `NPPR9-FWDCX-D2C8J-H872K-2YT43`<br>`96YNV-9X4RP-2YYKB-RMQH4-6Q72D`<br>`TN6CM-KCVXP-VVP8X-YVCF7-R9BDH`<br>`3PMKQ-YNVGT-HFJGG-2F4FQ-9D6T7` |
| Windows 10 Enterprise N | `DPH2V-TTNVB-4X9Q3-TJR4H-KHJW4`<br>`WGGHN-J84D6-QYCPR-T7PJ7-X766F` | | Windows 10/11 Enterprise N | `DPH2V-TTNVB-4X9Q3-TJR4H-KHJW4`<br>`WGGHN-J84D6-QYCPR-T7PJ7-X766F` |
| Windows 10 Enterprise S | `H76BG-QBNM7-73XY9-V6W2T-684BJ` | | Windows 10/11 Enterprise S | `H76BG-QBNM7-73XY9-V6W2T-684BJ` |
| Windows 10 Enterprise S N | `X4R4B-NV6WD-PKTVK-F98BH-4C2J8` | | Windows 10/11 Enterprise S N | `X4R4B-NV6WD-PKTVK-F98BH-4C2J8` |
| Windows 10 Enterprise 2015 LTSB | `WNMTR-4C88C-JK8YV-HQ7T2-76DF9` | | Windows 10 Enterprise 2015 LTSB | `WNMTR-4C88C-JK8YV-HQ7T2-76DF9` |
| Windows 10 Enterprise 2015 LTSB N | `2F77B-TNFGY-69QQF-B8YKP-D69TJ`<br>`RW7WN-FMT44-KRGBK-G44WK-QV7YK` | | Windows 10 Enterprise 2015 LTSB N | `2F77B-TNFGY-69QQF-B8YKP-D69TJ`<br>`RW7WN-FMT44-KRGBK-G44WK-QV7YK` |
| Windows 10 Enterprise 2016 LTSB | `DCPHK-NFMTC-H88MJ-PFHPY-QJ4BJ` | | Windows 10 Enterprise 2016 LTSB | `DCPHK-NFMTC-H88MJ-PFHPY-QJ4BJ` |
| Windows 10 Enterprise 2016 LTSB N | `QFFDN-GRT3P-VKWWX-X7T3R-8B639` | | Windows 10 Enterprise 2016 LTSB N | `QFFDN-GRT3P-VKWWX-X7T3R-8B639` |
| Windows 10 Home<br>Windows 10 Core | `TX9XD-98N7V-6WMQ6-BX7FG-H8Q99`<br>`33QT6-RCNYF-DXB4F-DGP7B-7MHX9` | | Windows 10/11 Home<br>Windows 10/11 Core | `TX9XD-98N7V-6WMQ6-BX7FG-H8Q99`<br>`33QT6-RCNYF-DXB4F-DGP7B-7MHX9` |
| Windows 10 Home N<br>Windows 10 Core N | `3KHY7-WNT83-DGQKR-F7HPR-844BM`<br>`CP4KF-NG6TC-9K6QF-P6GTT-H8RBM` | | Windows 10/11 Home N<br>Windows 10/11 Core N | `3KHY7-WNT83-DGQKR-F7HPR-844BM`<br>`CP4KF-NG6TC-9K6QF-P6GTT-H8RBM` |
| Windows 10 Home Single Language<br>Windows 10 Core Single Language | `7HNRX-D7KGG-3K4RQ-4WPJ4-YTDFH`<br>`9HGRW-NH2CQ-XQHJD-YCRWB-6VJV7`<br>`4NX46-6DHCG-MR3PH-9FMCX-3RQ3G` | | Windows 10/11 Home Single Language<br>Windows 10 Core Single Language | `7HNRX-D7KGG-3K4RQ-4WPJ4-YTDFH`<br>`9HGRW-NH2CQ-XQHJD-YCRWB-6VJV7`<br>`4NX46-6DHCG-MR3PH-9FMCX-3RQ3G` |
| Windows 10 Home Country Specific<br>Windows 10 Core Country Specific | `PVMJN-6DFY6-9CCP6-7BKTT-D3WVR`<br>`JN9HR-MH7K4-DBPDD-TFTXF-Q9MMF` | | Windows 10/11 Home Country Specific<br>Windows 10 Core Country Specific | `PVMJN-6DFY6-9CCP6-7BKTT-D3WVR`<br>`JN9HR-MH7K4-DBPDD-TFTXF-Q9MMF` |
### Windows Server 2012 R2 ### Windows Server 2012 R2

View file

@ -230,6 +230,10 @@ ENV RENEWAL_INTERVAL 10080
# Use this flag to store request information from unique clients in an SQLite database. # Use this flag to store request information from unique clients in an SQLite database.
ENV SQLITE false ENV SQLITE false
# TCP-port
# The network port to listen with the web interface on. The default is "8080".
ENV SQLITE_PORT 8080
# hwid # hwid
# Use this flag to specify a HWID. # Use this flag to specify a HWID.
# The HWID must be an 16-character string of hex characters. # The HWID must be an 16-character string of hex characters.

View file

@ -119,19 +119,24 @@ class kmsBase:
# Localize the request time, if module "tzlocal" is available. # Localize the request time, if module "tzlocal" is available.
try: try:
from datetime import datetime
from tzlocal import get_localzone from tzlocal import get_localzone
from pytz.exceptions import UnknownTimeZoneError from pytz.exceptions import UnknownTimeZoneError
try: try:
tz = get_localzone() local_dt = datetime.fromisoformat(str(requestDatetime)).astimezone(get_localzone())
local_dt = tz.localize(requestDatetime)
except UnknownTimeZoneError: except UnknownTimeZoneError:
pretty_printer(log_obj = loggersrv.warning, pretty_printer(log_obj = loggersrv.warning,
put_text = "{reverse}{yellow}{bold}Unknown time zone ! Request time not localized.{end}") put_text = "{reverse}{yellow}{bold}Unknown time zone ! Request time not localized.{end}")
local_dt = requestDatetime local_dt = requestDatetime
except ImportError: except ImportError:
pretty_printer(log_obj = loggersrv.warning, pretty_printer(log_obj = loggersrv.warning,
put_text = "{reverse}{yellow}{bold}Module 'tzlocal' not available ! Request time not localized.{end}") put_text = "{reverse}{yellow}{bold}Module 'tzlocal' or 'pytz' not available ! Request time not localized.{end}")
local_dt = requestDatetime local_dt = requestDatetime
except Exception as e:
# Just in case something else goes wrong
loggersrv.warning('Okay, something went horribly wrong while localizing the request time (proceeding anyways): ' + str(e))
local_dt = requestDatetime
pass
# Activation threshold. # Activation threshold.
# https://docs.microsoft.com/en-us/windows/deployment/volume-activation/activate-windows-10-clients-vamt # https://docs.microsoft.com/en-us/windows/deployment/volume-activation/activate-windows-10-clients-vamt

View file

@ -227,7 +227,7 @@ def logger_create(log_obj, config, mode = 'a'):
log_obj.setLevel(config['loglevel']) log_obj.setLevel(config['loglevel'])
#------------------------------------------------------------------------------------------------------------------------------------------------------------ #------------------------------------------------------------------------------------------------------------------------------------------------------------
def check_dir(path, where, log_obj = None, argument = '-F/--logfile', typefile = '.log'): def check_dir(path, where, log_obj = None, argument = '-F/--logfile'):
filename = os.path.basename(path) filename = os.path.basename(path)
pathname = os.path.dirname(path) pathname = os.path.dirname(path)
extension = os.path.splitext(filename)[1] extension = os.path.splitext(filename)[1]
@ -243,9 +243,6 @@ def check_dir(path, where, log_obj = None, argument = '-F/--logfile', typefile =
pathname = filename pathname = filename
pretty_printer(log_obj = log_obj, where = where, to_exit = True, pretty_printer(log_obj = log_obj, where = where, to_exit = True,
put_text = msg_dir %(argument, pathname)) put_text = msg_dir %(argument, pathname))
elif not extension.lower() == typefile:
pretty_printer(log_obj = log_obj, where = where, to_exit = True,
put_text = msg_fil %(argument, typefile, extension))
def check_logfile(optionlog, defaultlog, where): def check_logfile(optionlog, defaultlog, where):
if not isinstance(optionlog, list): if not isinstance(optionlog, list):

View file

@ -447,7 +447,7 @@ def server_check():
# Check sqlite. # Check sqlite.
if srv_config['sqlite']: if srv_config['sqlite']:
if isinstance(srv_config['sqlite'], str): if isinstance(srv_config['sqlite'], str):
check_dir(srv_config['sqlite'], 'srv', log_obj = loggersrv.error, argument = '-s/--sqlite', typefile = '.db') check_dir(srv_config['sqlite'], 'srv', log_obj = loggersrv.error, argument = '-s/--sqlite')
elif srv_config['sqlite'] is True: elif srv_config['sqlite'] is True:
srv_config['sqlite'] = srv_options['sql']['file'] srv_config['sqlite'] = srv_options['sql']['file']