pull/15/merge
Laurence Luo 2024-09-23 06:53:33 +00:00 committed by GitHub
commit eb99d42fdd
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
7 changed files with 309 additions and 122 deletions

View File

@ -1,4 +1,4 @@
name: ci name: Docker Image CI
on: on:
push: push:
@ -9,23 +9,56 @@ jobs:
docker: docker:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
-
name: Checkout
uses: actions/checkout@v4
-
name: Docker meta
id: meta
uses: docker/metadata-action@v5
with:
# list of Docker images to use as base name for tags
images: |
${{ secrets.DOCKERHUB_USERNAME }}/mobaxterm-genkey
ghcr.io/${{ github.actor }}/mobaxterm-genkey
# generate Docker tags based on the following events/attributes
tags: |
type=schedule
type=ref,event=branch
type=ref,event=pr
type=semver,pattern={{version}}
type=semver,pattern={{major}}.{{minor}}
type=semver,pattern={{major}}
type=sha
- -
name: Set up QEMU name: Set up QEMU
uses: docker/setup-qemu-action@v1 uses: docker/setup-qemu-action@v3
- -
name: Set up Docker Buildx name: Set up Docker Buildx
uses: docker/setup-buildx-action@v1 uses: docker/setup-buildx-action@v3
- -
name: Login to DockerHub name: Login to DockerHub
uses: docker/login-action@v1 uses: docker/login-action@v3
with: with:
username: ${{ secrets.DOCKERHUB_USERNAME }} username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }} password: ${{ secrets.DOCKERHUB_TOKEN }}
-
name: Log in to the Container registry
uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- -
name: Build and push name: Build and push
id: docker_build id: docker_build
uses: docker/build-push-action@v2 uses: docker/build-push-action@v5
with: with:
push: true push: true
file: Dockerfile context: .
tags: ${{ github.repository_owner }}/mobaxterm-genkey:latest file: ./Dockerfile
platforms: linux/amd64,linux/arm64
tags: |
${{ secrets.DOCKERHUB_USERNAME }}/mobaxterm-genkey:latest
ghcr.io/${{ github.actor }}/mobaxterm-genkey:latest
${{ steps.meta.outputs.tags }}

1
.gitignore vendored Normal file
View File

