Commit 644c6012 by Csók Tamás

Working windows parametrizable installer

parent 3cb9d3e3
# Backport of OrderedDict() class that runs on Python 2.4, 2.5, 2.6, 2.7 and pypy.
# Passes Python2.7's test suite and incorporates all the latest updates.
try:
from thread import get_ident as _get_ident
except ImportError:
from dummy_thread import get_ident as _get_ident
try:
from _abcoll import KeysView, ValuesView, ItemsView
except ImportError:
pass
class OrderedDict(dict):
'Dictionary that remembers insertion order'
# An inherited dict maps keys to values.
# The inherited dict provides __getitem__, __len__, __contains__, and get.
# The remaining methods are order-aware.
# Big-O running times for all methods are the same as for regular dictionaries.
# The internal self.__map dictionary maps keys to links in a doubly linked list.
# The circular doubly linked list starts and ends with a sentinel element.
# The sentinel element never gets deleted (this simplifies the algorithm).
# Each link is stored as a list of length three: [PREV, NEXT, KEY].
def __init__(self, *args, **kwds):
'''Initialize an ordered dictionary. Signature is the same as for
regular dictionaries, but keyword arguments are not recommended
because their insertion order is arbitrary.
'''
if len(args) > 1:
raise TypeError('expected at most 1 arguments, got %d' % len(args))
try:
self.__root
except AttributeError:
self.__root = root = [] # sentinel node
root[:] = [root, root, None]
self.__map = {}
self.__update(*args, **kwds)
def __setitem__(self, key, value, dict_setitem=dict.__setitem__):
'od.__setitem__(i, y) <==> od[i]=y'
# Setting a new item creates a new link which goes at the end of the linked
# list, and the inherited dictionary is updated with the new key/value pair.
if key not in self:
root = self.__root
last = root[0]
last[1] = root[0] = self.__map[key] = [last, root, key]
dict_setitem(self, key, value)
def __delitem__(self, key, dict_delitem=dict.__delitem__):
'od.__delitem__(y) <==> del od[y]'
# Deleting an existing item uses self.__map to find the link which is
# then removed by updating the links in the predecessor and successor nodes.
dict_delitem(self, key)
link_prev, link_next, key = self.__map.pop(key)
link_prev[1] = link_next
link_next[0] = link_prev
def __iter__(self):
'od.__iter__() <==> iter(od)'
root = self.__root
curr = root[1]
while curr is not root:
yield curr[2]
curr = curr[1]
def __reversed__(self):
'od.__reversed__() <==> reversed(od)'
root = self.__root
curr = root[0]
while curr is not root:
yield curr[2]
curr = curr[0]
def clear(self):
'od.clear() -> None. Remove all items from od.'
try:
for node in self.__map.itervalues():
del node[:]
root = self.__root
root[:] = [root, root, None]
self.__map.clear()
except AttributeError:
pass
dict.clear(self)
def popitem(self, last=True):
'''od.popitem() -> (k, v), return and remove a (key, value) pair.
Pairs are returned in LIFO order if last is true or FIFO order if false.
'''
if not self:
raise KeyError('dictionary is empty')
root = self.__root
if last:
link = root[0]
link_prev = link[0]
link_prev[1] = root
root[0] = link_prev
else:
link = root[1]
link_next = link[1]
root[1] = link_next
link_next[0] = root
key = link[2]
del self.__map[key]
value = dict.pop(self, key)
return key, value
# -- the following methods do not depend on the internal structure --
def keys(self):
'od.keys() -> list of keys in od'
return list(self)
def values(self):
'od.values() -> list of values in od'
return [self[key] for key in self]
def items(self):
'od.items() -> list of (key, value) pairs in od'
return [(key, self[key]) for key in self]
def iterkeys(self):
'od.iterkeys() -> an iterator over the keys in od'
return iter(self)
def itervalues(self):
'od.itervalues -> an iterator over the values in od'
for k in self:
yield self[k]
def iteritems(self):
'od.iteritems -> an iterator over the (key, value) items in od'
for k in self:
yield (k, self[k])
def update(*args, **kwds):
'''od.update(E, **F) -> None. Update od from dict/iterable E and F.
If E is a dict instance, does: for k in E: od[k] = E[k]
If E has a .keys() method, does: for k in E.keys(): od[k] = E[k]
Or if E is an iterable of items, does: for k, v in E: od[k] = v
In either case, this is followed by: for k, v in F.items(): od[k] = v
'''
if len(args) > 2:
raise TypeError('update() takes at most 2 positional '
'arguments (%d given)' % (len(args),))
elif not args:
raise TypeError('update() takes at least 1 argument (0 given)')
self = args[0]
# Make progressively weaker assumptions about "other"
other = ()
if len(args) == 2:
other = args[1]
if isinstance(other, dict):
for key in other:
self[key] = other[key]
elif hasattr(other, 'keys'):
for key in other.keys():
self[key] = other[key]
else:
for key, value in other:
self[key] = value
for key, value in kwds.items():
self[key] = value
__update = update # let subclasses override update without breaking __init__
__marker = object()
def pop(self, key, default=__marker):
'''od.pop(k[,d]) -> v, remove specified key and return the corresponding value.
If key is not found, d is returned if given, otherwise KeyError is raised.
'''
if key in self:
result = self[key]
del self[key]
return result
if default is self.__marker:
raise KeyError(key)
return default
def setdefault(self, key, default=None):
'od.setdefault(k[,d]) -> od.get(k,d), also set od[k]=d if k not in od'
if key in self:
return self[key]
self[key] = default
return default
def __repr__(self, _repr_running={}):
'od.__repr__() <==> repr(od)'
call_key = id(self), _get_ident()
if call_key in _repr_running:
return '...'
_repr_running[call_key] = 1
try:
if not self:
return '%s()' % (self.__class__.__name__,)
return '%s(%r)' % (self.__class__.__name__, self.items())
finally:
del _repr_running[call_key]
def __reduce__(self):
'Return state information for pickling'
items = [[k, self[k]] for k in self]
inst_dict = vars(self).copy()
for k in vars(OrderedDict()):
inst_dict.pop(k, None)
if inst_dict:
return (self.__class__, (items,), inst_dict)
return self.__class__, (items,)
def copy(self):
'od.copy() -> a shallow copy of od'
return self.__class__(self)
@classmethod
def fromkeys(cls, iterable, value=None):
'''OD.fromkeys(S[, v]) -> New ordered dictionary with keys from S
and values equal to v (which defaults to None).
'''
d = cls()
for key in iterable:
d[key] = value
return d
def __eq__(self, other):
'''od.__eq__(y) <==> od==y. Comparison to another OD is order-sensitive
while comparison to a regular mapping is order-insensitive.
'''
if isinstance(other, OrderedDict):
return len(self)==len(other) and self.items() == other.items()
return dict.__eq__(self, other)
def __ne__(self, other):
return not self == other
# -- the following methods are only used in Python 2.7 --
def viewkeys(self):
"od.viewkeys() -> a set-like object providing a view on od's keys"
return KeysView(self)
def viewvalues(self):
"od.viewvalues() -> an object providing a view on od's values"
return ValuesView(self)
def viewitems(self):
"od.viewitems() -> a set-like object providing a view on od's items"
return ItemsView(self)
\ No newline at end of file
......@@ -3,7 +3,7 @@ Encoding=UTF-8
Version=0.2
Type=Application
Name=Cloud GUI
Comment=Tool to use IK Cloud
Comment=Tool to use CIRCLE Cloud
Exec=cloud2 %u
Icon=/usr/share/icons/cloud.svg
Terminal=true
......
......@@ -162,6 +162,6 @@ def main():
if vm.state.upper()[:3] in ("FUT", "RUN"):
connect(vm)
except:
pass
print "Unknown error occurred! Please contact the developers!"
if __name__ == "__main__":
main()
......@@ -4,6 +4,7 @@
# Távoli klienshez csatlakozás windows OS alól
##
import sys, os, time, subprocess, glob, nxkey, win32crypt, binascii
##
# A távoli klienshez csatlakozás valósítja majd meg windows alól
# @param vm Paraméterek a csatlakozáshoz
......@@ -14,6 +15,65 @@
# vm.password Csatlakozáshoz használt jelszó
#
def connect(vm):
pass
if vm.protocol == "SSH":
arguments = "-ssh -P %s -pw %s %s@%s" % (vm.port, vm.password, vm.user, vm.host)
subprocess.Popen("putty.exe "+arguments, shell = True)
elif vm.protocol == "NX":
listdir = os.path.expanduser("~\\.nx\\config\\*.nxs")
found = False
server = "\"Server host\" value=\"%s\"" % vm.host
port = "\"Server port\" value=\"%s\"" % vm.port
for config_file in glob.glob(listdir):
with open(config_file) as f:
file = f.read()
if server in file and port in file:
found = True
break
if not found:
config_file = "%s%s%s" % (os.path.expanduser("~\\.nx\\config\\"), str(int(time.time()*1000)), ".nxs")
password = nxkey.NXKeyGen(vm.password).getEncrypted()
config = NX_template % {'USERNAME' : vm.user, 'PASSWORD' : password, 'HOST' : vm.host, 'PORT' : vm.port}
f = open(config_file, 'w')
f.write(config)
f.close()
subprocess.Popen(config_file, shell = True)
elif vm.protocol == "RDP":
listdir = os.path.dirname(os.path.realpath(__file__))+"\\.rdp\\*.rdp"
found = False
full_address = "full address:s:%s:%s" % (vm.host, vm.port)
user = "username:s:%s" % vm.user
for config_file in glob.glob(listdir):
with open(config_file) as f:
file = f.read()
if full_address in file and user in file:
found = True
break
if not found:
config_file = "%s%s%s" % (os.path.dirname(os.path.realpath(__file__))+"\\.rdp\\", str(int(time.time()*1000)), ".rdp")
password = binascii.hexlify(win32crypt.CryptProtectData(u"%s" % vm.password,u'psw',None,None,None,0))
config = RPD_template % {'USERNAME' : vm.user, 'PASSWORD' : password, 'HOST' : vm.host, 'PORT' : vm.port}
f = open(config_file, 'w')
f.write(config)
f.close()
subprocess.Popen(config_file, shell = True)
NX_template = """<!DOCTYPE NXClientSettings>
<NXClientSettings application="nxclient" version="1.3" >
<group name="General" >
<option key="Remember password" value="true" />
<option key="Resolution" value="fullscreen" />
<option key="Server host" value="%(HOST)s" />
<option key="Server port" value="%(PORT)s" />
<option key="Session" value="unix" />
</group>
<group name="Login" >
<option key="Auth" value="%(PASSWORD)s" />
<option key="Guest Mode" value="false" />
<option key="Login Method" value="nx" />
<option key="User" value="%(USERNAME)s" />
</group>
</NXClientSettings>"""
RPD_template = """username:s:%(USERNAME)s
full address:s:%(HOST)s:%(PORT)s
password 51:b:%(PASSWORD)s"""
\ No newline at end of file
......@@ -4,9 +4,9 @@ sudo apt-get install sshpass python-pip remmina-plugin-nx remmina-plugin-rdp xdg
sudo pip install selenium
if [ "$(uname -m)" == 'x86_64' ]; then
sudo cp remminapasswd64 /usr/local/bin/remminapasswd
sudo cp x64/remminapasswd /usr/local/bin/remminapasswd
else
sudo cp remminapasswd32 /usr/local/bin/remminapasswd
sudo cp x86/remminapasswd /usr/local/bin/remminapasswd
fi
sudo chmod +x /usr/local/bin/remminapasswd
sudo cp cloud2 /usr/local/bin/
......
#!/usr/bin/python
# -*- coding: utf-8 -*-
##
# Generating NoMachine NX scrambled key according to https://www.nomachine.com/AR01C00125
##
import sys
import random
import re
from xml.sax.saxutils import escape
##
# NXKeyGen class
# Creates NoMachine NX scrambled keys
#
class NXKeyGen:
numValidCharList = 85
dummyString = "{{{{"
##
# Initialize the class
# @param password Password that will be scrambled
#
def __init__(self, password):
self.password = password
##
# Encrypt (scramble) the given password
# @return scrambleString Scrambled version of the original password
#
def getEncrypted(self):
return self.scrambleString(self.password)
##
# Valid character list
# @return validcharlist List of the valid characters
#
def getvalidCharList(self, pos):
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]
##
# Password encoder
# @return sPass Encoded password
#
def encodePassword(self, p):
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
##
# Character position finder
# @param c Character that needs to be matched if valid
# @return i Place where the character is in the valid list
#
def findCharInList(self, c):
i = -1
for j in range(self.numValidCharList):
randchar = self.getvalidCharList(j);
if randchar == c:
i = j
return i
return i
##
# Random valid character getter
# @return char Valid character placed 0-60 in the valid list
#
def getRandomValidCharFromList(self):
return self.getvalidCharList(random.randint(0,60))
##
# Password scrambler
# @param s Password that needs to be scrambled
# @return sRet NoMachine NX scrambled password
#
def scrambleString(self, s):
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)
##
# Replace a character at a special position
#
def substr_replace(self,in_str,ch,pos,qt):
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()
File added
#!/usr/bin/python
# -*- coding: utf-8 -*-
##
# Pywin32 installer for CIRCLE client application
##
import os, sys, subprocess
from nx_client_installer import DecideArchitecture
##
# Main program
# Install Pywin32 to the computer
#
def main():
if sys.hexversion < 0x02060000:
print "Not a 2.6+ version Python is running, commencing update"
subprocess.Popen(os.path.dirname(os.path.realpath(__file__))+"\\no_root_install.bat")
sys.exit(1)
else:
pywin32_version = str(219)
if sys.hexversion < 0x02070000:
if DecideArchitecture.Is64Windows():
subprocess.Popen(os.path.dirname(os.path.realpath(__file__))+"\\x64\\pywin32-"+pywin32_version+".win-amd64-py2.6.exe").wait()
else:
subprocess.Popen(os.path.dirname(os.path.realpath(__file__))+"\\x86\\pywin32-"+pywin32_version+".win32-py2.6.exe").wait()
elif sys.hexversion < 0x02080000:
if DecideArchitecture.Is64Windows():
subprocess.Popen(os.path.dirname(os.path.realpath(__file__))+"\\x64\\pywin32-"+pywin32_version+".win-amd64-py2.7.exe").wait()
else:
subprocess.Popen(os.path.dirname(os.path.realpath(__file__))+"\\x86\\pywin32-"+pywin32_version+".win32-py2.7.exe").wait()
else:
print "Unsupported Python version is found!"
if __name__ == "__main__":
main()
\ No newline at end of file
@echo off
cls
setLocal EnableDelayedExpansion
rem Set whether we want output info on screen or not
IF NOT "%1"=="" (
SET "output_on_screen=%1"
) else (
SET "output_on_screen=False"
)
rem Starting the uninstall script
IF NOT "!output_on_screen!"=="False" (
@echo Starting CIRCLE Client uninstall script
@echo.
)
rem Get the running directory for later ease of use
SET running_directory=%~dp0
rem Set where this file will install the rest of the files
SET "install_location=%APPDATA%\CIRCLE"
if not exist "%install_location%\" (
SET "install_location=%ProgramFiles%\CIRCLE"
)
if not exist "%install_location%\" (
IF NOT "!output_on_screen!"=="False" (
@echo Installation direcory not found^^! Please delete ^'CIRCLE^' direcory manually
pause
)
goto end
)
IF NOT "!output_on_screen!"=="False" (
@echo Installation direcory found at ^'%install_location%^'
@echo Removing files
)
rem Delete files and directory
rd>nul /q/s %install_location% 2>nul
IF NOT "!output_on_screen!"=="False" (
@echo Done
@echo Removing desktop icon
call python %running_directory%win_install.py ^-r
@echo Done
pause
) else (
call python %running_directory%win_install.py ^-r >nul 2>&1
)
:end
\ No newline at end of file
......@@ -2,29 +2,62 @@
# -*- coding: utf-8 -*-
##
# Windows installer helper for CIRCLE client application
# Windows icon installer for CIRCLE client application
##
import os, sys, argparse
import os, sys, argparse, subprocess
if sys.hexversion > 0x02070000:
from collections import *
else:
from OrderedDict import *
import pythoncom
from win32com.shell import shell, shellcon
from nx_client_installer import DecideArchitecture, RegistryHandler, Struct
##
# Argument parser, argparse modulon alapszik
# Argument parser, based on argparse module
# @return args
#
def pars_arguments():
parser = argparse.ArgumentParser();
parser.add_argument("-d", "--driver", help="Select webdriver. Aside from Firefox, you have to install first the proper driver.", \
type=str, choices=['firefox', 'chrome', 'iexplore', 'opera'], default="firefox")
parser.add_argument("-l", "--location", help="Location of the client files in the system", default=os.getenv('ProgramFiles')+"\\CIRCLE\\")
type=str, choices=['firefox', 'chrome', 'iexplore', 'opera'], default="firefox", required=False)
if DecideArchitecture.Is64Windows():
local_default = DecideArchitecture.GetProgramFiles64()+"\\CIRCLE\\"
else:
local_default = DecideArchitecture.GetProgramFiles32()+"\\CIRCLE\\"
if not os.path.exists(local_default[:-1]) and os.path.exists(os.environ['APPDATA']+"\\CIRCLE"):
local_default = os.environ['APPDATA']+"\\CIRCLE\\"
parser.add_argument("-l", "--location", help="Location of the client files in the system", default=local_default, required=False)
parser.add_argument("-r", "--remove", help="Remove installed files instead of creating them", action="store_true", required=False)
parser.add_argument("-u", "--url", help="Whether we installed and we want to use selenium or not", action="store_true", required=False)
parser.add_argument("-t", "--target", help="If this is an URL icon, where should it point", default="https://pc3.szgt.uni-miskolc.hu/", required=False)
args = parser.parse_args();
return args
##
# Custom protocol register based on RegistryHandler module
# Can raise AttributeError on wrongly provided dictionary chain
# @param dict_chain OrderedDictionary chain of the registry tree
#
def custom_protocol_register(custom_protocol):
if not isinstance(custom_protocol, OrderedDict):
raise AttributeError
print "\t"+custom_protocol.iterkeys().next()
try:
custom_arguments = Struct()
custom_arguments.registry = "HKCR"
handler = RegistryHandler(custom_arguments)
handler.create_registry_from_dict_chain(custom_protocol, True)
print "\t\tDone!"
except:
raise
##
# Main program
# read the parameters
# create a proper icon with the proper driver
# call the nx_client_installer
def main():
try:
args = pars_arguments()
......@@ -34,6 +67,22 @@ def main():
pythoncom.CLSCTX_INPROC_SERVER,
shell.IID_IShellLink
)
desktop_path = shell.SHGetFolderPath (0, shellcon.CSIDL_DESKTOP, 0, 0)
if args.remove:
location =os.path.join(desktop_path, "Cloud GUI")
if os.path.isfile("%s%s" % (location, ".lnk")):
os.remove("%s%s" % (location, ".lnk"))
if os.path.isfile("%s%s" % (location, ".url")):
os.remove("%s%s" % (location, ".url"))
else:
subprocess.call("python "+os.path.dirname(os.path.realpath(__file__))+"\\nx_client_installer.py")
if args.url:
location = os.path.join(desktop_path, "Cloud GUI.url")
shortcut = file(location, 'w')
shortcut.write('[InternetShortcut]\n')
shortcut.write('URL='+args.target)
shortcut.close()
else:
shortcut.SetPath (args.location+"cloud.py")
if args.driver == "chrome":
shortcut.SetArguments("-d chrome")
......@@ -43,11 +92,27 @@ def main():
shortcut.SetArguments("-d opera")
shortcut.SetDescription ("Tool to use CIRCLE Cloud")
shortcut.SetIconLocation (args.location+"cloud.ico", 0)
desktop_path = shell.SHGetFolderPath (0, shellcon.CSIDL_DESKTOP, 0, 0)
persist_file = shortcut.QueryInterface (pythoncom.IID_IPersistFile)
persist_file.Save (os.path.join (desktop_path, "Cloud GUI.lnk"), 0)
print "Icon successfully created on desktop"
print "Creating custom URL protocol handlers"
try:
custom_ssh = OrderedDict([('ssh', "URL:CIRCLE-SSH Protocol"), ('ssh\\URL Protocol', ""),\
('ssh\\DefaultIcon', args.location+"cloud.ico"),\
('ssh\\shell', {'open': {'command': "\"python.exe\" \""+args.location+"cloud.py\" \"%1\""}})])
custom_protocol_register(custom_ssh)
custom_rdp = OrderedDict([('rdp', "URL:CIRCLE-RDP Protocol"), ('rdp\\URL Protocol', ""),\
('rdp\\DefaultIcon', args.location+"cloud.ico"),\
('rdp\\shell', {'open': {'command': "\"python.exe\" \""+args.location+"cloud.py\" \"%1\""}})])
custom_protocol_register(custom_rdp)
custom_nx = OrderedDict([('nx', "URL:CIRCLE-NX Protocol"), ('nx\\URL Protocol', ""),\
('nx\\DefaultIcon', args.location+"cloud.ico"),\
('nx\\shell', {'open': {'command': "\"python.exe\" \""+args.location+"cloud.py\" \"%1\""}})])
custom_protocol_register(custom_nx)
except:
print "Error! URL Protocol handler installation aborted!"
except:
pass
print "Unknown error occurred! Please contact the developers!"
if __name__ == "__main__":
main()
\ No newline at end of file
#!/bin/bash
sudo apt-get install sshpass python-pip remmina-plugin-nx remmina-plugin-rdp xdg-user-dirs
sudo pip install selenium
if [ "$(uname -m)" == 'x86_64' ]; then
sudo cp x64/remminapasswd /usr/local/bin/remminapasswd
else
sudo cp x86/remminapasswd /usr/local/bin/remminapasswd
fi
sudo chmod +x /usr/local/bin/remminapasswd
sudo cp cloud2 /usr/local/bin/
sudo chmod +x /usr/local/bin/cloud2
sudo cp cloud.py /usr/local/bin/
sudo chmod +x /usr/local/bin/cloud.py
sudo cp cloud_connect_from_linux.py /usr/local/bin/
sudo chmod +x /usr/local/bin/cloud_connect_from_linux.py
sudo cp cloud.svg /usr/share/icons/
sudo cp cloud.desktop /usr/share/applications
sudo chmod +x /usr/share/applications/cloud.desktop
sudo update-desktop-database
cp cloud.desktop $(xdg-user-dir DESKTOP)
chmod +x $(xdg-user-dir DESKTOP)/cloud.desktop
remmina
\ No newline at end of file
#!/bin/bash
sudo rm -f /usr/local/bin/remminapasswd
sudo rm -f /usr/local/bin/cloud2
sudo rm -f /usr/local/bin/cloud.py
sudo rm -f /usr/local/bin/cloud_connect_from_linux.py
sudo rm -f /usr/share/icons/cloud.svg
rm -f $(xdg-user-dir DESKTOP)/cloud.desktop
\ No newline at end of file
@echo off
:addPath pathVar /B
::
:: Safely appends the path contained within variable pathVar to the end
:: of PATH if and only if the path does not already exist within PATH.
::
:: If the case insensitive /B option is specified, then the path is
:: inserted into the front (Beginning) of PATH instead.
::
:: If the pathVar path is fully qualified, then it is logically compared
:: to each fully qualified path within PATH. The path strings are
:: considered a match if they are logically equivalent.
::
:: If the pathVar path is relative, then it is strictly compared to each
:: relative path within PATH. Case differences and double quotes are
:: ignored, but otherwise the path strings must match exactly.
::
:: Before appending the pathVar path, all double quotes are stripped, and
:: then the path is enclosed in double quotes if and only if the path
:: contains at least one semicolon.
::
:: addPath aborts with ERRORLEVEL 2 if pathVar is missing or undefined
:: or if PATH is undefined.
::
::------------------------------------------------------------------------
::
:: Error checking
if "%~1"=="" exit /b 2
if not defined %~1 exit /b 2
if not defined path exit /b 2
::
:: Determine if function was called while delayed expansion was enabled
setlocal
set "NotDelayed=!"
::
:: Prepare to safely parse PATH into individual paths
setlocal DisableDelayedExpansion
set "var=%path:"=""%"
set "var=%var:^=^^%"
set "var=%var:&=^&%"
set "var=%var:|=^|%"
set "var=%var:<=^<%"
set "var=%var:>=^>%"
set "var=%var:;=^;^;%"
set var=%var:""="%
set "var=%var:"=""Q%"
set "var=%var:;;="S"S%"
set "var=%var:^;^;=;%"
set "var=%var:""="%"
setlocal EnableDelayedExpansion
set "var=!var:"Q=!"
set "var=!var:"S"S=";"!"
::
:: Remove quotes from pathVar and abort if it becomes empty
set "new=!%~1:"^=!"
if not defined new exit /b 2
::
:: Determine if pathVar is fully qualified
echo("!new!"|findstr /i /r /c:^"^^\"[a-zA-Z]:[\\/][^\\/]" ^
/c:^"^^\"[\\][\\]" >nul ^
&& set "abs=1" || set "abs=0"
::
:: For each path in PATH, check if path is fully qualified and then
:: do proper comparison with pathVar. Exit if a match is found.
:: Delayed expansion must be disabled when expanding FOR variables
:: just in case the value contains !
for %%A in ("!new!\") do for %%B in ("!var!") do (
if "!!"=="" setlocal disableDelayedExpansion
for %%C in ("%%~B\") do (
echo(%%B|findstr /i /r /c:^"^^\"[a-zA-Z]:[\\/][^\\/]" ^
/c:^"^^\"[\\][\\]" >nul ^
&& (if %abs%==1 if /i "%%~sA"=="%%~sC" exit /b 0) ^
|| (if %abs%==0 if /i %%A==%%C exit /b 0)
)
)
::
:: Build the modified PATH, enclosing the added path in quotes
:: only if it contains ;
setlocal enableDelayedExpansion
if "!new:;=!" neq "!new!" set new="!new!"
if /i "%~2"=="/B" (set "rtn=!new!;!path!") else set "rtn=!path!;!new!"
::
:: rtn now contains the modified PATH. We need to safely pass the
:: value accross the ENDLOCAL barrier
::
:: Make rtn safe for assignment using normal expansion by replacing
:: % and " with not yet defined FOR variables
set "rtn=!rtn:%%=%%A!"
set "rtn=!rtn:"=%%B!"
::
:: Escape ^ and ! if function was called while delayed expansion was enabled.
:: The trailing ! in the second assignment is critical and must not be removed.
if not defined NotDelayed set "rtn=!rtn:^=^^^^!"
if not defined NotDelayed set "rtn=%rtn:!=^^^!%" !
::
:: Pass the rtn value accross the ENDLOCAL barrier using FOR variables to
:: restore the % and " characters. Again the trailing ! is critical.
for /f "usebackq tokens=1,2" %%A in ('%%^ ^"') do (
endlocal & endlocal & endlocal & endlocal & endlocal
set "path=%rtn%" !
)
exit /b 0
\ No newline at end of file
@echo off
:inPath pathVar
::
:: Tests if the path stored within variable pathVar exists within PATH.
::
:: The result is returned as the ERRORLEVEL:
:: 0 if the pathVar path is found in PATH.
:: 1 if the pathVar path is not found in PATH.
:: 2 if pathVar is missing or undefined or if PATH is undefined.
::
:: If the pathVar path is fully qualified, then it is logically compared
:: to each fully qualified path within PATH. The path strings don't have
:: to match exactly, they just need to be logically equivalent.
::
:: If the pathVar path is relative, then it is strictly compared to each
:: relative path within PATH. Case differences and double quotes are
:: ignored, but otherwise the path strings must match exactly.
::
::------------------------------------------------------------------------
::
:: Error checking
if "%~1"=="" exit /b 2
if not defined %~1 exit /b 2
if not defined path exit /b 2
::
:: Prepare to safely parse PATH into individual paths
setlocal DisableDelayedExpansion
set "var=%path:"=""%"
set "var=%var:^=^^%"
set "var=%var:&=^&%"
set "var=%var:|=^|%"
set "var=%var:<=^<%"
set "var=%var:>=^>%"
set "var=%var:;=^;^;%"
set var=%var:""="%
set "var=%var:"=""Q%"
set "var=%var:;;="S"S%"
set "var=%var:^;^;=;%"
set "var=%var:""="%"
setlocal EnableDelayedExpansion
set "var=!var:"Q=!"
set "var=!var:"S"S=";"!"
::
:: Remove quotes from pathVar and abort if it becomes empty
set "new=!%~1:"=!"
if not defined new exit /b 2
::
:: Determine if pathVar is fully qualified
echo("!new!"|findstr /i /r /c:^"^^\"[a-zA-Z]:[\\/][^\\/]" ^
/c:^"^^\"[\\][\\]" >nul ^
&& set "abs=1" || set "abs=0"
::
:: For each path in PATH, check if path is fully qualified and then do
:: proper comparison with pathVar.
:: Exit with ERRORLEVEL 0 if a match is found.
:: Delayed expansion must be disabled when expanding FOR variables
:: just in case the value contains !
for %%A in ("!new!\") do for %%B in ("!var!") do (
if "!!"=="" endlocal
for %%C in ("%%~B\") do (
echo(%%B|findstr /i /r /c:^"^^\"[a-zA-Z]:[\\/][^\\/]" ^
/c:^"^^\"[\\][\\]" >nul ^
&& (if %abs%==1 if /i "%%~sA"=="%%~sC" exit /b 0) ^
|| (if %abs%==0 if /i "%%~A"=="%%~C" exit /b 0)
)
)
:: No match was found so exit with ERRORLEVEL 1
exit /b 1
\ No newline at end of file
[Desktop Entry]
Encoding=UTF-8
Version=0.2
Type=Application
Name=Cloud GUI
Comment=Tool to use CIRCLE Cloud
Exec=cloud2 %u
Icon=/usr/share/icons/cloud.svg
Terminal=true
MimeType=x-scheme-handler/rdp;x-scheme-handler/nx;x-scheme-handler/ssh;
Categories=Utility;Application;
# Backport of OrderedDict() class that runs on Python 2.4, 2.5, 2.6, 2.7 and pypy.
# Passes Python2.7's test suite and incorporates all the latest updates.
try:
from thread import get_ident as _get_ident
except ImportError:
from dummy_thread import get_ident as _get_ident
try:
from _abcoll import KeysView, ValuesView, ItemsView
except ImportError:
pass
class OrderedDict(dict):
'Dictionary that remembers insertion order'
# An inherited dict maps keys to values.
# The inherited dict provides __getitem__, __len__, __contains__, and get.
# The remaining methods are order-aware.
# Big-O running times for all methods are the same as for regular dictionaries.
# The internal self.__map dictionary maps keys to links in a doubly linked list.
# The circular doubly linked list starts and ends with a sentinel element.
# The sentinel element never gets deleted (this simplifies the algorithm).
# Each link is stored as a list of length three: [PREV, NEXT, KEY].
def __init__(self, *args, **kwds):
'''Initialize an ordered dictionary. Signature is the same as for
regular dictionaries, but keyword arguments are not recommended
because their insertion order is arbitrary.
'''
if len(args) > 1:
raise TypeError('expected at most 1 arguments, got %d' % len(args))
try:
self.__root
except AttributeError:
self.__root = root = [] # sentinel node
root[:] = [root, root, None]
self.__map = {}
self.__update(*args, **kwds)
def __setitem__(self, key, value, dict_setitem=dict.__setitem__):
'od.__setitem__(i, y) <==> od[i]=y'
# Setting a new item creates a new link which goes at the end of the linked
# list, and the inherited dictionary is updated with the new key/value pair.
if key not in self:
root = self.__root
last = root[0]
last[1] = root[0] = self.__map[key] = [last, root, key]
dict_setitem(self, key, value)
def __delitem__(self, key, dict_delitem=dict.__delitem__):
'od.__delitem__(y) <==> del od[y]'
# Deleting an existing item uses self.__map to find the link which is
# then removed by updating the links in the predecessor and successor nodes.
dict_delitem(self, key)
link_prev, link_next, key = self.__map.pop(key)
link_prev[1] = link_next
link_next[0] = link_prev
def __iter__(self):
'od.__iter__() <==> iter(od)'
root = self.__root
curr = root[1]
while curr is not root:
yield curr[2]
curr = curr[1]
def __reversed__(self):
'od.__reversed__() <==> reversed(od)'
root = self.__root
curr = root[0]
while curr is not root:
yield curr[2]
curr = curr[0]
def clear(self):
'od.clear() -> None. Remove all items from od.'
try:
for node in self.__map.itervalues():
del node[:]
root = self.__root
root[:] = [root, root, None]
self.__map.clear()
except AttributeError:
pass
dict.clear(self)
def popitem(self, last=True):
'''od.popitem() -> (k, v), return and remove a (key, value) pair.
Pairs are returned in LIFO order if last is true or FIFO order if false.
'''
if not self:
raise KeyError('dictionary is empty')
root = self.__root
if last:
link = root[0]
link_prev = link[0]
link_prev[1] = root
root[0] = link_prev
else:
link = root[1]
link_next = link[1]
root[1] = link_next
link_next[0] = root
key = link[2]
del self.__map[key]
value = dict.pop(self, key)
return key, value
# -- the following methods do not depend on the internal structure --
def keys(self):
'od.keys() -> list of keys in od'
return list(self)
def values(self):
'od.values() -> list of values in od'
return [self[key] for key in self]
def items(self):
'od.items() -> list of (key, value) pairs in od'
return [(key, self[key]) for key in self]
def iterkeys(self):
'od.iterkeys() -> an iterator over the keys in od'
return iter(self)
def itervalues(self):
'od.itervalues -> an iterator over the values in od'
for k in self:
yield self[k]
def iteritems(self):
'od.iteritems -> an iterator over the (key, value) items in od'
for k in self:
yield (k, self[k])
def update(*args, **kwds):
'''od.update(E, **F) -> None. Update od from dict/iterable E and F.
If E is a dict instance, does: for k in E: od[k] = E[k]
If E has a .keys() method, does: for k in E.keys(): od[k] = E[k]
Or if E is an iterable of items, does: for k, v in E: od[k] = v
In either case, this is followed by: for k, v in F.items(): od[k] = v
'''
if len(args) > 2:
raise TypeError('update() takes at most 2 positional '
'arguments (%d given)' % (len(args),))
elif not args:
raise TypeError('update() takes at least 1 argument (0 given)')
self = args[0]
# Make progressively weaker assumptions about "other"
other = ()
if len(args) == 2:
other = args[1]
if isinstance(other, dict):
for key in other:
self[key] = other[key]
elif hasattr(other, 'keys'):
for key in other.keys():
self[key] = other[key]
else:
for key, value in other:
self[key] = value
for key, value in kwds.items():
self[key] = value
__update = update # let subclasses override update without breaking __init__
__marker = object()
def pop(self, key, default=__marker):
'''od.pop(k[,d]) -> v, remove specified key and return the corresponding value.
If key is not found, d is returned if given, otherwise KeyError is raised.
'''
if key in self:
result = self[key]
del self[key]
return result
if default is self.__marker:
raise KeyError(key)
return default
def setdefault(self, key, default=None):
'od.setdefault(k[,d]) -> od.get(k,d), also set od[k]=d if k not in od'
if key in self:
return self[key]
self[key] = default
return default
def __repr__(self, _repr_running={}):
'od.__repr__() <==> repr(od)'
call_key = id(self), _get_ident()
if call_key in _repr_running:
return '...'
_repr_running[call_key] = 1
try:
if not self:
return '%s()' % (self.__class__.__name__,)
return '%s(%r)' % (self.__class__.__name__, self.items())
finally:
del _repr_running[call_key]
def __reduce__(self):
'Return state information for pickling'
items = [[k, self[k]] for k in self]
inst_dict = vars(self).copy()
for k in vars(OrderedDict()):
inst_dict.pop(k, None)
if inst_dict:
return (self.__class__, (items,), inst_dict)
return self.__class__, (items,)
def copy(self):
'od.copy() -> a shallow copy of od'
return self.__class__(self)
@classmethod
def fromkeys(cls, iterable, value=None):
'''OD.fromkeys(S[, v]) -> New ordered dictionary with keys from S
and values equal to v (which defaults to None).
'''
d = cls()
for key in iterable:
d[key] = value
return d
def __eq__(self, other):
'''od.__eq__(y) <==> od==y. Comparison to another OD is order-sensitive
while comparison to a regular mapping is order-insensitive.
'''
if isinstance(other, OrderedDict):
return len(self)==len(other) and self.items() == other.items()
return dict.__eq__(self, other)
def __ne__(self, other):
return not self == other
# -- the following methods are only used in Python 2.7 --
def viewkeys(self):
"od.viewkeys() -> a set-like object providing a view on od's keys"
return KeysView(self)
def viewvalues(self):
"od.viewvalues() -> an object providing a view on od's values"
return ValuesView(self)
def viewitems(self):
"od.viewitems() -> a set-like object providing a view on od's items"
return ItemsView(self)
\ No newline at end of file
......@@ -34,7 +34,7 @@ def pars_arguments():
parser.add_argument("-u", "--username", type=str)
parser.add_argument("-p", "--password", type=str)
parser.add_argument("-d", "--driver", help="Select webdriver. Aside from Firefox, you have to install first the proper driver.", \
type=str, choices=['firefox', 'chrome', 'ie', 'opera', 'safari'], default="firefox")
type=str, choices=['firefox', 'chrome', 'ie', 'opera'], default="firefox")
parser.add_argument("-o", "--old", help="Use old interface", action="store_true")
args = parser.parse_args();
return args
......@@ -54,8 +54,6 @@ class Browser:
self.driver = webdriver.Ie()
elif args.driver == "opera":
self.driver = webdriver.Opera()
elif args.driver == "safari":
self.driver = webdriver.Safari()
self.driver.implicitly_wait(10)
##
......@@ -96,6 +94,7 @@ class Browser:
driver.find_element_by_css_selector("a[href*='/logout/']").click()
except:
print "Browser session timed out!"
raise
return vm
##
......@@ -127,6 +126,7 @@ class Browser:
driver.find_element_by_css_selector("a[href*='/logout/']").click()
except:
print "Browser session timed out!"
raise
return vm
##
......@@ -138,6 +138,7 @@ class Browser:
# kapcsolódunk a klienshez
def main():
try:
args = pars_arguments()
if args.uri is not None:
vm = Struct()
......@@ -146,17 +147,21 @@ def main():
vm.state = "RUN"
else:
browser = Browser(args)
try:
if args.old:
vm = browser.old_main()
else:
vm = browser.main()
browser.driver.quit()
except:
raise
if platform.system() == "Linux":
from cloud_connect_from_linux import connect
elif platform.system() == "Windows":
from cloud_connect_from_windows import connect
if vm.state.upper()[:3] in ("FUT", "RUN"):
connect(vm)
except:
print "Unknown error occurred! Please contact the developers!"
if __name__ == "__main__":
main()
......@@ -4,6 +4,7 @@
# Távoli klienshez csatlakozás windows OS alól
##
import sys, os, time, subprocess, glob, nxkey, win32crypt, binascii
##
# A távoli klienshez csatlakozás valósítja majd meg windows alól
# @param vm Paraméterek a csatlakozáshoz
......@@ -14,6 +15,65 @@
# vm.password Csatlakozáshoz használt jelszó
#
def connect(vm):
pass
if vm.protocol == "SSH":
arguments = "-ssh -P %s -pw %s %s@%s" % (vm.port, vm.password, vm.user, vm.host)
subprocess.Popen("putty.exe "+arguments, shell = True)
elif vm.protocol == "NX":
listdir = os.path.expanduser("~\\.nx\\config\\*.nxs")
found = False
server = "\"Server host\" value=\"%s\"" % vm.host
port = "\"Server port\" value=\"%s\"" % vm.port
for config_file in glob.glob(listdir):
with open(config_file) as f:
file = f.read()
if server in file and port in file:
found = True
break
if not found:
config_file = "%s%s%s" % (os.path.expanduser("~\\.nx\\config\\"), str(int(time.time()*1000)), ".nxs")
password = nxkey.NXKeyGen(vm.password).getEncrypted()
config = NX_template % {'USERNAME' : vm.user, 'PASSWORD' : password, 'HOST' : vm.host, 'PORT' : vm.port}
f = open(config_file, 'w')
f.write(config)
f.close()
subprocess.Popen(config_file, shell = True)
elif vm.protocol == "RDP":
listdir = os.path.dirname(os.path.realpath(__file__))+"\\.rdp\\*.rdp"
found = False
full_address = "full address:s:%s:%s" % (vm.host, vm.port)
user = "username:s:%s" % vm.user
for config_file in glob.glob(listdir):
with open(config_file) as f:
file = f.read()
if full_address in file and user in file:
found = True
break
if not found:
config_file = "%s%s%s" % (os.path.dirname(os.path.realpath(__file__))+"\\.rdp\\", str(int(time.time()*1000)), ".rdp")
password = binascii.hexlify(win32crypt.CryptProtectData(u"%s" % vm.password,u'psw',None,None,None,0))
config = RPD_template % {'USERNAME' : vm.user, 'PASSWORD' : password, 'HOST' : vm.host, 'PORT' : vm.port}
f = open(config_file, 'w')
f.write(config)
f.close()
subprocess.Popen(config_file, shell = True)
NX_template = """<!DOCTYPE NXClientSettings>
<NXClientSettings application="nxclient" version="1.3" >
<group name="General" >
<option key="Remember password" value="true" />
<option key="Resolution" value="fullscreen" />
<option key="Server host" value="%(HOST)s" />
<option key="Server port" value="%(PORT)s" />
<option key="Session" value="unix" />
</group>
<group name="Login" >
<option key="Auth" value="%(PASSWORD)s" />
<option key="Guest Mode" value="false" />
<option key="Login Method" value="nx" />
<option key="User" value="%(USERNAME)s" />
</group>
</NXClientSettings>"""
RPD_template = """username:s:%(USERNAME)s
full address:s:%(HOST)s:%(PORT)s
password 51:b:%(PASSWORD)s"""
\ No newline at end of file
This source diff could not be displayed because it is too large. You can view the blob instead.
#!/usr/bin/python
# -*- coding: utf-8 -*-
##
# Generating NoMachine NX scrambled key according to https://www.nomachine.com/AR01C00125
##
import sys
import random
import re
from xml.sax.saxutils import escape
##
# NXKeyGen class
# Creates NoMachine NX scrambled keys
#
class NXKeyGen:
numValidCharList = 85
dummyString = "{{{{"
##
# Initialize the class
# @param password Password that will be scrambled
#
def __init__(self, password):
self.password = password
##
# Encrypt (scramble) the given password
# @return scrambleString Scrambled version of the original password
#
def getEncrypted(self):
return self.scrambleString(self.password)
##
# Valid character list
# @return validcharlist List of the valid characters
#
def getvalidCharList(self, pos):
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]
##
# Password encoder
# @return sPass Encoded password
#
def encodePassword(self, p):
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
##
# Character position finder
# @param c Character that needs to be matched if valid
# @return i Place where the character is in the valid list
#
def findCharInList(self, c):
i = -1
for j in range(self.numValidCharList):
randchar = self.getvalidCharList(j);
if randchar == c:
i = j
return i
return i
##
# Random valid character getter
# @return char Valid character placed 0-60 in the valid list
#
def getRandomValidCharFromList(self):
return self.getvalidCharList(random.randint(0,60))
##
# Password scrambler
# @param s Password that needs to be scrambled
# @return sRet NoMachine NX scrambled password
#
def scrambleString(self, s):
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)
##
# Replace a character at a special position
#
def substr_replace(self,in_str,ch,pos,qt):
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()
#!/usr/bin/python
# -*- coding: utf-8 -*-
##
# Pywin32 installer for CIRCLE client application
##
import os, sys, subprocess
from nx_client_installer import DecideArchitecture
##
# Main program
# Install Pywin32 to the computer
#
def main():
if sys.hexversion < 0x02060000:
print "Not a 2.6+ version Python is running, commencing update"
subprocess.Popen(os.path.dirname(os.path.realpath(__file__))+"\\no_root_install.bat")
sys.exit(1)
else:
pywin32_version = str(219)
if sys.hexversion < 0x02070000:
if DecideArchitecture.Is64Windows():
subprocess.Popen(os.path.dirname(os.path.realpath(__file__))+"\\x64\\pywin32-"+pywin32_version+".win-amd64-py2.6.exe").wait()
else:
subprocess.Popen(os.path.dirname(os.path.realpath(__file__))+"\\x86\\pywin32-"+pywin32_version+".win32-py2.6.exe").wait()
elif sys.hexversion < 0x02080000:
if DecideArchitecture.Is64Windows():
subprocess.Popen(os.path.dirname(os.path.realpath(__file__))+"\\x64\\pywin32-"+pywin32_version+".win-amd64-py2.7.exe").wait()
else:
subprocess.Popen(os.path.dirname(os.path.realpath(__file__))+"\\x86\\pywin32-"+pywin32_version+".win32-py2.7.exe").wait()
else:
print "Unsupported Python version is found!"
if __name__ == "__main__":
main()
\ No newline at end of file
#!/usr/bin/python
# -*- coding: utf-8 -*-
##
# Windows icon installer for CIRCLE client application
##
import os, sys, argparse, subprocess
if sys.hexversion > 0x02070000:
from collections import *
else:
from OrderedDict import *
import pythoncom
from win32com.shell import shell, shellcon
from nx_client_installer import DecideArchitecture, RegistryHandler, Struct
##
# Argument parser, based on argparse module
# @return args
#
def pars_arguments():
parser = argparse.ArgumentParser();
parser.add_argument("-d", "--driver", help="Select webdriver. Aside from Firefox, you have to install first the proper driver.", \
type=str, choices=['firefox', 'chrome', 'iexplore', 'opera'], default="firefox", required=False)
if DecideArchitecture.Is64Windows():
local_default = DecideArchitecture.GetProgramFiles64()+"\\CIRCLE\\"
else:
local_default = DecideArchitecture.GetProgramFiles32()+"\\CIRCLE\\"
if not os.path.exists(local_default[:-1]) and os.path.exists(os.environ['APPDATA']+"\\CIRCLE"):
local_default = os.environ['APPDATA']+"\\CIRCLE\\"
parser.add_argument("-l", "--location", help="Location of the client files in the system", default=local_default, required=False)
parser.add_argument("-r", "--remove", help="Remove installed files instead of creating them", action="store_true", required=False)
parser.add_argument("-u", "--url", help="Whether we installed and we want to use selenium or not", action="store_true", required=False)
parser.add_argument("-t", "--target", help="If this is an URL icon, where should it point", default="https://pc3.szgt.uni-miskolc.hu/", required=False)
args = parser.parse_args();
return args
##
# Custom protocol register based on RegistryHandler module
# Can raise AttributeError on wrongly provided dictionary chain
# @param dict_chain OrderedDictionary chain of the registry tree
#
def custom_protocol_register(custom_protocol):
if not isinstance(custom_protocol, OrderedDict):
raise AttributeError
print "\t"+custom_protocol.iterkeys().next()
try:
custom_arguments = Struct()
custom_arguments.registry = "HKCR"
handler = RegistryHandler(custom_arguments)
handler.create_registry_from_dict_chain(custom_protocol, True)
print "\t\tDone!"
except:
raise
##
# Main program
# read the parameters
# create a proper icon with the proper driver
# call the nx_client_installer
def main():
try:
args = pars_arguments()
shortcut = pythoncom.CoCreateInstance (
shell.CLSID_ShellLink,
None,
pythoncom.CLSCTX_INPROC_SERVER,
shell.IID_IShellLink
)
desktop_path = shell.SHGetFolderPath (0, shellcon.CSIDL_DESKTOP, 0, 0)
if args.remove:
location =os.path.join(desktop_path, "Cloud GUI")
if os.path.isfile("%s%s" % (location, ".lnk")):
os.remove("%s%s" % (location, ".lnk"))
if os.path.isfile("%s%s" % (location, ".url")):
os.remove("%s%s" % (location, ".url"))
else:
subprocess.call("python "+os.path.dirname(os.path.realpath(__file__))+"\\nx_client_installer.py")
if args.url:
location = os.path.join(desktop_path, "Cloud GUI.url")
shortcut = file(location, 'w')
shortcut.write('[InternetShortcut]\n')
shortcut.write('URL='+args.target)
shortcut.close()
else:
shortcut.SetPath (args.location+"cloud.py")
if args.driver == "chrome":
shortcut.SetArguments("-d chrome")
elif args.driver == "iexplore":
shortcut.SetArguments("-d ie")
elif args.driver == "opera":
shortcut.SetArguments("-d opera")
shortcut.SetDescription ("Tool to use CIRCLE Cloud")
shortcut.SetIconLocation (args.location+"cloud.ico", 0)
desktop_path = shell.SHGetFolderPath (0, shellcon.CSIDL_DESKTOP, 0, 0)
persist_file = shortcut.QueryInterface (pythoncom.IID_IPersistFile)
persist_file.Save (os.path.join (desktop_path, "Cloud GUI.lnk"), 0)
print "Icon successfully created on desktop"
print "Creating custom URL protocol handlers"
try:
custom_ssh = OrderedDict([('ssh', "URL:CIRCLE-SSH Protocol"), ('ssh\\URL Protocol', ""),\
('ssh\\DefaultIcon', args.location+"cloud.ico"),\
('ssh\\shell', {'open': {'command': "\"python.exe\" \""+args.location+"cloud.py\" \"%1\""}})])
custom_protocol_register(custom_ssh)
custom_rdp = OrderedDict([('rdp', "URL:CIRCLE-RDP Protocol"), ('rdp\\URL Protocol', ""),\
('rdp\\DefaultIcon', args.location+"cloud.ico"),\
('rdp\\shell', {'open': {'command': "\"python.exe\" \""+args.location+"cloud.py\" \"%1\""}})])
custom_protocol_register(custom_rdp)
custom_nx = OrderedDict([('nx', "URL:CIRCLE-NX Protocol"), ('nx\\URL Protocol', ""),\
('nx\\DefaultIcon', args.location+"cloud.ico"),\
('nx\\shell', {'open': {'command': "\"python.exe\" \""+args.location+"cloud.py\" \"%1\""}})])
custom_protocol_register(custom_nx)
except:
print "Error! URL Protocol handler installation aborted!"
except:
print "Unknown error occurred! Please contact the developers!"
if __name__ == "__main__":
main()
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or sign in to comment