Merge eed12402d7
into 7a360264ea
commit
eb99d42fdd
|
@ -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 }}
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
**/.idea/**
|
|
@ -1,4 +1,4 @@
|
|||
FROM python:3.6-slim
|
||||
FROM python:3.12-alpine
|
||||
|
||||
MAINTAINER malaohu <tua@live.cn>
|
||||
|
||||
|
|
47
README.md
47
README.md
|
@ -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).
|
||||
|
||||

|
||||
  
|
||||
     
|
||||
|
||||
**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
|
||||

|
||||
### Container Registry (GitHub)
|
||||
|
||||
### 激活方式
|
||||
直接放到软件目录即可!
|
||||
```
|
||||
docker pull ghcr.io/lzcapp/mobaxterm-genkey:latest
|
||||
docker run -d -p 5000:5000 ghcr.io/lzcapp/mobaxterm-genkey:latest
|
||||
```
|
||||
|
||||
## Screenshot
|
||||
|
||||

|
||||

|
||||
|
||||
核心内容来自: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
76
app.py
|
@ -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
|
||||
)
|
||||
|
|
255
index.html
255
index.html
|
@ -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 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>
|
||||
|
|
|
@ -1 +1,2 @@
|
|||
Flask==2.1.0
|
||||
Flask==3.0.3
|
||||
Werkzeug==3.0.3
|
||||
|
|
Loading…
Reference in New Issue