#!/usr/bin/env python # -*- coding: utf-8 -*- """ Generating NoMachine NX scrambled key according to https://www.nomachine.com/AR01C00125 """ import sys import random from xml.sax.saxutils import escape class NXKeyGen: """ NXKeyGen class Creates NoMachine NX scrambled keys """ numValidCharList = 85 dummyString = "{{{{" def __init__(self, password): """ Initialize the class Keyword arguments: @param password -- Password that will be scrambled """ self.password = password def getEncrypted(self): """ Encrypt (scramble) the given password Keyword arguments: @return scrambleString -- Scrambled version of the original password """ return self.scrambleString(self.password) def getvalidCharList(self, pos): """ Valid character list Keyword arguments: @return validcharlist -- List of the valid characters """ validcharlist = [ "!", "#", "$", "%", "&", "(", ")", "*", "+", "-", ".", "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", ":", ";", "<", ">", "?", "@", "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z", "[", "]", "_", "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z", "{", "|", "}"] return validcharlist[pos] def encodePassword(self, p): """ Password encoder Keyword arguments: @return sPass -- Encoded password """ sPass = ":" sTmp = "" if not p: return "" for i in range(len(p)): c = p[i:i+1] a = ord(c) sTmp = str(a + i + 1) + ":" sPass += sTmp sTmp = "" return sPass def findCharInList(self, c): """ Character position finder Keyword arguments: @param c -- Character that needs to be matched if valid @return i -- Place where the character is in the valid list """ i = -1 for j in range(self.numValidCharList): randchar = self.getvalidCharList(j) if randchar == c: i = j return i return i def getRandomValidCharFromList(self): """ Random valid character getter Keyword arguments: @return char -- Valid character placed 0-60 in the valid list """ return self.getvalidCharList(random.randint(0, 60)) def scrambleString(self, s): """ Password scrambler Keyword arguments: @param s -- Password that needs to be scrambled @return sRet -- NoMachine NX scrambled password """ sRet = "" if not s: return s strp = self.encodePassword(s) if len(strp) < 32: sRet += self.dummyString for iR in reversed(range(len(strp))): sRet += strp[iR:iR+1] if len(sRet) < 32: sRet += self.dummyString app = self.getRandomValidCharFromList() k = ord(app) l = k + len(sRet) - 2 sRet = app + sRet for i1 in range(1, len(sRet)): app2 = sRet[i1: i1 + 1] j = self.findCharInList(app2) if j == -1: return sRet i = (j + l * (i1 + 1)) % self.numValidCharList car = self.getvalidCharList(i) sRet = self.substr_replace(sRet, car, i1, 1) c = (ord(self.getRandomValidCharFromList())) + 2 c2 = chr(c) sRet = sRet + c2 return escape(sRet) def substr_replace(self, in_str, ch, pos, qt): """ Replace a character at a special position """ clist = list(in_str) count = 0 tmp_str = '' for key in clist: if count != pos: tmp_str += key else: tmp_str += ch count = count+1 return tmp_str if __name__ == "__main__": NXPass = NXKeyGen(sys.argv[1]) print NXPass.password print NXPass.getEncrypted()