@ -0,0 +1 @@
**/.idea/**

View File

@ -1,4 +1,4 @@
FROM python:3.6-slim FROM python:3.12-alpine
MAINTAINER malaohu <tua@live.cn> MAINTAINER malaohu <tua@live.cn>

View File

@ -1,33 +1,50 @@
# MobaXterm-GenKey # MobaXterm-GenKey (Docker)
你懂的!!
## 演示地址 🔗 For the static web app version, see [MobaXterm-GenKey-Web](https://github.com/lzcapp/MobaXterm-GenKey-Web).
http://192.99.11.204:5000/
![GitHub Actions Workflow Status](https://img.shields.io/github/actions/workflow/status/lzcapp/MobaXterm-GenKey/main.yml?style=for-the-badge)
&ensp; ![Docker Image Version](https://img.shields.io/docker/v/seeleo/mobaxterm-genkey?style=for-the-badge)
&ensp; ![Docker Image Size](https://img.shields.io/docker/image-size/seeleo/mobaxterm-genkey?style=for-the-badge) &ensp; ![Website](https://img.shields.io/website?url=https%3A%2F%2Fmobaxterm.seeleo.com%2F&style=for-the-badge&label=mobaxterm.seeleo.com)
**FOR EDUCATIONAL AND TESTING PURPOSE ONLY**
## Demo
- [mobaxterm.seeleo.com](https://mobaxterm.seeleo.com/)
## Local
**Python 3** Required
## 本地启动
需要安装Python3!!!
``` ```
pip install --no-cache-dir -r requirements.txt pip install --no-cache-dir -r requirements.txt
python app.py python app.py
``` ```
## Docker ## Docker
### Docker Hub
``` ```
docker pull malaohu/mobaxterm-genkey docker pull seeleo/mobaxterm-genkey:latest
docker run -d -p 5000:5000 malaohu/mobaxterm-genkey docker run -d -p 5000:5000 seeleo/mobaxterm-genkey:latest
``` ```
## 使用方法 ### Container Registry (GitHub)
访问IP:5000
![image](https://user-images.githubusercontent.com/8140841/116803404-e94c8300-ab49-11eb-83db-ad0246ebedd3.png)
### 激活方式 ```
直接放到软件目录即可! docker pull ghcr.io/lzcapp/mobaxterm-genkey:latest
docker run -d -p 5000:5000 ghcr.io/lzcapp/mobaxterm-genkey:latest
```
## Screenshot
![1](https://github.com/malaohu/MobaXterm-GenKey/assets/12462465/fa319fe6-b75c-404f-b6fb-59290cda0d66)
![2](https://github.com/malaohu/MobaXterm-GenKey/assets/12462465/ea5387f5-144a-4b1c-a8a8-0847a0912223)
核心内容来自https://github.com/flygon2018/MobaXterm-keygen ## Credits
详细介绍文章https://51.ruyo.net/17008.html
> - https://github.com/flygon2018/MobaXterm-keygen
> - https://github.com/malaohu/MobaXterm-GenKey
> - https://51.ruyo.net/17008.html

76
app.py
View File

@ -1,16 +1,19 @@
#/usr/bin/env python3 # /usr/bin/env python3
import os, sys, zipfile import os
from flask import Flask, request, send_file
import os.path import os.path
import zipfile
from flask import Flask, request, send_file
app = Flask(__name__) app = Flask(__name__)
VariantBase64Table = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=' VariantBase64Table = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/='
VariantBase64Dict = { i : VariantBase64Table[i] for i in range(len(VariantBase64Table)) } VariantBase64Dict = {i: VariantBase64Table[i] for i in range(len(VariantBase64Table))}
VariantBase64ReverseDict = { VariantBase64Table[i] : i for i in range(len(VariantBase64Table)) } VariantBase64ReverseDict = {VariantBase64Table[i]: i for i in range(len(VariantBase64Table))}
def VariantBase64Encode(bs : bytes):
def VariantBase64Encode(bs: bytes):
result = b'' result = b''
blocks_count, left_bytes = divmod(len(bs), 3) blocks_count, left_bytes = divmod(len(bs), 3)
@ -38,7 +41,8 @@ def VariantBase64Encode(bs : bytes):
result += block.encode() result += block.encode()
return result return result
def VariantBase64Decode(s : str):
def VariantBase64Decode(s: str):
result = b'' result = b''
blocks_count, left_bytes = divmod(len(s), 4) blocks_count, left_bytes = divmod(len(s), 4)
@ -65,42 +69,48 @@ def VariantBase64Decode(s : str):
else: else:
raise ValueError('Invalid encoding.') raise ValueError('Invalid encoding.')
def EncryptBytes(key : int, bs : bytes):
def EncryptBytes(key: int, bs: bytes):
result = bytearray() result = bytearray()
for i in range(len(bs)): for i in range(len(bs)):
result.append(bs[i] ^ ((key >> 8) & 0xff)) result.append(bs[i] ^ ((key >> 8) & 0xff))
key = result[-1] & key | 0x482D key = result[-1] & key | 0x482D
return bytes(result) return bytes(result)
def DecryptBytes(key : int, bs : bytes):
def DecryptBytes(key: int, bs: bytes):
result = bytearray() result = bytearray()
for i in range(len(bs)): for i in range(len(bs)):
result.append(bs[i] ^ ((key >> 8) & 0xff)) result.append(bs[i] ^ ((key >> 8) & 0xff))
key = bs[i] & key | 0x482D key = bs[i] & key | 0x482D
return bytes(result) return bytes(result)
class LicenseType: class LicenseType:
Professional = 1 Professional = 1
Educational = 3 Educational = 3
Persional = 4 Personal = 4
def GenerateLicense(Type : LicenseType, Count : int, UserName : str, MajorVersion : int, MinorVersion):
assert(Count >= 0) def GenerateLicense(Type: int, Count: int, UserName: str, MajorVersion: int, MinorVersion):
LicenseString = '%d#%s|%d%d#%d#%d3%d6%d#%d#%d#%d#' % (Type, assert (Count >= 0)
UserName, MajorVersion, MinorVersion, LicenseString = '%d#%s|%d%d#%d#%d3%d6%d#%d#%d#%d#' % (
Count, Type,
MajorVersion, MinorVersion, MinorVersion, UserName, MajorVersion, MinorVersion,
0, # Unknown Count,
0, # No Games flag. 0 means "NoGames = false". But it does not work. MajorVersion, MinorVersion, MinorVersion,
0) # No Plugins flag. 0 means "NoPlugins = false". But it does not work. 0, # Unknown
0, # No Games flag. 0 means "NoGames = false". But it does not work.
0 # No Plugins flag. 0 means "NoPlugins = false". But it does not work.
)
EncodedLicenseString = VariantBase64Encode(EncryptBytes(0x787, LicenseString.encode())).decode() EncodedLicenseString = VariantBase64Encode(EncryptBytes(0x787, LicenseString.encode())).decode()
FileName = EncodedLicenseString.replace('/','').replace('\\','') FileName = EncodedLicenseString.replace('/', '').replace('\\', '')
with zipfile.ZipFile(FileName, 'w') as f: with zipfile.ZipFile(FileName, 'w') as f:
f.writestr('Pro.key', data = EncodedLicenseString) f.writestr('Pro.key', data=EncodedLicenseString)
return FileName return FileName
#@app.route('/gen') # @app.route('/gen')
def get_lc(): def get_lc():
name = request.args.get('name', '') name = request.args.get('name', '')
version = request.args.get('ver', '') version = request.args.get('ver', '')
@ -115,14 +125,17 @@ def get_lc():
return lc return lc
#@app.route('/download/<lc>') # @app.route('/download/<lc>')
def download_lc(lc): def download_lc(lc):
if lc and len(lc) > 5 and os.path.exists('./' + lc): if lc and len(lc) > 5 and os.path.exists('./' + lc):
return send_file(lc, return send_file(
as_attachment=True, lc,
attachment_filename='Custom.mxtpro') None,
True,
'Custom.mxtpro'
)
else: else:
return "请检查用户名版本号是否正确!" return "请检查用户名版本号是否正确!"
@app.route('/gen') @app.route('/gen')
@ -136,8 +149,9 @@ def index():
return send_file('index.html') return send_file('index.html')
if __name__ == '__main__': if __name__ == '__main__':
app.run(host='0.0.0.0', port=5000, debug=False) app.run(
'0.0.0.0',
5000,
False
)

View File

@ -1,73 +1,194 @@
<!DOCTYPE html> <!DOCTYPE html>
<html> <html lang="en">
<head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>MobaXterm Keygen</title> <head>
<title>MobaXterm GenKey</title>
<link href="https://fonts.googleapis.cnpmjs.org/css?family=Roboto:300,400,500,700" rel="stylesheet"> <link href="https://fonts.googleapis.cnpmjs.org/css?family=Roboto:300,400,500,700" rel="stylesheet">
<style> <style>
html, body { body {
display: flex; display: flex;
justify-content: center; justify-content: center;
font-family: Roboto, Arial, sans-serif; align-items: center;
font-size: 15px; height: 100vh;
} margin: 0;
form { }
border: 5px solid #f1f1f1;
} form {
input[type=text], input[type=text] { width: 350px; /* Set the width of the form */
width: 100%; padding: 20px;
padding: 16px 8px; border: 1px solid #ccc;
margin: 8px 0; border-radius: 5px;
display: inline-block; background: #f5f5f5;
border: 1px solid #ccc; }
box-sizing: border-box;
} h1 {
button { color: #303F9F;
background-color: #8ebf42; text-justify: newspaper;
color: white; text-align: justify;
padding: 14px 0; margin-bottom: 20px;
margin: 10px 0; }
border: none;
cursor: grabbing; .container {
width: 100%; margin-top: 10px;
} margin-bottom: 10px;
h1 { }
text-align:center;
font-size:18; button {
} display: block;
button:hover { width: 100%;
opacity: 0.8; padding: 13px;
} color: white;
.formcontainer { border: none;
text-align: left; border-radius: 5px;
margin: 24px 50px 12px; cursor: pointer;
} margin: 5px 0 20px;
.container { font-size: 15px;
padding: 16px 0; }
text-align: left;
} button:hover {
.github { background-color: #007bff;
padding: 16px 0; }
text-align: center;
} .github {
text-align: center;
}
html, body {
display: flex;
justify-content: center;
font-family: Roboto, Arial, sans-serif;
font-size: 15px;
background-color: #2b2b2b;
color: #212121;
}
form {
border: 5px solid #f1f1f1;
}
input[type=text], input[type=text] {
width: 100%;
padding: 16px 8px;
margin: 10px 0 10px;
display: inline-block;
border: 1px solid #ccc;
box-sizing: border-box;
}
#space {
height: 15px;
}
h1 {
text-align: center;
}
button:hover {
opacity: 0.8;
}
.container {
padding: 16px 0;
text-align: left;
}
.github {
padding: 20px 0 0;
text-align: right;
}
.github span {
color: #212121;
font-size: smaller;
}
.github span a {
color: #242424;
font-weight: bold;
}
.github span a img {
height: 18px;
padding-bottom: 3px;
vertical-align: middle;
}
#btnReset {
margin-top: 15px;
background-color: #757575;
}
#btnSubmit {
background-color: #3F51B5;
}
#lblName, #lblVersion {
font-weight: bold;
}
#inputName, #inputVersion {
height: 35px;
margin-top: 10px;
border: 1px solid #ccc;
padding: 5px 5px 5px 10px;
}
#inputName {
height: 47px;
color: #333;
}
#inputVersion {
width: 334px;
height: 35px;
}
</style> </style>
</head> </head>
<body> <body>
<form action="./gen" mothod="get"> <form action="./gen" mothod="get">
<h1>MobaXterm Keygen</h1> <h1>MobaXterm&ensp;GenKey</h1>
<div class="formcontainer"></div> <div class="container">
<hr/> <label for="name" id="lblName">Name</label>
<div class="container"> <label style="width: 350px; display: block;">
<label for="name"><strong>Name</strong></label> <input name="name" id="inputName" placeholder="Please enter name" required type="text">
<input type="text" placeholder="Enter name" name="name" required>
<label for="ver"><strong>Version</strong></label>
<input type="text" placeholder="Enter version: (21.1)" name="ver" required>
</div>
<button type="submit">Gen!</button>
<div class="github">
<label style="padding-left: 15px">
</label> </label>
<span><a style="text-decoration: none;" href="https://github.com/malaohu/MobaXterm-GenKey">View on GitHub</a><img src="https://github.githubassets.com/favicons/favicon.svg" height="16px"></span> <div id="space"></div>
</div> <label for="ver" id="lblVersion">Version</label>
</form> <label style="width: 350px; display: block;">
</body> <input name="ver" id="inputVersion" type="number" placeholder="Please enter version" step="0.1" min="0" />
</label>
</div>
<button id="btnReset" type="reset">Reset</button>
<button id="btnSubmit" type="submit">Generate</button>
<div class="github">
<span>
<a href="https://github.com/lzcapp/MobaXterm-GenKey" style="text-decoration: none;">
<img src="https://github.githubassets.com/favicons/favicon.svg" alt="GitHub">
MobaXterm-GenKey
</a>
<span id="forked">forked from</span>
<a href="https://github.com/malaohu/MobaXterm-GenKey" style="text-decoration: none;">
malaohu
</a>
</span>
</div>
</form>
<script>
const userLanguage = navigator.language || navigator.userLanguage;
const languageCode = userLanguage.substring(0, 2);
console.log(languageCode);
if (languageCode === "zh") {
document.documentElement.lang = "zh";
document.getElementById("lblName").innerHTML = "用户名"
document.getElementById("inputName").placeholder = "请输入用户名"
document.getElementById("lblVersion").innerHTML = "版本"
document.getElementById("inputVersion").placeholder = "请输入版本"
document.getElementById("btnReset").innerHTML = "清空"
document.getElementById("btnSubmit").innerHTML = "生成"
document.getElementById("forked").innerHTML = "分叉自"
}
</script>
</body>
</html> </html>

View File

@ -1 +1,2 @@
Flask==2.1.0 Flask==3.0.3
Werkzeug==3.0.3