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:
push:
@ -9,23 +9,56 @@ jobs:
docker:
runs-on: ubuntu-latest
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
uses: docker/setup-qemu-action@v1
uses: docker/setup-qemu-action@v3
-
name: Set up Docker Buildx
uses: docker/setup-buildx-action@v1
uses: docker/setup-buildx-action@v3
-
name: Login to DockerHub
uses: docker/login-action@v1
uses: docker/login-action@v3
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
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
id: docker_build
uses: docker/build-push-action@v2
uses: docker/build-push-action@v5
with:
push: true
file: Dockerfile
tags: ${{ github.repository_owner }}/mobaxterm-genkey:latest
context: .
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>

View File

@ -1,33 +1,50 @@
# MobaXterm-GenKey
你懂的!!
# MobaXterm-GenKey (Docker)
## 演示地址
http://192.99.11.204:5000/
🔗 For the static web app version, see [MobaXterm-GenKey-Web](https://github.com/lzcapp/MobaXterm-GenKey-Web).
![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
python app.py
```
## Docker
### Docker Hub
```
docker pull malaohu/mobaxterm-genkey
docker run -d -p 5000:5000 malaohu/mobaxterm-genkey
docker pull seeleo/mobaxterm-genkey:latest
docker run -d -p 5000:5000 seeleo/mobaxterm-genkey:latest
```
## 使用方法
访问IP:5000
![image](https://user-images.githubusercontent.com/8140841/116803404-e94c8300-ab49-11eb-83db-ad0246ebedd3.png)
### Container Registry (GitHub)
### 激活方式
直接放到软件目录即可!
```
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
详细介绍文章https://51.ruyo.net/17008.html
## Credits
> - 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
from flask import Flask, request, send_file
import os
import os.path
import zipfile
from flask import Flask, request, send_file
app = Flask(__name__)
VariantBase64Table = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/='
VariantBase64Dict = { i : VariantBase64Table[i] for i in range(len(VariantBase64Table)) }
VariantBase64ReverseDict = { VariantBase64Table[i] : 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))}
def VariantBase64Encode(bs : bytes):
def VariantBase64Encode(bs: bytes):
result = b''
blocks_count, left_bytes = divmod(len(bs), 3)
@ -38,7 +41,8 @@ def VariantBase64Encode(bs : bytes):
result += block.encode()
return result
def VariantBase64Decode(s : str):
def VariantBase64Decode(s: str):
result = b''
blocks_count, left_bytes = divmod(len(s), 4)
@ -65,42 +69,48 @@ def VariantBase64Decode(s : str):
else:
raise ValueError('Invalid encoding.')
def EncryptBytes(key : int, bs : bytes):
def EncryptBytes(key: int, bs: bytes):
result = bytearray()
for i in range(len(bs)):
result.append(bs[i] ^ ((key >> 8) & 0xff))
key = result[-1] & key | 0x482D
return bytes(result)
def DecryptBytes(key : int, bs : bytes):
def DecryptBytes(key: int, bs: bytes):
result = bytearray()
for i in range(len(bs)):
result.append(bs[i] ^ ((key >> 8) & 0xff))
key = bs[i] & key | 0x482D
return bytes(result)
class LicenseType:
Professional = 1
Educational = 3
Persional = 4
Personal = 4
def GenerateLicense(Type : LicenseType, Count : int, UserName : str, MajorVersion : int, MinorVersion):
assert(Count >= 0)
LicenseString = '%d#%s|%d%d#%d#%d3%d6%d#%d#%d#%d#' % (Type,
UserName, MajorVersion, MinorVersion,
Count,
MajorVersion, MinorVersion, MinorVersion,
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.
def GenerateLicense(Type: int, Count: int, UserName: str, MajorVersion: int, MinorVersion):
assert (Count >= 0)
LicenseString = '%d#%s|%d%d#%d#%d3%d6%d#%d#%d#%d#' % (
Type,
UserName, MajorVersion, MinorVersion,
Count,
MajorVersion, MinorVersion, MinorVersion,
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()
FileName = EncodedLicenseString.replace('/','').replace('\\','')
FileName = EncodedLicenseString.replace('/', '').replace('\\', '')
with zipfile.ZipFile(FileName, 'w') as f:
f.writestr('Pro.key', data = EncodedLicenseString)
f.writestr('Pro.key', data=EncodedLicenseString)
return FileName
#@app.route('/gen')
# @app.route('/gen')
def get_lc():
name = request.args.get('name', '')
version = request.args.get('ver', '')
@ -115,14 +125,17 @@ def get_lc():
return lc
#@app.route('/download/<lc>')
# @app.route('/download/<lc>')
def download_lc(lc):
if lc and len(lc) > 5 and os.path.exists('./' + lc):
return send_file(lc,
as_attachment=True,
attachment_filename='Custom.mxtpro')
return send_file(
lc,
None,
True,
'Custom.mxtpro'
)
else:
return "请检查用户名版本号是否正确!"
return "请检查用户名版本号是否正确!"
@app.route('/gen')
@ -136,8 +149,9 @@ def index():
return send_file('index.html')
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>
<html>
<head>
<title>MobaXterm Keygen</title>
<html lang="en">
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<head>
<title>MobaXterm GenKey</title>
<link href="https://fonts.googleapis.cnpmjs.org/css?family=Roboto:300,400,500,700" rel="stylesheet">
<style>
html, body {
display: flex;
justify-content: center;
font-family: Roboto, Arial, sans-serif;
font-size: 15px;
}
form {
border: 5px solid #f1f1f1;
}
input[type=text], input[type=text] {
width: 100%;
padding: 16px 8px;
margin: 8px 0;
display: inline-block;
border: 1px solid #ccc;
box-sizing: border-box;
}
button {
background-color: #8ebf42;
color: white;
padding: 14px 0;
margin: 10px 0;
border: none;
cursor: grabbing;
width: 100%;
}
h1 {
text-align:center;
font-size:18;
}
button:hover {
opacity: 0.8;
}
.formcontainer {
text-align: left;
margin: 24px 50px 12px;
}
.container {
padding: 16px 0;
text-align: left;
}
.github {
padding: 16px 0;
text-align: center;
}
body {
display: flex;
justify-content: center;
align-items: center;
height: 100vh;
margin: 0;
}
form {
width: 350px; /* Set the width of the form */
padding: 20px;
border: 1px solid #ccc;
border-radius: 5px;
background: #f5f5f5;
}
h1 {
color: #303F9F;
text-justify: newspaper;
text-align: justify;
margin-bottom: 20px;
}
.container {
margin-top: 10px;
margin-bottom: 10px;
}
button {
display: block;
width: 100%;
padding: 13px;
color: white;
border: none;
border-radius: 5px;
cursor: pointer;
margin: 5px 0 20px;
font-size: 15px;
}
button:hover {
background-color: #007bff;
}
.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>
</head>
<body>
<form action="./gen" mothod="get">
<h1>MobaXterm Keygen</h1>
<div class="formcontainer"></div>
<hr/>
<div class="container">
<label for="name"><strong>Name</strong></label>
<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">
</head>
<body>
<form action="./gen" mothod="get">
<h1>MobaXterm&ensp;GenKey</h1>
<div class="container">
<label for="name" id="lblName">Name</label>
<label style="width: 350px; display: block;">
<input name="name" id="inputName" placeholder="Please enter name" required type="text">
</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>
</form>
</body>
<div id="space"></div>
<label for="ver" id="lblVersion">Version</label>
<label style="width: 350px; display: block;">
<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>

View File

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