Add Login/Logout passwords
This commit is contained in:
parent
fb06a20077
commit
9bbaaf64d5
|
@ -0,0 +1,237 @@
|
|||
#!/usr/bin/python3
|
||||
from dreamtown_config import *
|
||||
import sys
|
||||
import os
|
||||
import json
|
||||
import sqlite3
|
||||
import time
|
||||
import hashlib
|
||||
import random
|
||||
|
||||
#
|
||||
# Bassed off https://github.com/MrBlinky/Tamagotchi-friends-code-generator
|
||||
#
|
||||
# MIT License
|
||||
#
|
||||
# Copyright (c) 2021 Mr.Blinky
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
# of this software and associated documentation files (the "Software"), to deal
|
||||
# in the Software without restriction, including without limitation the rights
|
||||
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
# copies of the Software, and to permit persons to whom the Software is
|
||||
# furnished to do so, subject to the following conditions:
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included in all
|
||||
# copies or substantial portions of the Software.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
# SOFTWARE.
|
||||
|
||||
|
||||
|
||||
passwordchars1 = "0123456789ABCDEF"
|
||||
passwordchars2 = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0"
|
||||
namechars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ "
|
||||
namechars_xor = [0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0xA0]
|
||||
checksum_xor = [0x11, 0x32, 0x53, 0x74, 0x15, 0x36, 0x58, 0x77, 0x29, 0x4F, 0x6E, 0x0D, 0x2C, 0x4B, 0x6A, 0x7F]
|
||||
step3count_xor = [0x57, 0x3A]
|
||||
nameorder = [6, 8, 10, 7, 9, 13, 11, 12] #digit order of name characters
|
||||
step13count_add = [[1, 2, 3, 4, 5, 6, 7, 8],
|
||||
[2, 3, 4, 5, 6, 7, 8, 1],
|
||||
[3, 4, 5, 6, 7, 8, 1, 2],
|
||||
[4, 5, 6, 7, 8, 1, 2, 3],
|
||||
[5, 6, 7, 8, 1, 2, 3, 4],
|
||||
[6, 7, 8, 1, 2, 3, 4, 5],
|
||||
[7, 2, 1, 2, 3, 4, 5, 6],
|
||||
[8, 1, 2, 3, 4, 5, 6, 7]]
|
||||
|
||||
|
||||
|
||||
print("Content-Type: application/json")
|
||||
print("")
|
||||
|
||||
content_len = int(os.environ["CONTENT_LENGTH"])
|
||||
post = sys.stdin.read(content_len)
|
||||
jsonData = json.loads(post)
|
||||
result = {"status":SUCCESS}
|
||||
|
||||
method = os.environ["REQUEST_METHOD"]
|
||||
if method != "POST":
|
||||
print("Expected POST")
|
||||
os._exit()
|
||||
|
||||
def GetTamaName(tama_id):
|
||||
if tama_id >= len(tamagotchi) or tama_id < 0:
|
||||
return "Unknown #"+str(tama_id)
|
||||
|
||||
tamaName = tamagotchi[tama_id]
|
||||
if tamaName == "":
|
||||
tamaName = "Unknown #"+str(tama_id)
|
||||
|
||||
return tamaName
|
||||
|
||||
def InputValidation(password):
|
||||
if len(password) != 14:
|
||||
return False
|
||||
|
||||
for i in range(0,6):
|
||||
if passwordchars1.find(password[i]) == -1:
|
||||
return False
|
||||
|
||||
for i in range(6,14):
|
||||
if passwordchars2.find(password[i]) == -1:
|
||||
return False
|
||||
|
||||
return True
|
||||
|
||||
def GetItem(special):
|
||||
#check item input
|
||||
if not special:
|
||||
itemType = random.randrange(0, 2)
|
||||
else:
|
||||
itemType = random.randrange(2, 6)
|
||||
itemId = random.randrange(0, 30)
|
||||
if itemType == 0:
|
||||
pass
|
||||
if itemType == 1:
|
||||
itemId += 30;
|
||||
else:
|
||||
if itemId > 14:
|
||||
itemId = 14;
|
||||
itemId += (itemType-2) * 15;
|
||||
itemType = 2;
|
||||
return [itemId, itemType]
|
||||
|
||||
|
||||
|
||||
def GetName(password, stepCount):
|
||||
name = '';
|
||||
for i in range(0,8): #get user name
|
||||
c = passwordchars2.find(password[nameorder[i]]) - step13count_add[stepCount][i];
|
||||
if c < 0:
|
||||
c += 0x1B;
|
||||
name += namechars[c];
|
||||
return name
|
||||
|
||||
def TryGet():
|
||||
authToken = jsonData['authToken']
|
||||
|
||||
c = db.cursor()
|
||||
cur = c.execute('SELECT COUNT(1) from users WHERE LastSession=?',(authToken,))
|
||||
rows = cur.fetchone()
|
||||
count = rows[0]
|
||||
if count == 0:
|
||||
result['status'] = USER_DOES_NOT_EXIST
|
||||
return 0
|
||||
|
||||
#validate
|
||||
loginPassword = jsonData["code"].upper()
|
||||
ticketNumber = jsonData['ticketNumber']
|
||||
if not InputValidation(loginPassword):
|
||||
result['status'] = 2 # code invalid
|
||||
return 0
|
||||
|
||||
#decode
|
||||
checksum = passwordchars1.find(loginPassword[0])
|
||||
step13count = passwordchars1.find(loginPassword[1]) >> 1
|
||||
step3count = passwordchars1.find(loginPassword[1]) & 1
|
||||
|
||||
name = GetName(loginPassword, step13count)
|
||||
|
||||
#login data for decoding and checksum verifying
|
||||
logindata = [
|
||||
(passwordchars1.find(loginPassword[4]) << 4) | passwordchars1.find(loginPassword[5]),
|
||||
(passwordchars1.find(loginPassword[2]) << 4) | passwordchars1.find(loginPassword[3]),
|
||||
((namechars.find(name[1]) & 0x3) << 6) | namechars.find(name[0]),
|
||||
((namechars.find(name[2]) & 0xF) << 4) | (namechars.find(name[1]) >> 2),
|
||||
(namechars.find(name[3]) << 2) | (namechars.find(name[2]) >> 4),
|
||||
((namechars.find(name[5]) & 0x3) << 6) | namechars.find(name[4]),
|
||||
((namechars.find(name[6]) & 0xF) << 4) | (namechars.find(name[5]) >> 2),
|
||||
(namechars.find(name[7]) << 2) | (namechars.find(name[6]) >> 4),
|
||||
(passwordchars1.find(loginPassword[0]) << 4) | passwordchars1.find(loginPassword[1])
|
||||
]
|
||||
|
||||
|
||||
# step 3 counter xoring
|
||||
logindata[0] ^= step3count_xor[step3count]
|
||||
logindata[1] ^= step3count_xor[step3count]
|
||||
|
||||
#name xor
|
||||
logindata[0] ^= namechars_xor[namechars.find(name[1])];
|
||||
logindata[1] ^= namechars_xor[namechars.find(name[3])];
|
||||
|
||||
#checksum xor
|
||||
logindata[0] ^= checksum_xor[checksum];
|
||||
logindata[1] ^= checksum_xor[checksum];
|
||||
|
||||
# Check checksum
|
||||
c = 0;
|
||||
for i in range(0, 17):
|
||||
if (i & 1) == 1:
|
||||
c -= (logindata[i >> 1] >> 4);
|
||||
else:
|
||||
c -= (logindata[i >> 1] & 0xF);
|
||||
|
||||
if (c & 0xF) != checksum:
|
||||
result['status'] = 2 # code invalid
|
||||
return 0
|
||||
|
||||
tama_id = logindata[0] & 0x3F
|
||||
step7count = logindata[1] >> 4;
|
||||
device_id = (logindata[0] >> 6) | ((logindata[1] & 0xF) << 2);
|
||||
|
||||
special = False
|
||||
if ticketNumber > 1:
|
||||
special = True
|
||||
|
||||
itemResult = GetItem(special)
|
||||
itemId = itemResult[0]
|
||||
itemType = itemResult[1]
|
||||
|
||||
#create logout data
|
||||
logoutdata = [
|
||||
logindata[0],
|
||||
logindata[1] | 0x80,
|
||||
itemId,
|
||||
(step3count << 3) | itemType
|
||||
]
|
||||
checksum = (0 - (logoutdata[1] >> 4) - (logoutdata[1] & 0xF) -
|
||||
(logoutdata[0] >> 4) - (logoutdata[0] & 0xF) -
|
||||
(logoutdata[2] >> 4) - (logoutdata[2] & 0xF) -
|
||||
(logoutdata[3] & 0xF)) & 0XF;
|
||||
|
||||
#xor checksum
|
||||
for i in range(0,3):
|
||||
logoutdata[i] ^= checksum_xor[checksum];
|
||||
|
||||
#player name xoring
|
||||
logoutdata[0] ^= namechars_xor[namechars.find(name[1])];
|
||||
logoutdata[1] ^= namechars_xor[namechars.find(name[3])];
|
||||
logoutdata[2] ^= namechars_xor[namechars.find(name[5])];
|
||||
#step 3 counter xoring
|
||||
for i in range(0,3):
|
||||
logoutdata[i] ^= step3count_xor[step3count];
|
||||
|
||||
logoutPassword = '%X%X%X%X%X%X%X%X' % (
|
||||
logoutdata[1] >> 4, logoutdata[1] & 0xF,
|
||||
logoutdata[0] >> 4, logoutdata[0] & 0xF,
|
||||
checksum , logoutdata[3] & 0xF,
|
||||
logoutdata[2] >> 4, logoutdata[2] & 0xF)
|
||||
|
||||
result["code"] = logoutPassword
|
||||
try:
|
||||
db = sqlite3.connect(SQLLITE_DB_PATH)
|
||||
TryGet()
|
||||
db.commit()
|
||||
db.close()
|
||||
except Exception as e:
|
||||
print(e)
|
||||
os._exit()
|
||||
|
||||
print(json.dumps(result))
|
|
@ -1,4 +1,179 @@
|
|||
#!/usr/bin/python3
|
||||
from dreamtown_config import *
|
||||
import sys
|
||||
import os
|
||||
import json
|
||||
import sqlite3
|
||||
import time
|
||||
import hashlib
|
||||
|
||||
#
|
||||
# Bassed off https://github.com/MrBlinky/Tamagotchi-friends-code-generator
|
||||
#
|
||||
# MIT License
|
||||
#
|
||||
# Copyright (c) 2021 Mr.Blinky
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
# of this software and associated documentation files (the "Software"), to deal
|
||||
# in the Software without restriction, including without limitation the rights
|
||||
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
# copies of the Software, and to permit persons to whom the Software is
|
||||
# furnished to do so, subject to the following conditions:
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included in all
|
||||
# copies or substantial portions of the Software.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
# SOFTWARE.
|
||||
|
||||
|
||||
tamagotchi = ["", "Aokumotchi", "Pinkbotchi"]
|
||||
|
||||
passwordchars1 = "0123456789ABCDEF"
|
||||
passwordchars2 = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0"
|
||||
namechars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ "
|
||||
namechars_xor = [0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0xA0]
|
||||
checksum_xor = [0x11, 0x32, 0x53, 0x74, 0x15, 0x36, 0x58, 0x77, 0x29, 0x4F, 0x6E, 0x0D, 0x2C, 0x4B, 0x6A, 0x7F]
|
||||
step3count_xor = [0x57, 0x3A]
|
||||
nameorder = [6, 8, 10, 7, 9, 13, 11, 12] #digit order of name characters
|
||||
step13count_add = [[1, 2, 3, 4, 5, 6, 7, 8],
|
||||
[2, 3, 4, 5, 6, 7, 8, 1],
|
||||
[3, 4, 5, 6, 7, 8, 1, 2],
|
||||
[4, 5, 6, 7, 8, 1, 2, 3],
|
||||
[5, 6, 7, 8, 1, 2, 3, 4],
|
||||
[6, 7, 8, 1, 2, 3, 4, 5],
|
||||
[7, 2, 1, 2, 3, 4, 5, 6],
|
||||
[8, 1, 2, 3, 4, 5, 6, 7]]
|
||||
|
||||
|
||||
|
||||
print("Content-Type: application/json")
|
||||
print("")
|
||||
print("{'playerName':'Mametchi','characterName':'Mametchi','status':1}")
|
||||
|
||||
content_len = int(os.environ["CONTENT_LENGTH"])
|
||||
post = sys.stdin.read(content_len)
|
||||
jsonData = json.loads(post)
|
||||
result = {"status":SUCCESS}
|
||||
|
||||
method = os.environ["REQUEST_METHOD"]
|
||||
if method != "POST":
|
||||
print("Expected POST")
|
||||
os._exit()
|
||||
|
||||
def GetTamaName(tama_id):
|
||||
if tama_id >= len(tamagotchi) or tama_id < 0:
|
||||
return "Unknown #"+str(tama_id)
|
||||
|
||||
tamaName = tamagotchi[tama_id]
|
||||
if tamaName == "":
|
||||
tamaName = "Unknown #"+str(tama_id)
|
||||
|
||||
return tamaName
|
||||
|
||||
def InputValidation(password):
|
||||
if len(password) != 14:
|
||||
return False
|
||||
|
||||
for i in range(0,6):
|
||||
if passwordchars1.find(password[i]) == -1:
|
||||
return False
|
||||
|
||||
for i in range(6,14):
|
||||
if passwordchars2.find(password[i]) == -1:
|
||||
return False
|
||||
|
||||
return True
|
||||
|
||||
def GetName(password, stepCount):
|
||||
name = '';
|
||||
for i in range(0,8): #get user name
|
||||
c = passwordchars2.find(password[nameorder[i]]) - step13count_add[stepCount][i];
|
||||
if c < 0:
|
||||
c += 0x1B;
|
||||
name += namechars[c];
|
||||
return name
|
||||
|
||||
def TryGet():
|
||||
authToken = jsonData['authToken']
|
||||
|
||||
c = db.cursor()
|
||||
cur = c.execute('SELECT COUNT(1) from users WHERE LastSession=?',(authToken,))
|
||||
rows = cur.fetchone()
|
||||
count = rows[0]
|
||||
if count == 0:
|
||||
result['status'] = USER_DOES_NOT_EXIST
|
||||
return 0
|
||||
|
||||
#validate
|
||||
loginPassword = jsonData["code"].upper()
|
||||
if not InputValidation(loginPassword):
|
||||
result['status'] = 2 # code invalid
|
||||
return 0
|
||||
|
||||
#decode
|
||||
checksum = passwordchars1.find(loginPassword[0])
|
||||
step13count = passwordchars1.find(loginPassword[1]) >> 1
|
||||
step3count = passwordchars1.find(loginPassword[1]) & 1
|
||||
|
||||
name = GetName(loginPassword, step13count)
|
||||
|
||||
#login data for decoding and checksum verifying
|
||||
logindata = [
|
||||
(passwordchars1.find(loginPassword[4]) << 4) | passwordchars1.find(loginPassword[5]),
|
||||
(passwordchars1.find(loginPassword[2]) << 4) | passwordchars1.find(loginPassword[3]),
|
||||
((namechars.find(name[1]) & 0x3) << 6) | namechars.find(name[0]),
|
||||
((namechars.find(name[2]) & 0xF) << 4) | (namechars.find(name[1]) >> 2),
|
||||
(namechars.find(name[3]) << 2) | (namechars.find(name[2]) >> 4),
|
||||
((namechars.find(name[5]) & 0x3) << 6) | namechars.find(name[4]),
|
||||
((namechars.find(name[6]) & 0xF) << 4) | (namechars.find(name[5]) >> 2),
|
||||
(namechars.find(name[7]) << 2) | (namechars.find(name[6]) >> 4),
|
||||
(passwordchars1.find(loginPassword[0]) << 4) | passwordchars1.find(loginPassword[1])
|
||||
]
|
||||
|
||||
|
||||
# step 3 counter xoring
|
||||
logindata[0] ^= step3count_xor[step3count]
|
||||
logindata[1] ^= step3count_xor[step3count]
|
||||
|
||||
#name xor
|
||||
logindata[0] ^= namechars_xor[namechars.find(name[1])];
|
||||
logindata[1] ^= namechars_xor[namechars.find(name[3])];
|
||||
|
||||
#checksum xor
|
||||
logindata[0] ^= checksum_xor[checksum];
|
||||
logindata[1] ^= checksum_xor[checksum];
|
||||
|
||||
tama_id = logindata[0] & 0x3F
|
||||
|
||||
# Check checksum
|
||||
c = 0;
|
||||
for i in range(0, 17):
|
||||
if (i & 1) == 1:
|
||||
c -= (logindata[i >> 1] >> 4);
|
||||
else:
|
||||
c -= (logindata[i >> 1] & 0xF);
|
||||
|
||||
if (c & 0xF) != checksum:
|
||||
result['status'] = 2 # code invalid
|
||||
return 0
|
||||
|
||||
result['playerName'] = name.strip()
|
||||
result['characterName'] = GetTamaName(tama_id)
|
||||
|
||||
|
||||
try:
|
||||
db = sqlite3.connect(SQLLITE_DB_PATH)
|
||||
TryGet()
|
||||
db.commit()
|
||||
db.close()
|
||||
except Exception as e:
|
||||
print(e)
|
||||
os._exit()
|
||||
|
||||
print(json.dumps(result))
|
Loading…
Reference in New Issue