Compare commits

...

105 Commits

Author SHA1 Message Date
Adolfo Gómez García
cb5d6ed771 small typo 2015-05-21 13:14:25 +02:00
Adolfo Gómez García
b9283c6778 Fixed ramdom password... {3} must be {2}!!! 2015-05-21 13:06:11 +02:00
Adolfo Gómez García
8d4f60b0fb Fixed a couple things for Linux random password 2015-05-21 07:23:18 +02:00
Adolfo Gómez García
df498dd5bc Fixed several "case" uuids tests, so UDS can work with case sensitive
databases
2015-05-14 11:46:45 +02:00
Adolfo Gómez García
b592e10126 After upgrade of python to 2.7.9, several HTTPS connections needed to be
fixed. This is about that
2015-05-06 05:36:03 +02:00
Adolfo Gómez García
a235e43c07 Fixed edition of ovirt service O.o 2015-05-06 04:27:14 +02:00
Adolfo Gómez García
15c785d5fe Again, counter fix to 15 seconds (1 minuto seems too long for me right
now...)
2015-04-30 08:23:07 +02:00
Adolfo Gómez García
6295e7400d added virtualenv for pydev project for 1.7 2015-04-29 17:43:53 +02:00
Adolfo Gómez García
54a2a0cb35 Added exception checking on service main loop for windows 2015-04-29 17:19:30 +02:00
Adolfo Gómez García
15554ab08f A couple of minor fixes 2015-04-29 17:17:06 +02:00
Adolfo Gómez García
60556ad4ec fixed RDP with user credentials 2015-04-21 12:29:10 +02:00
Adolfo Gómez García
95b8969f5b * Fixed service ip checking access on access
* Added new "connection" REST method (Virginios request to make
"automated" connections with local clients)
2015-04-16 20:55:28 +02:00
Adolfo Gómez García
fc447e3ccf updated handlers.py from mainstream 2015-04-16 18:24:43 +02:00
Adolfo Gómez García
2fe783e3ae Updated Filesaver && fixed exporting to excel 2015-03-25 10:10:34 +01:00
Adolfo Gómez García
b69f56ecb8 Fixed servicepool deletion on image deletion 2015-03-24 11:22:28 +01:00
Adolfo Gómez García
7d26463639 updated translations 2015-03-24 10:41:52 +01:00
Adolfo Gómez García
523ca37ee8 typo 2015-03-24 09:42:54 +01:00
Adolfo Gómez García
cfad948660 Added multiple monitor support for windows clients & servers 2015-03-23 12:22:45 +01:00
Adolfo Gómez García
9fa4bacc74 fixed case of uuids to lower 2015-03-23 02:22:17 +01:00
Adolfo Gómez García
cc4619220a * Added a "preinit" to xscreensaver, to give some more oportunities on
linux to initialize this correctly.
* Fixed typos on dashboard
* Fixed not saving correctly textarea fields of configuration
2015-03-20 15:15:35 +01:00
Adolfo Gómez García
7648e9c655 Added a reset to initIdleDuration 2015-03-18 15:30:13 +01:00
Adolfo Gómez García
695a67c2cb Fixed so image deletion does not deletes it associated deployed service 2015-03-18 11:07:26 +01:00
Adolfo Gómez García
cbf68030d3 Removed debug from oVirt 2015-03-09 16:51:56 +01:00
Adolfo Gómez García
2470e88d55 added .pyo to ignore list 2015-03-09 15:51:47 +01:00
Adolfo Gómez García
63278938c8 fixed translations 2015-03-09 08:29:18 +01:00
Adolfo Gómez García
f751fff8ca Fixed using 169.254/16 as a valid IP for notifying to broker 2015-02-28 09:45:12 +01:00
Adolfo Gómez García
2d942fbac7 More minor fixes 2015-02-27 17:32:24 +01:00
Adolfo Gómez García
4bb4987937 minor fix related to grace time 2015-02-27 17:24:57 +01:00
Adolfo Gómez García
d371e3f7ac Fixed some posible "logging out too early" to users when using idle
checker
2015-02-27 17:23:26 +01:00
Adolfo Gómez García
033fb6eff2 * Fix to StatsManager so numeric fields can also be used
* Added remaining related cache elements on cache_hit & cache_miss
* pep fix to WidowsOsManger
* Reduced size of Dashboard sidebar
* Removed "AM/PM" from datetimes
2015-02-27 17:05:06 +01:00
Adolfo Gómez García
23819b77ee * Added cache hit/miss logging events 2015-02-27 09:28:04 +01:00
Adolfo Gómez García
45b2e61631 * Added some debug logging to actor 2015-02-26 10:39:18 +01:00
Adolfo Gómez García
4fceb8609f Fixed log of pub manager\nModified default config of tunneler\nUpdated actor REST api to not allow less than 30 seconds of "max idle" configuration 2015-02-25 17:05:39 +01:00
Adolfo Gómez García
26c6b559a5 * Minor tuning 2015-02-25 11:15:08 +01:00
Adolfo Gómez García
90e34029f3 Fixing up rdp transport (tunneled) 2015-02-25 10:28:18 +01:00
Adolfo Gómez García
6895f602ab Just updated guacamole pom to use 0.9.4 2015-02-23 13:26:34 +01:00
Adolfo Gómez García
b1b8b613e6 Updated translations 2015-02-23 10:16:44 +01:00
Adolfo Gómez García
40ba837f70 Added logging of what caused the exception 2015-02-23 08:35:26 +01:00
Adolfo Gómez García
c075ae5a9c * Updated notification so, by default, is broker which "deduces" the
client IP and not the client who notifies it (this is left just for
"trusted" environments)
2015-02-22 09:31:56 +01:00
Adolfo Gómez García
8de49e5e94 * Removed "Trusted only" from manifest 2015-02-22 09:17:06 +01:00
Adolfo Gómez García
7887b7f3cc Fixed Linux applet to "show" wallpapers if required 2015-02-20 15:27:16 +01:00
Adolfo Gómez García
c81f162b90 Fixed "print" to "logger.debug" 2015-02-20 11:31:06 +01:00
Adolfo Gómez García
35a5a78220 updated requirements 2015-02-20 09:30:19 +01:00
Adolfo Gómez García
2bc0f64e34 Set a default ip for connection source on service connection request
(equals to request "deducted" ip...).
2015-02-18 14:45:08 +01:00
Adolfo Gómez García
19cb475e2d * Updated bootstrap switch to latest (and working) version
* Fixed displaying state "twice" in authenticators groups due to a
"developing" data left behind...
2015-02-17 23:46:56 +01:00
Adolfo Gómez García
ae4fc2d51a Removed log from user space actor for user login.. (Filtered out) 2015-02-17 22:18:01 +01:00
Adolfo Gómez García
06e886a366 * Fixed HTML5RDP to work correctly with new actor
* Fixed base transport to receive an "user" and not an "username"
2015-02-17 11:45:30 +01:00
Adolfo Gómez García
1497314a46 Fixing up windows service behavior 2015-02-17 09:51:51 +01:00
Adolfo Gómez García
e6998cb1f3 Added posibility to modify several OS Manager fields even if it is being used 2015-02-16 18:31:16 +01:00
Adolfo Gómez García
111782dffd removing binaries 2015-02-16 17:54:30 +01:00
Adolfo Gómez García
a86fbf83e8 removing binaries 2015-02-16 17:53:27 +01:00
Adolfo Gómez García
c9f6c17407 Fixed state notification when os manager is working 2015-02-16 15:58:38 +01:00
Adolfo Gómez García
c04037a4ea Fixed actor return error on DC not reachable 2015-02-16 14:58:27 +01:00
Adolfo Gómez García
d1adcebe4b Added "info" to mac users
Restored overview info to match item info
2015-02-11 11:22:56 +01:00
Adolfo Gómez García
3e5cbda861 Testing up manifest changes for signed applets on mac 2015-02-11 09:49:31 +01:00
Adolfo Gómez García
8a393c6717 Added "is in maintenance" method for userservice 2015-02-10 17:44:41 +01:00
Adolfo Gómez García
f235bc0796 If service is in maintenance, denies now new accesses (index page may be
outdated)
2015-02-10 17:26:27 +01:00
Adolfo Gómez García
2549510eaa * Fixed several "last hour" REST requests related to tickets
* Added OS Detector so if os is not detected before, tries it at request
moment
* Added a new error so services in maintenance mode are notified
2015-02-10 17:24:27 +01:00
Adolfo Gómez García
3fbcee60cb small fix 2015-02-10 10:29:01 +01:00
Adolfo Gómez García
20cc73dca8 * Added Manifest small fixes for applets
* Updated translations
* Added several "methods" support for sqlite3 db backend (on __init__ of
uds) such as max, min & ceil (needed for stats)
2015-02-10 09:54:45 +01:00
Adolfo Gómez García
375fe6551c Some minor cosmetic fixes to scheduler runner 2015-02-03 18:26:25 +01:00
Adolfo Gómez García
f74524d947 * Fixed HTML5 RDP
* Updated translations
* Fixed Scheduler to ensure that when started up, all "owned" tasks are
released
2015-02-03 18:19:21 +01:00
Adolfo Gómez García
e1f26d2157 * Fixed "double cancel" of a publication (cancelling over an already
cancelling publication will "force" the cancellation, meaning that no
check is done, it simply stops publication and mark it as "cancelled"
(leaving a log on service pool, ofc)
2015-02-03 06:30:27 +01:00
Adolfo Gómez García
7d44bd7b65 Some more minor fixes to literals & translations 2015-02-02 11:43:56 +01:00
Adolfo Gómez García
ab5f51a3b1 * Fixed several bad formed literal strings
* Updated translations
2015-02-02 11:31:59 +01:00
Adolfo Gómez García
d1e2e98099 Fixed rpm actors download path 2015-02-02 07:13:17 +01:00
Adolfo Gómez García
f94bbaad67 Fixed mime types por rpm actors packages 2015-02-01 06:18:37 +01:00
Adolfo Gómez García
7143682062 * Fixed cancelation of a publication on dashboard
* Now allows "forced cancel" after a cancel is requested
2015-02-01 06:17:11 +01:00
Adolfo Gómez García
17a087ed4a * Removed binaries for NX from git (we have source code..)
* Fixed downloadable list for administrators with actors
2015-02-01 05:53:54 +01:00
Adolfo Gómez García
762138ca57 Fixed so new publications are not allowed while a provider is in
maintenance mode
2015-02-01 05:41:24 +01:00
Adolfo Gómez García
1fb46003fc Several minor actor fixed to manage some workarounds in a better way 2015-02-01 04:07:46 +01:00
Adolfo Gómez García
e1bbbece43 * Added minimun values for Service Pool form numeric fields
* Added support for key "minValue" for numeric ui fields
* Fixed cache updater to take into account those services pools that has
initial or l1 cache to 0
* Fixed old (legacy) uds actor logging
* Fixed index view for pools that do not have assigned services
*
2015-01-31 11:14:24 +01:00
Adolfo Gómez García
e3e652d4e1 Fixed cache updater, so now we can select "0 elements" for cache,
initials, etc..
2015-01-31 10:18:12 +01:00
Adolfo Gómez García
b8a1fc31f3 Adding colours to failed services 2015-01-28 09:15:08 +01:00
Adolfo Gómez García
d5034c9971 * Restored "missing" services that where in maintenance mode. Now they
got displayed but with some transparency & can't be clicked
* Added "slightly" blue color & tooptip to indicate that a service is
currently with an opened session
2015-01-28 08:16:48 +01:00
Adolfo Gómez García
215c8f8f3e Split views across several source files to easier "maintenance" 2015-01-28 06:30:57 +01:00
Adolfo Gómez García
b2bf4bd0db * Added some more docstrings
* Fixed how logs of user login/logout on services are done
2015-01-27 07:03:38 +01:00
Adolfo Gómez García
1d2c4c8282 Fixed requests version detection
Fixed warnings so they are no more logged to console (for urllib3
mainly)
2015-01-27 07:02:24 +01:00
Adolfo Gómez García
70fc09b21a * Added service known IP to services list
* Optimized service retrieval for dashboard
* Added group regex expressions
* Added pool in maintenance mode for pools list
* Upgraded visibility of "warned" pools (couoling them)
* Improved base service list on new pool (added provider in front of
service)
2015-01-26 09:30:25 +01:00
Adolfo Gómez García
9a529b8f5b Added experimental support for pattern in group names (using pat:... as group name) 2015-01-23 08:54:52 +01:00
Adolfo Gómez García
4a2401b622 Added fld4 to stats events. Added validators to providers 2015-01-22 11:47:01 +01:00
Adolfo Gómez García
3feb502fec Started to use events stats system 2015-01-22 03:32:26 +01:00
Adolfo Gómez García
e75c86ad58 Stabilizing for 1.7
* Fixed several IDE "false errors"
* Added several needed comments
* Added logging to base os manager to login/logout process
* Fixed Linux & Windows managers to allow use of new base os manager
feature
* Fixed coffe script error that do not allows to create e new service
2015-01-21 13:30:37 +01:00
Adolfo Gómez García
9a95d39156 * added admin dashboard link for administrator to "old" interface 2015-01-21 10:14:38 +01:00
Adolfo Gómez García
cc48b50dcb Minor code fixes & updates 2015-01-21 08:36:35 +01:00
Adolfo Gómez García
32b1ac71a9 Log fixing 2015-01-21 08:20:53 +01:00
Adolfo Gómez García
bd98349dc4 Added missing resolutions to select in preferences screen 2015-01-15 18:14:07 +01:00
Adolfo Gómez García
cf6602033d Fixed LDAP authenticators so they scape "inputs" from unknown source
(basically the username).
2015-01-15 18:11:37 +01:00
Adolfo Gómez García
2959a878af Fixed navbar to not allow "root" user to access preferences (root user
will never own services)
2015-01-15 09:24:58 +01:00
Adolfo Gómez García
ea087fce53 fixed upload directory permissions on sample settings 2015-01-14 19:55:38 +01:00
Adolfo Gómez García
9335c73003 Added config initialization on config command 2015-01-14 19:35:59 +01:00
Adolfo Gómez García
e11867a55e Added config initialization on config command 2015-01-14 19:21:01 +01:00
Adolfo Gómez García
c72a8d3950 * Added new resolutions to RDP
* Added logging of generated password to service log
* Small "pepe" corrections
2015-01-13 14:50:49 +01:00
Adolfo Gómez García
ddd8df3b26 small fix 2015-01-13 05:48:59 +01:00
Adolfo Gómez García
c491dc78ab Added TODO.txt to not forget what is next :) & updated (again) translations 2015-01-13 05:37:53 +01:00
Adolfo Gómez García
fd4fe245c6 Added CoRD custom build & update download link for Mac 2015-01-13 05:06:22 +01:00
Adolfo Gómez García
cbd8a17cc4 Updated translations 2015-01-13 04:58:53 +01:00
Adolfo Gómez García
9356fc3559 Advanced on events stats 2014-12-21 12:56:21 +01:00
Adolfo Gómez García
243e627827 Added "Maintenance mode" to providers (by Seville University request..
thanks for the advice ;-) ), that marks a provider as "on Maintenance
Mode". In this mode, every operation depending on this provider will be
"paused", and deployed services will be "hidden" from users...
2014-12-20 16:47:19 +01:00
Adolfo Gómez García
bb408a31a2 Fixed OS Managers & New Services presentation 2014-12-17 21:45:48 +01:00
Adolfo Gómez García
3035360ce7 * Changed "tiled" list of services for a... better one??
* Added a switch to the service pool so we can disable the show of
alternative transports (so only main is available...)
2014-12-12 00:43:36 +01:00
Adolfo Gómez García
cdaf5a17fa * Upgraded Java Detection js
* Added generic icon of UDS
2014-12-11 16:21:20 +01:00
Adolfo Gómez García
f97e02e867 Changed "key" generation on actor to use a random 48 chars strings
instead of an uuid
2014-12-10 12:08:13 +01:00
Adolfo Gómez García
101aa6fc39 Fixed tipo "eror" :) 2014-12-09 17:30:18 +01:00
Adolfo Gómez García
8e7a6af3ad Removed old actors 2014-12-09 17:17:36 +01:00
300 changed files with 13384 additions and 76436 deletions

1
.gitignore vendored
View File

@@ -1,4 +1,5 @@
*.pyc
*.pyo
*.orig
*~
*.swp

6
TODO.txt Normal file
View File

@@ -0,0 +1,6 @@
* Add "Scheduler" to manage pools, and posibbly other operations (Expect to release an version 1.7.1??)
* Improve stats
* Add App Virtualization support
* Add "Meta Pools"
* Manage to connect several UDS in "tree", so one UDS can be provider o another UDS

View File

@@ -1,4 +1,4 @@
udsactor (1.7.0) UNRELEASED; urgency=medium
udsactor (1.7.0) stable; urgency=medium
* Initial release.

View File

@@ -197,13 +197,18 @@ class UDSSystemTray(QtGui.QSystemTrayIcon):
self.counter = 0
self.timer.start(5000) # Launch idle checking every 5 seconds
self.graceTimerShots = 6 # Start counting for idle after 30 seconds after login, got on windows some "instant" logout because of idle timer not being reset??
self.ipc.start()
# If this is running, it's because he have logged in
self.ipc.sendLogin(operations.getCurrentUser())
def checkIdle(self):
if self.maxIdleTime is None: # No idle checl
if self.maxIdleTime is None: # No idle check
return
if self.graceTimerShots > 0:
self.graceTimerShots -= 1
return
idleTime = operations.getIdleDuration()
@@ -221,12 +226,10 @@ class UDSSystemTray(QtGui.QSystemTrayIcon):
if self.showIdleWarn is True and remainingTime < 120: # With two minutes, show a warning message
self.showIdleWarn = False
self.msgDlg.displayMessage("You have been idle for too long. The session will end if you don't resume operations")
logger.debug('Here')
def displayMessage(self, message):
logger.debug('Displaying message')
self.msgDlg.displayMessage("You have been idle for too long. The session will end if you don't resume operations")
QtGui.QMessageBox.information(None, "UDS Actor", message)
self.msgDlg.displayMessage(message)
def executeScript(self, script):
logger.debug('Executing script')
@@ -255,18 +258,22 @@ class UDSSystemTray(QtGui.QSystemTrayIcon):
def quit(self):
logger.debug('Quit invoked')
if self.stopped is True:
return
self.stopped = True
if self.stopped is False:
self.stopped = True
try:
# If we close Client, send Logoff to Broker
self.ipc.sendLogout(operations.getCurrentUser())
self.timer.stop()
self.ipc.stop()
except Exception:
# May we have lost connection with server, simply exit in that case
pass
try:
# If we close Client, send Logoff to Broker
self.ipc.sendLogout(operations.getCurrentUser())
self.timer.stop()
self.ipc.stop()
operations.loggoff()
operations.loggoff() # Invoke log off
except Exception:
# May we have lost connection with server, simply exit in that case
pass
self.app.quit()
if __name__ == '__main__':
@@ -285,6 +292,9 @@ if __name__ == '__main__':
logger.error('UDS Service is not running. Tool stopped')
sys.exit(1)
# Sets a default idle duration, but will not be used unless idle is notified from server
operations.initIdleDuration(3600 * 10)
trayIcon.show()
# Catch kill and logout user :)

View File

@@ -121,7 +121,7 @@
<x>20</x>
<y>20</y>
<width>361</width>
<height>146</height>
<height>131</height>
</rect>
</property>
<layout class="QFormLayout" name="formLayout">
@@ -207,6 +207,9 @@
<property name="currentIndex">
<number>1</number>
</property>
<property name="frame">
<bool>true</bool>
</property>
<item>
<property name="text">
<string notr="true">DEBUG</string>
@@ -219,7 +222,7 @@
</item>
<item>
<property name="text">
<string notr="true">EROR</string>
<string notr="true">ERROR</string>
</property>
</item>
<item>

View File

@@ -1,141 +1,142 @@
# -*- coding: utf-8 -*-
# Form implementation generated from reading ui file 'setup-dialog.ui'
#
# Created: Wed Nov 12 04:50:26 2014
# by: PyQt4 UI code generator 4.11.2
#
# WARNING! All changes made in this file will be lost!
from PyQt4 import QtCore, QtGui
try:
_fromUtf8 = QtCore.QString.fromUtf8
except AttributeError:
def _fromUtf8(s):
return s
try:
_encoding = QtGui.QApplication.UnicodeUTF8
def _translate(context, text, disambig):
return QtGui.QApplication.translate(context, text, disambig, _encoding)
except AttributeError:
def _translate(context, text, disambig):
return QtGui.QApplication.translate(context, text, disambig)
class Ui_UdsActorSetupDialog(object):
def setupUi(self, UdsActorSetupDialog):
UdsActorSetupDialog.setObjectName(_fromUtf8("UdsActorSetupDialog"))
UdsActorSetupDialog.setWindowModality(QtCore.Qt.WindowModal)
UdsActorSetupDialog.resize(400, 243)
sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Preferred, QtGui.QSizePolicy.Preferred)
sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0)
sizePolicy.setHeightForWidth(UdsActorSetupDialog.sizePolicy().hasHeightForWidth())
UdsActorSetupDialog.setSizePolicy(sizePolicy)
font = QtGui.QFont()
font.setFamily(_fromUtf8("Verdana"))
font.setPointSize(9)
UdsActorSetupDialog.setFont(font)
UdsActorSetupDialog.setAutoFillBackground(False)
UdsActorSetupDialog.setLocale(QtCore.QLocale(QtCore.QLocale.English, QtCore.QLocale.UnitedStates))
UdsActorSetupDialog.setSizeGripEnabled(False)
UdsActorSetupDialog.setModal(True)
self.testButton = QtGui.QPushButton(UdsActorSetupDialog)
self.testButton.setEnabled(False)
self.testButton.setGeometry(QtCore.QRect(20, 160, 361, 23))
self.testButton.setObjectName(_fromUtf8("testButton"))
self.saveButton = QtGui.QPushButton(UdsActorSetupDialog)
self.saveButton.setEnabled(False)
self.saveButton.setGeometry(QtCore.QRect(20, 190, 101, 23))
sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Preferred, QtGui.QSizePolicy.Fixed)
sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0)
sizePolicy.setHeightForWidth(self.saveButton.sizePolicy().hasHeightForWidth())
self.saveButton.setSizePolicy(sizePolicy)
self.saveButton.setObjectName(_fromUtf8("saveButton"))
self.cancelButton = QtGui.QPushButton(UdsActorSetupDialog)
self.cancelButton.setGeometry(QtCore.QRect(260, 190, 121, 23))
sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Preferred, QtGui.QSizePolicy.Fixed)
sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0)
sizePolicy.setHeightForWidth(self.cancelButton.sizePolicy().hasHeightForWidth())
self.cancelButton.setSizePolicy(sizePolicy)
self.cancelButton.setObjectName(_fromUtf8("cancelButton"))
self.layoutWidget = QtGui.QWidget(UdsActorSetupDialog)
self.layoutWidget.setGeometry(QtCore.QRect(20, 20, 361, 146))
self.layoutWidget.setObjectName(_fromUtf8("layoutWidget"))
self.formLayout = QtGui.QFormLayout(self.layoutWidget)
self.formLayout.setFieldGrowthPolicy(QtGui.QFormLayout.AllNonFixedFieldsGrow)
self.formLayout.setMargin(0)
self.formLayout.setVerticalSpacing(16)
self.formLayout.setObjectName(_fromUtf8("formLayout"))
self.label = QtGui.QLabel(self.layoutWidget)
self.label.setObjectName(_fromUtf8("label"))
self.formLayout.setWidget(0, QtGui.QFormLayout.LabelRole, self.label)
self.host = QtGui.QLineEdit(self.layoutWidget)
self.host.setAcceptDrops(False)
self.host.setObjectName(_fromUtf8("host"))
self.formLayout.setWidget(0, QtGui.QFormLayout.FieldRole, self.host)
self.label_3 = QtGui.QLabel(self.layoutWidget)
self.label_3.setObjectName(_fromUtf8("label_3"))
self.formLayout.setWidget(1, QtGui.QFormLayout.LabelRole, self.label_3)
self.masterKey = QtGui.QLineEdit(self.layoutWidget)
self.masterKey.setObjectName(_fromUtf8("masterKey"))
self.formLayout.setWidget(1, QtGui.QFormLayout.FieldRole, self.masterKey)
self.label_4 = QtGui.QLabel(self.layoutWidget)
self.label_4.setObjectName(_fromUtf8("label_4"))
self.formLayout.setWidget(2, QtGui.QFormLayout.LabelRole, self.label_4)
self.useSSl = QtGui.QComboBox(self.layoutWidget)
self.useSSl.setObjectName(_fromUtf8("useSSl"))
self.useSSl.addItem(_fromUtf8(""))
self.useSSl.addItem(_fromUtf8(""))
self.formLayout.setWidget(2, QtGui.QFormLayout.FieldRole, self.useSSl)
self.logLevelLabel = QtGui.QLabel(self.layoutWidget)
self.logLevelLabel.setObjectName(_fromUtf8("logLevelLabel"))
self.formLayout.setWidget(3, QtGui.QFormLayout.LabelRole, self.logLevelLabel)
self.logLevelComboBox = QtGui.QComboBox(self.layoutWidget)
self.logLevelComboBox.setObjectName(_fromUtf8("logLevelComboBox"))
self.logLevelComboBox.addItem(_fromUtf8(""))
self.logLevelComboBox.setItemText(0, _fromUtf8("DEBUG"))
self.logLevelComboBox.addItem(_fromUtf8(""))
self.logLevelComboBox.setItemText(1, _fromUtf8("INFO"))
self.logLevelComboBox.addItem(_fromUtf8(""))
self.logLevelComboBox.setItemText(2, _fromUtf8("EROR"))
self.logLevelComboBox.addItem(_fromUtf8(""))
self.logLevelComboBox.setItemText(3, _fromUtf8("FATAL"))
self.formLayout.setWidget(3, QtGui.QFormLayout.FieldRole, self.logLevelComboBox)
self.retranslateUi(UdsActorSetupDialog)
self.logLevelComboBox.setCurrentIndex(1)
QtCore.QObject.connect(self.host, QtCore.SIGNAL(_fromUtf8("textChanged(QString)")), UdsActorSetupDialog.textChanged)
QtCore.QObject.connect(self.masterKey, QtCore.SIGNAL(_fromUtf8("textChanged(QString)")), UdsActorSetupDialog.textChanged)
QtCore.QObject.connect(self.cancelButton, QtCore.SIGNAL(_fromUtf8("pressed()")), UdsActorSetupDialog.cancelAndDiscard)
QtCore.QObject.connect(self.testButton, QtCore.SIGNAL(_fromUtf8("pressed()")), UdsActorSetupDialog.testParameters)
QtCore.QObject.connect(self.saveButton, QtCore.SIGNAL(_fromUtf8("pressed()")), UdsActorSetupDialog.acceptAndSave)
QtCore.QMetaObject.connectSlotsByName(UdsActorSetupDialog)
def retranslateUi(self, UdsActorSetupDialog):
UdsActorSetupDialog.setWindowTitle(_translate("UdsActorSetupDialog", "UDS Actor Configuration", None))
self.testButton.setToolTip(_translate("UdsActorSetupDialog", "Click to test the selecter parameters", None))
self.testButton.setWhatsThis(_translate("UdsActorSetupDialog", "<html><head/><body><p>Click on this button to test the server host and master key parameters.</p><p>A window will be displayed with results after the test is executed.</p><p><br/></p><p>This button will only be active if all parameters are filled.</p></body></html>", None))
self.testButton.setText(_translate("UdsActorSetupDialog", "Test parameters", None))
self.saveButton.setToolTip(_translate("UdsActorSetupDialog", "Accepts changes and saves them", None))
self.saveButton.setWhatsThis(_translate("UdsActorSetupDialog", "Clicking on this button will accept all changes and save them, closing the configuration window", None))
self.saveButton.setText(_translate("UdsActorSetupDialog", "Accept && Save", None))
self.cancelButton.setToolTip(_translate("UdsActorSetupDialog", "Cancel all changes and discard them", None))
self.cancelButton.setWhatsThis(_translate("UdsActorSetupDialog", "Discards all changes and closes the configuration window", None))
self.cancelButton.setText(_translate("UdsActorSetupDialog", "Cancel && Discard", None))
self.label.setText(_translate("UdsActorSetupDialog", "UDS Server Host", None))
self.host.setToolTip(_translate("UdsActorSetupDialog", "Uds Broker Server Addres. Use IP or FQDN", None))
self.host.setWhatsThis(_translate("UdsActorSetupDialog", "Enter here the UDS Broker Addres using either its IP address or its FQDN address", None))
self.label_3.setText(_translate("UdsActorSetupDialog", "UDS Master Key", None))
self.masterKey.setToolTip(_translate("UdsActorSetupDialog", "Master key to communicate with UDS Broker", None))
self.masterKey.setWhatsThis(_translate("UdsActorSetupDialog", "<html><head/><body><p>Enter the Master Key (found on<span style=\" font-weight:600;\"> UDS Configuration</span> section) of the UDS Broker to allow communication of the Actor with Broker</p></body></html>", None))
self.label_4.setText(_translate("UdsActorSetupDialog", "Security", None))
self.useSSl.setToolTip(_translate("UdsActorSetupDialog", "Select communication security with broker", None))
self.useSSl.setWhatsThis(_translate("UdsActorSetupDialog", "<html><head/><body><p>Select the security for communications with UDS Broker.</p><p>The recommended method of communication is <span style=\" font-weight:600;\">Use SSL</span>, but selection needs to be acording to your broker configuration.</p></body></html>", None))
self.useSSl.setItemText(0, _translate("UdsActorSetupDialog", "Do not use SSL", None))
self.useSSl.setItemText(1, _translate("UdsActorSetupDialog", "Use SSL", None))
self.logLevelLabel.setText(_translate("UdsActorSetupDialog", "Log Level", None))
# -*- coding: utf-8 -*-
# Form implementation generated from reading ui file 'setup-dialog.ui'
#
# Created: Tue Dec 9 17:29:24 2014
# by: PyQt4 UI code generator 4.11.2
#
# WARNING! All changes made in this file will be lost!
from PyQt4 import QtCore, QtGui
try:
_fromUtf8 = QtCore.QString.fromUtf8
except AttributeError:
def _fromUtf8(s):
return s
try:
_encoding = QtGui.QApplication.UnicodeUTF8
def _translate(context, text, disambig):
return QtGui.QApplication.translate(context, text, disambig, _encoding)
except AttributeError:
def _translate(context, text, disambig):
return QtGui.QApplication.translate(context, text, disambig)
class Ui_UdsActorSetupDialog(object):
def setupUi(self, UdsActorSetupDialog):
UdsActorSetupDialog.setObjectName(_fromUtf8("UdsActorSetupDialog"))
UdsActorSetupDialog.setWindowModality(QtCore.Qt.WindowModal)
UdsActorSetupDialog.resize(400, 243)
sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Preferred, QtGui.QSizePolicy.Preferred)
sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0)
sizePolicy.setHeightForWidth(UdsActorSetupDialog.sizePolicy().hasHeightForWidth())
UdsActorSetupDialog.setSizePolicy(sizePolicy)
font = QtGui.QFont()
font.setFamily(_fromUtf8("Verdana"))
font.setPointSize(9)
UdsActorSetupDialog.setFont(font)
UdsActorSetupDialog.setAutoFillBackground(False)
UdsActorSetupDialog.setLocale(QtCore.QLocale(QtCore.QLocale.English, QtCore.QLocale.UnitedStates))
UdsActorSetupDialog.setSizeGripEnabled(False)
UdsActorSetupDialog.setModal(True)
self.testButton = QtGui.QPushButton(UdsActorSetupDialog)
self.testButton.setEnabled(False)
self.testButton.setGeometry(QtCore.QRect(20, 160, 361, 23))
self.testButton.setObjectName(_fromUtf8("testButton"))
self.saveButton = QtGui.QPushButton(UdsActorSetupDialog)
self.saveButton.setEnabled(False)
self.saveButton.setGeometry(QtCore.QRect(20, 190, 101, 23))
sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Preferred, QtGui.QSizePolicy.Fixed)
sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0)
sizePolicy.setHeightForWidth(self.saveButton.sizePolicy().hasHeightForWidth())
self.saveButton.setSizePolicy(sizePolicy)
self.saveButton.setObjectName(_fromUtf8("saveButton"))
self.cancelButton = QtGui.QPushButton(UdsActorSetupDialog)
self.cancelButton.setGeometry(QtCore.QRect(260, 190, 121, 23))
sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Preferred, QtGui.QSizePolicy.Fixed)
sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0)
sizePolicy.setHeightForWidth(self.cancelButton.sizePolicy().hasHeightForWidth())
self.cancelButton.setSizePolicy(sizePolicy)
self.cancelButton.setObjectName(_fromUtf8("cancelButton"))
self.layoutWidget = QtGui.QWidget(UdsActorSetupDialog)
self.layoutWidget.setGeometry(QtCore.QRect(20, 20, 361, 131))
self.layoutWidget.setObjectName(_fromUtf8("layoutWidget"))
self.formLayout = QtGui.QFormLayout(self.layoutWidget)
self.formLayout.setFieldGrowthPolicy(QtGui.QFormLayout.AllNonFixedFieldsGrow)
self.formLayout.setMargin(0)
self.formLayout.setVerticalSpacing(16)
self.formLayout.setObjectName(_fromUtf8("formLayout"))
self.label = QtGui.QLabel(self.layoutWidget)
self.label.setObjectName(_fromUtf8("label"))
self.formLayout.setWidget(0, QtGui.QFormLayout.LabelRole, self.label)
self.host = QtGui.QLineEdit(self.layoutWidget)
self.host.setAcceptDrops(False)
self.host.setObjectName(_fromUtf8("host"))
self.formLayout.setWidget(0, QtGui.QFormLayout.FieldRole, self.host)
self.label_3 = QtGui.QLabel(self.layoutWidget)
self.label_3.setObjectName(_fromUtf8("label_3"))
self.formLayout.setWidget(1, QtGui.QFormLayout.LabelRole, self.label_3)
self.masterKey = QtGui.QLineEdit(self.layoutWidget)
self.masterKey.setObjectName(_fromUtf8("masterKey"))
self.formLayout.setWidget(1, QtGui.QFormLayout.FieldRole, self.masterKey)
self.label_4 = QtGui.QLabel(self.layoutWidget)
self.label_4.setObjectName(_fromUtf8("label_4"))
self.formLayout.setWidget(2, QtGui.QFormLayout.LabelRole, self.label_4)
self.useSSl = QtGui.QComboBox(self.layoutWidget)
self.useSSl.setObjectName(_fromUtf8("useSSl"))
self.useSSl.addItem(_fromUtf8(""))
self.useSSl.addItem(_fromUtf8(""))
self.formLayout.setWidget(2, QtGui.QFormLayout.FieldRole, self.useSSl)
self.logLevelLabel = QtGui.QLabel(self.layoutWidget)
self.logLevelLabel.setObjectName(_fromUtf8("logLevelLabel"))
self.formLayout.setWidget(3, QtGui.QFormLayout.LabelRole, self.logLevelLabel)
self.logLevelComboBox = QtGui.QComboBox(self.layoutWidget)
self.logLevelComboBox.setFrame(True)
self.logLevelComboBox.setObjectName(_fromUtf8("logLevelComboBox"))
self.logLevelComboBox.addItem(_fromUtf8(""))
self.logLevelComboBox.setItemText(0, _fromUtf8("DEBUG"))
self.logLevelComboBox.addItem(_fromUtf8(""))
self.logLevelComboBox.setItemText(1, _fromUtf8("INFO"))
self.logLevelComboBox.addItem(_fromUtf8(""))
self.logLevelComboBox.setItemText(2, _fromUtf8("ERROR"))
self.logLevelComboBox.addItem(_fromUtf8(""))
self.logLevelComboBox.setItemText(3, _fromUtf8("FATAL"))
self.formLayout.setWidget(3, QtGui.QFormLayout.FieldRole, self.logLevelComboBox)
self.retranslateUi(UdsActorSetupDialog)
self.logLevelComboBox.setCurrentIndex(1)
QtCore.QObject.connect(self.host, QtCore.SIGNAL(_fromUtf8("textChanged(QString)")), UdsActorSetupDialog.textChanged)
QtCore.QObject.connect(self.masterKey, QtCore.SIGNAL(_fromUtf8("textChanged(QString)")), UdsActorSetupDialog.textChanged)
QtCore.QObject.connect(self.cancelButton, QtCore.SIGNAL(_fromUtf8("pressed()")), UdsActorSetupDialog.cancelAndDiscard)
QtCore.QObject.connect(self.testButton, QtCore.SIGNAL(_fromUtf8("pressed()")), UdsActorSetupDialog.testParameters)
QtCore.QObject.connect(self.saveButton, QtCore.SIGNAL(_fromUtf8("pressed()")), UdsActorSetupDialog.acceptAndSave)
QtCore.QMetaObject.connectSlotsByName(UdsActorSetupDialog)
def retranslateUi(self, UdsActorSetupDialog):
UdsActorSetupDialog.setWindowTitle(_translate("UdsActorSetupDialog", "UDS Actor Configuration", None))
self.testButton.setToolTip(_translate("UdsActorSetupDialog", "Click to test the selecter parameters", None))
self.testButton.setWhatsThis(_translate("UdsActorSetupDialog", "<html><head/><body><p>Click on this button to test the server host and master key parameters.</p><p>A window will be displayed with results after the test is executed.</p><p><br/></p><p>This button will only be active if all parameters are filled.</p></body></html>", None))
self.testButton.setText(_translate("UdsActorSetupDialog", "Test parameters", None))
self.saveButton.setToolTip(_translate("UdsActorSetupDialog", "Accepts changes and saves them", None))
self.saveButton.setWhatsThis(_translate("UdsActorSetupDialog", "Clicking on this button will accept all changes and save them, closing the configuration window", None))
self.saveButton.setText(_translate("UdsActorSetupDialog", "Accept && Save", None))
self.cancelButton.setToolTip(_translate("UdsActorSetupDialog", "Cancel all changes and discard them", None))
self.cancelButton.setWhatsThis(_translate("UdsActorSetupDialog", "Discards all changes and closes the configuration window", None))
self.cancelButton.setText(_translate("UdsActorSetupDialog", "Cancel && Discard", None))
self.label.setText(_translate("UdsActorSetupDialog", "UDS Server Host", None))
self.host.setToolTip(_translate("UdsActorSetupDialog", "Uds Broker Server Addres. Use IP or FQDN", None))
self.host.setWhatsThis(_translate("UdsActorSetupDialog", "Enter here the UDS Broker Addres using either its IP address or its FQDN address", None))
self.label_3.setText(_translate("UdsActorSetupDialog", "UDS Master Key", None))
self.masterKey.setToolTip(_translate("UdsActorSetupDialog", "Master key to communicate with UDS Broker", None))
self.masterKey.setWhatsThis(_translate("UdsActorSetupDialog", "<html><head/><body><p>Enter the Master Key (found on<span style=\" font-weight:600;\"> UDS Configuration</span> section) of the UDS Broker to allow communication of the Actor with Broker</p></body></html>", None))
self.label_4.setText(_translate("UdsActorSetupDialog", "Security", None))
self.useSSl.setToolTip(_translate("UdsActorSetupDialog", "Select communication security with broker", None))
self.useSSl.setWhatsThis(_translate("UdsActorSetupDialog", "<html><head/><body><p>Select the security for communications with UDS Broker.</p><p>The recommended method of communication is <span style=\" font-weight:600;\">Use SSL</span>, but selection needs to be acording to your broker configuration.</p></body></html>", None))
self.useSSl.setItemText(0, _translate("UdsActorSetupDialog", "Do not use SSL", None))
self.useSSl.setItemText(1, _translate("UdsActorSetupDialog", "Use SSL", None))
self.logLevelLabel.setText(_translate("UdsActorSetupDialog", "Log Level", None))

View File

@@ -39,6 +39,7 @@ import logging
import json
import uuid
import six
import warnings
from udsactor.log import logger
@@ -81,6 +82,7 @@ except Exception:
try:
urllib3.disable_warnings() # @UndefinedVariable
warnings.simplefilter("ignore")
except Exception:
pass # In fact, isn't too important, but wil log warns to logging file
@@ -102,15 +104,24 @@ class Api(object):
def __init__(self, host, masterKey, ssl):
self.host = host
self.masterKey = masterKey
self.useSSL = ssl
self.useSSL = True if ssl else False
self.uuid = None
self.mac = None
self.url = "{}://{}/rest/actor/".format(('http', 'https')[ssl], self.host)
self.url = "{}://{}/rest/actor/".format(('http', 'https')[self.useSSL], self.host)
self.idle = None
self.secretKey = six.text_type(uuid.uuid4())
self.newerRequestLib = requests.__version__.split('.') >= '1'
try:
self.newerRequestLib = requests.__version__.split('.')[0] >= '1'
except Exception:
self.newerRequestLib = False # I no version, guess this must be an old requests
# Disable logging requests messages except for errors, ...
logging.getLogger("requests").setLevel(logging.CRITICAL)
# Tries to disable all warnings
try:
warnings.simplefilter("ignore") # Disables all warnings
except Exception:
pass
def _getUrl(self, method, key=None, ids=None):
url = self.url + method
@@ -129,15 +140,17 @@ class Api(object):
def _request(self, url, data=None):
try:
if data is None:
# Old requests version does not support verify, but they do not checks ssl certificate
# Old requests version does not support verify, but they do not checks ssl certificate by default
if self.newerRequestLib:
r = requests.get(url, verify=VERIFY_CERT)
else:
logger.debug('Requesting with old')
r = requests.get(url) # Always ignore certs??
else:
if self.newerRequestLib:
r = requests.post(url, data=data, headers={'content-type': 'application/json'}, verify=VERIFY_CERT)
else:
logger.debug('Requesting with old')
r = requests.post(url, data=data, headers={'content-type': 'application/json'})
r = json.loads(r.content) # Using instead of r.json() to make compatible with oooold rquests lib versions
@@ -165,17 +178,20 @@ class Api(object):
uuid, mac
Optionally can return an third parameter, that is max "idle" request time
'''
logger.debug('Invoking init')
url = self._getUrl('init', key=self.masterKey, ids=ids)
res = self._request(url)['result']
logger.debug('Got response parameters: {}'.format(res))
self.uuid, self.mac = res[0:2]
self.idle = int(res[2])
if self.idle < 15:
if self.idle < 30:
self.idle = None # No values under 30 seconds are allowed :)
return self.uuid
def postMessage(self, msg, data, processData=True):
logger.debug('Invoking post message {} with data {}'.format(msg, data))
if self.uuid is None:
raise ConnectionError('REST api has not been initialized')
@@ -185,22 +201,28 @@ class Api(object):
return self._request(url, data)['result']
def notifyComm(self, url):
logger.debug('Notifying comms {}'.format(url))
return self.postMessage('notifyComms', url)
def login(self, username):
logger.debug('Notifying login {}'.format(username))
return self.postMessage('login', username)
def logout(self, username):
logger.debug('Notifying logout {}'.format(username))
return self.postMessage('logout', username)
def information(self):
logger.debug('Requesting information'.format())
return self.postMessage('information', '')
def setReady(self, ipsInfo):
logger.debug('Notifying readyness: {}'.format(ipsInfo))
data = ','.join(['{}={}'.format(v[0], v[1]) for v in ipsInfo])
return self.postMessage('ready', data)
def notifyIpChanges(self, ipsInfo):
logger.debug('Notifying ip changes: {}'.format(ipsInfo))
data = ','.join(['{}={}'.format(v[0], v[1]) for v in ipsInfo])
return self.postMessage('ip', data)

View File

@@ -37,7 +37,8 @@ from udsactor.certs import createSelfSignedCert
from udsactor.scriptThread import ScriptExecutorThread
import threading
import uuid
import string
import random
import json
import six
from six.moves import socketserver # @UnresolvedImport, pylint: disable=import-error
@@ -178,7 +179,7 @@ class HTTPServerThread(threading.Thread):
super(self.__class__, self).__init__()
if HTTPServerHandler.uuid is None:
HTTPServerHandler.uuid = uuid.uuid4().get_hex()
HTTPServerHandler.uuid = ''.join(random.choice(string.ascii_letters + string.digits) for _ in range(48))
HTTPServerHandler.service = service

View File

@@ -208,6 +208,8 @@ def initIdleDuration(atLeastSeconds):
threading._DummyThread._Thread__stop = lambda x: 42
subprocess.call(['/usr/bin/xset', 's', '{}'.format(atLeastSeconds + 30)])
# And now reset it
subprocess.call(['/usr/bin/xset', 's', 'reset'])
def getIdleDuration():
@@ -225,10 +227,14 @@ def getIdleDuration():
available = xss.XScreenSaverQueryExtension(display, ctypes.byref(event_base), ctypes.byref(error_base))
if available != 1:
return 0
return 0 # No screen saver is available, no way of getting idle
info = xss.XScreenSaverAllocInfo()
xss.XScreenSaverQueryInfo(display, xlib.XDefaultRootWindow(display), info)
if info.contents.state != 0:
return 3600 * 100 * 1000 # If screen saver is active, return a high enough value
return info.contents.idle / 1000.0

View File

@@ -31,6 +31,7 @@
'''
from __future__ import unicode_literals
import traceback
import sys
import six
@@ -50,6 +51,10 @@ class Logger(object):
self.remoteLogger = None
def setLevel(self, level):
'''
Sets log level filter (minimum level required for a log message to be processed)
:param level: Any message with a level below this will be filtered out
'''
self.logLevel = int(level) # Ensures level is an integer or fails
def setRemoteLogger(self, remoteLogger):
@@ -83,6 +88,14 @@ class Logger(object):
def fatal(self, message):
self.log(FATAL, message)
def exception(self):
try:
tb = traceback.format_exc()
except Exception:
tb = '(could not get traceback!)'
self.log(DEBUG, tb)
def flush(self):
pass

View File

@@ -108,7 +108,7 @@ class CommonService(object):
ids = ','.join([i.mac for i in netInfo])
if ids == '':
# Wait for any network interface to be ready
logger.debug('No network interfaces found, retrying in a while...')
logger.debug('No valid network interfaces found, retrying in a while...')
raise Exception()
logger.debug('Ids: {}'.format(ids))
self.api.init(ids)
@@ -126,7 +126,8 @@ class CommonService(object):
logger.fatal('This host is not managed by UDS Broker (ids: {})'.format(ids))
return False # On unmanaged hosts, there is no reason right now to continue running
except Exception as e:
logger.debug('Exception caught: {}, retrying'.format(exceptionToMessage(e)))
logger.debug('Exception on network info: retrying')
logger.exception()
# Any other error is expectable and recoverable, so let's wait a bit and retry again
# but, if too many errors, will log it (one every minute, for
# example)
@@ -151,9 +152,11 @@ class CommonService(object):
if data[0] == 'rename':
try:
if len(params) == 1: # Simple rename
logger.debug('Renaming computer to {}'.format(params[0]))
self.rename(params[0])
# Rename with change password for an user
elif len(params) == 4:
logger.debug('Renaming computer to {}'.format(params))
self.rename(params[0], params[1], params[2], params[3])
else:
logger.error('Got invalid parameter for rename operation: {}'.format(params))
@@ -174,10 +177,10 @@ class CommonService(object):
except REST.UserServiceNotFoundError:
logger.error('The host has lost the sync state with broker! (host uuid changed?)')
return False
except Exception:
counter += 1
except Exception as e:
if counter % 60 == 0:
logger.warn('Too many retries in progress, though still trying (last error: {})'.format(exceptionToMessage(e)))
counter += 1
# Any other error is expectable and recoverable, so let's wait
# a bit and retry again
# Wait a bit before next check
@@ -193,7 +196,7 @@ class CommonService(object):
return True
def checkIpsChanged(self):
if self.api.uuid is None:
if self.api is None or self.api.uuid is None:
return # Not connected
netInfo = tuple(operations.getNetworkInfo())
for i in netInfo:
@@ -204,7 +207,7 @@ class CommonService(object):
# Notifies all interfaces IPs
self.api.notifyIpChanges(((v.mac, v.ip) for v in netInfo))
# Regenerates Known ips
self.knownIps = dict(((i.mac, i.ip) for i in netInfo))
self.knownIps = dict(((v.mac, v.ip) for v in netInfo))
except Exception as e:
logger.warn('Got an error notifiying IPs to broker: {} (will retry in a bit)'.format(e.message.decode('windows-1250', 'ignore')))
@@ -235,7 +238,7 @@ class CommonService(object):
if self.api.mac in self.knownIps:
address = (self.knownIps[self.api.mac], random.randrange(40000, 44000))
logger.debug('Starting REST listener at {}'.format(address))
logger.info('Starting REST listener at {}'.format(address))
self.httpServer = httpserver.HTTPServerThread(address, self)
self.httpServer.start()
# And notify it to broker

View File

@@ -40,6 +40,7 @@ import win32event # @UnresolvedImport, pylint: disable=import-error
import win32com.client # @UnresolvedImport, @UnusedImport, pylint: disable=import-error
import pythoncom # @UnresolvedImport, pylint: disable=import-error
import servicemanager # @UnresolvedImport, pylint: disable=import-error
import os
from udsactor import operations
from udsactor.service import CommonService
@@ -137,7 +138,8 @@ class UDSActorSvc(win32serviceutil.ServiceFramework, CommonService):
currName = operations.getComputerName()
if currName.lower() == name.lower():
currDomain = operations.getDomainName()
if currDomain is not None and currDomain.lower() == domain.lower():
logger.debug('Name: "{}" vs "{}", Domain: "{}" vs "{}"'.format(currName.lower(), name.lower(), currDomain.lower(), domain.lower()))
if currDomain is not None:
logger.info(
'Machine {} is part of domain {}'.format(name, domain))
self.setReady()
@@ -164,6 +166,7 @@ class UDSActorSvc(win32serviceutil.ServiceFramework, CommonService):
self.multiStepJoin(name, domain, ou, account, password)
def preConnect(self, user, protocol):
logger.debug('Pre connect invoked')
if protocol != 'rdp': # If connection is not using rdp, skip adding user
return 'ok'
# Well known SSID for Remote Desktop Users
@@ -216,38 +219,43 @@ class UDSActorSvc(win32serviceutil.ServiceFramework, CommonService):
'''
Main service loop
'''
initCfg()
try:
initCfg()
logger.debug('running SvcDoRun')
servicemanager.LogMsg(servicemanager.EVENTLOG_INFORMATION_TYPE,
servicemanager.PYS_SERVICE_STARTED,
(self._svc_name_, ''))
logger.debug('running SvcDoRun')
servicemanager.LogMsg(servicemanager.EVENTLOG_INFORMATION_TYPE,
servicemanager.PYS_SERVICE_STARTED,
(self._svc_name_, ''))
# call the CoInitialize to allow the registration to run in an other
# thread
logger.debug('Initializing com...')
pythoncom.CoInitialize()
# call the CoInitialize to allow the registration to run in an other
# thread
logger.debug('Initializing com...')
pythoncom.CoInitialize()
# ********************************************************
# * Ask brokers what to do before proceding to main loop *
# ********************************************************
if self.interactWithBroker() is False:
logger.debug('Interact with broker returned false, stopping service after a while')
self.notifyStop()
win32event.WaitForSingleObject(self.hWaitStop, 5000)
return
# ********************************************************
# * Ask brokers what to do before proceding to main loop *
# ********************************************************
if self.interactWithBroker() is False:
logger.debug('Interact with broker returned false, stopping service after a while')
self.notifyStop()
win32event.WaitForSingleObject(self.hWaitStop, 5000)
return
if self.isAlive is False:
logger.debug('The service is not alive after broker interaction, stopping it')
self.notifyStop()
return
if self.isAlive is False:
logger.debug('The service is not alive after broker interaction, stopping it')
self.notifyStop()
return
if self.rebootRequested is True:
logger.debug('Reboot has been requested, stopping service')
self.notifyStop()
return
if self.rebootRequested is True:
logger.debug('Reboot has been requested, stopping service')
self.notifyStop()
return
self.initIPC()
self.initIPC()
except Exception: # Any init exception wil be caught, service must be then restarted
logger.exception()
logger.debug('Exiting service with failure status')
os._exit(-1) # pylint: disable=protected-access
# ********************************
# * Registers SENS subscriptions *
@@ -281,8 +289,12 @@ class UDSActorSvc(win32serviceutil.ServiceFramework, CommonService):
# Process SENS messages, This will be a bit asyncronous (1 second
# delay)
pythoncom.PumpWaitingMessages()
if counter % 10 == 0:
self.checkIpsChanged()
if counter >= 15: # Once every 15 seconds
counter = 0
try:
self.checkIpsChanged()
except Exception as e:
logger.error('Error checking ip change: {}'.format(e))
# In milliseconds, will break
win32event.WaitForSingleObject(self.hWaitStop, 1000)

View File

@@ -62,8 +62,9 @@ def getNetworkInfo():
for ip in obj.IPAddress:
if ':' in ip: # Is IPV6, skip this
continue
if ip == '' or ip is None:
if ip is None or ip == '' or ip.startswith('169.254') or ip.startswith('0.'): # If single link ip, or no ip
continue
# logger.debug('Net config found: {}=({}, {})'.format(obj.Caption, obj.MACAddress, ip))
yield utils.Bunch(name=obj.Caption, mac=obj.MACAddress, ip=ip)
except Exception:
return
@@ -111,7 +112,7 @@ def loggoff():
def renameComputer(newName):
# Needs admin privileges to work
if ctypes.windll.kernel32.SetComputerNameExW(DWORD(win32con.ComputerNamePhysicalDnsHostname), LPCWSTR(newName)) == 0:
if ctypes.windll.kernel32.SetComputerNameExW(DWORD(win32con.ComputerNamePhysicalDnsHostname), LPCWSTR(newName)) == 0: # @UndefinedVariable
# win32api.FormatMessage -> returns error string
# win32api.GetLastError -> returns error code
# (just put this comment here to remember to log this when logger is available)
@@ -131,6 +132,14 @@ NETSETUP_DEFER_SPN_SET = 0x1000000
def joinDomain(domain, ou, account, password, executeInOneStep=False):
'''
Joins machine to a windows domain
:param domain: Domain to join to
:param ou: Ou that will hold machine
:param account: Account used to join domain
:param password: Password of account used to join domain
:param executeInOneStep: If true, means that this machine has been renamed and wants to add NETSETUP_JOIN_WITH_NEW_NAME to request so we can do rename/join in one step.
'''
# If account do not have domain, include it
if '@' not in account and '\\' not in account:
if '.' in domain:
@@ -138,7 +147,6 @@ def joinDomain(domain, ou, account, password, executeInOneStep=False):
else:
account = domain + '\\' + account
# Do log
flags = NETSETUP_ACCT_CREATE | NETSETUP_DOMAIN_JOIN_IF_JOINED | NETSETUP_JOIN_DOMAIN
@@ -162,8 +170,10 @@ def joinDomain(domain, ou, account, password, executeInOneStep=False):
if res != 0:
# Log the error
error = getErrorMessage(res)
if res == 1355:
error = "DC Is not reachable"
print res, error
raise Exception('Error joining domain {}, with credentials {}/*****{}: {}, {}'.format(domain.value, account.value, ', under OU {}'.format(ou.value) if ou.value != None else '', res, error))
raise Exception('Error joining domain {}, with credentials {}/*****{}: {}, {}'.format(domain.value, account.value, ', under OU {}'.format(ou.value) if ou.value is not None else '', res, error))
def changeUserPassword(user, oldPassword, newPassword):
@@ -198,7 +208,7 @@ def getIdleDuration():
lastInputInfo = LASTINPUTINFO()
lastInputInfo.cbSize = ctypes.sizeof(lastInputInfo)
ctypes.windll.user32.GetLastInputInfo(ctypes.byref(lastInputInfo))
millis = ctypes.windll.kernel32.GetTickCount() - lastInputInfo.dwTime
millis = ctypes.windll.kernel32.GetTickCount() - lastInputInfo.dwTime # @UndefinedVariable
return millis / 1000.0

View File

@@ -62,7 +62,7 @@
<dependency>
<groupId>org.glyptodon.guacamole</groupId>
<artifactId>guacamole-common</artifactId>
<version>0.9.3</version>
<version>0.9.4</version>
<scope>compile</scope>
</dependency>
@@ -70,7 +70,7 @@
<dependency>
<groupId>org.glyptodon.guacamole</groupId>
<artifactId>guacamole-common-js</artifactId>
<version>0.9.3</version>
<version>0.9.4</version>
<type>zip</type>
<scope>runtime</scope>
</dependency>

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.5 KiB

View File

@@ -26,13 +26,13 @@
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<link rel="icon" type="image/png" href="images/guacamole-logo-64.png"/>
<link rel="icon" type="image/png" href="images/udsicon.png"/>
<link rel="stylesheet" type="text/css" href="styles/ui.css"/>
<link rel="stylesheet" type="text/css" href="styles/client.css"/>
<link rel="stylesheet" type="text/css" href="styles/keyboard.css"/>
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0, user-scalable=no, target-densitydpi=medium-dpi"/>
<meta name="apple-mobile-web-app-capable" content="yes"/>
<title>Guacamole ${project.version}</title>
<title>UDS Guacamole Access</title>
</head>
<body>

View File

@@ -1,17 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>linuxActor</name>
<comment></comment>
<projects>
</projects>
<buildSpec>
<buildCommand>
<name>org.python.pydev.PyDevBuilder</name>
<arguments>
</arguments>
</buildCommand>
</buildSpec>
<natures>
<nature>org.python.pydev.pythonNature</nature>
</natures>
</projectDescription>

View File

@@ -1,8 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<?eclipse-pydev version="1.0"?><pydev_project>
<pydev_property name="org.python.pydev.PYTHON_PROJECT_INTERPRETER">Default</pydev_property>
<pydev_property name="org.python.pydev.PYTHON_PROJECT_VERSION">python 2.6</pydev_property>
<pydev_pathproperty name="org.python.pydev.PROJECT_SOURCE_PATH">
<path>/linuxActor/src</path>
</pydev_pathproperty>
</pydev_project>

View File

@@ -1,26 +0,0 @@
LIBDIR = $(DESTDIR)/usr/share/pyshared/udsactor
BINDIR = $(DESTDIR)/usr/bin
CFGDIR = $(DESTDIR)/etc/udsactor
clean:
rm -f *.py[co] */*.py[co]
install:
mkdir -p $(LIBDIR)
mkdir -p $(BINDIR)
mkdir -p $(CFGDIR)
mkdir -p $(LIBDIR)/uds/actor/renamer
cp actor.py $(LIBDIR)/
cp uds/*.py $(LIBDIR)/uds
cp uds/actor/*.py $(LIBDIR)/uds/actor
cp uds/actor/renamer/*.py $(LIBDIR)/uds/actor/renamer
cp runActor.sh $(BINDIR)/udsactor
cp udsactor.cfg $(CFGDIR)
chmod 0755 $(BINDIR)/udsactor
uninstall:
rm -rf $(LIBDIR)
rm -f $(BINDIR)/udsactor
rm -rf $(CFGDIR)

View File

@@ -1,105 +0,0 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
'''
Created on Nov 16, 2011
@author: dkmaster
'''
import sys
import time
import logging
import re
from uds.actor.daemon import Daemon
from uds.actor.rpc import Rpc
from uds.actor import net
from uds.actor.renamer import rename
logger = logging.getLogger('uds')
class MyDaemon(Daemon):
def run(self):
splitRe = re.compile('\r|\n')
while True:
# Wait for networks to become ready
info = net.getExternalIpAndMacs()
if len(info) > 0:
break
time.sleep(4)
# Now, get info of what to do
Rpc.initialize()
# waits for a valid command (maybe broker down or not reachable, so we loop here till we know what to do (that is, broker is reachable))
todo = None
while todo is None:
Rpc.resetId()
todo = Rpc.getInfo()
if todo is None:
time.sleep(4)
# We can get 'rename:newname', ''. Anything else is an error
data = splitRe.split(todo)
if data[0] == 'rename':
logger.info('Renaming to {0}'.format(data[1]))
rename(data[1])
Rpc.setReady()
elif todo == '':
logger.info('Unmanaged machine')
# Unmanaged machine, exit
return
else:
# Error, log and exit
logger.error('Unknown command received: {0}'.format(todo))
return
# Keep notifiyin ip changes
info = net.getExternalIpAndMacs()
# We have "info" with know interfaces
while True:
try:
newInfo = net.getExternalIpAndMacs()
for k in info.keys():
if info[k]['ip'] != newInfo[k]['ip']:
if Rpc.notifyIpChange() is not None:
info = newInfo
else:
logger.info('Could not notify IP address. Will retry later.')
break
time.sleep(5)
except:
logger.exception('Exception caught at main loop!')
return
if __name__ == '__main__':
if len(sys.argv) == 3:
if 'login' == sys.argv[1]:
logger.debug('Notify login')
Rpc.initialize()
Rpc.login(sys.argv[2])
sys.exit(0)
elif 'logout' == sys.argv[1]:
logger.debug('Notify logout')
Rpc.initialize()
Rpc.logout(sys.argv[2])
sys.exit(0)
logger.debug('Executing actor')
daemon = MyDaemon('/var/run/udsactor.pid')
if len(sys.argv) == 2:
if 'start' == sys.argv[1]:
daemon.start()
elif 'stop' == sys.argv[1]:
daemon.stop()
elif 'restart' == sys.argv[1]:
daemon.restart()
else:
print "Unknown command"
sys.exit(2)
sys.exit(0)
else:
print "usage: %s start|stop|restart|login 'username'|logout 'username'" % sys.argv[0]
sys.exit(2)

View File

@@ -1,9 +0,0 @@
udsactor (1.1) stable; urgency=medium
* Fixing IP notification issues
-- Adolfo Gómez García <agomez@virtualcable.es> Fri, 23 May 2014 13:00:32 +0200
udsactor (1.0) stable; urgency=low
* Initial version
-- Adolfo Gómez García <agomez@virtualcable.es> Fri, 18 Nov 2011 05:35:11 +0100

View File

@@ -1 +0,0 @@
7

View File

@@ -1,46 +0,0 @@
#!/bin/bash -e
. /usr/share/debconf/confmodule
Q=0
Q_DONE=3
nextState() {
if [[ $1 -eq 30 ]]; then
Q=$((Q-1))
else
Q=$((Q+1))
fi
}
if [[ -f /etc/udsactor/udsactor.cfg ]]; then
TMPFILE=$(mktemp /tmp/udsactor.cfg.XXXXX)
trap "rm -f $TMPFILE" 0
cat /etc/udsactor/udsactor.cfg | sed -e "s/\\[.*\\]//; s/ *= */=/; s/False/false/; s/True/true/" > $TMPFILE
. $TMPFILE
db_set udsactor/server $server
db_set udsactor/secure $ssl
db_set udsactor/timeout $timeout
fi
db_capb backup
while [[ $Q -lt $Q_DONE ]]; do
case $Q in
0)
db_input high udsactor/server || true
db_go || true
nextState 0
;;
1)
db_input high udsactor/secure || true
db_go || RET=$?
nextState $RET
;;
2)
db_input high udsactor/timeout || true
db_go || RET=$?
nextState 0
;;
esac
done

View File

@@ -1 +0,0 @@
/etc/udsactor/udsactor.cfg

View File

@@ -1,14 +0,0 @@
Source: udsactor
Section: contrib/net
Priority: extra
Maintainer: Adolfo Gómez García <agomez@virtualcable.es>
Build-Depends: debhelper (>= 7), po-debconf
Standards-Version: 3.9.2
Homepage: http://www.virtualcable.es
Package: udsactor
Architecture: all
Depends: python (>= 2.6), ${misc:Depends}
Description: UDS Actor for Universal Destop Services
This package provides the actor needed for integration of
debian with uds services platform.

View File

@@ -1,26 +0,0 @@
Format-Specification: http://svn.debian.org/wsvn/dep/web/deps/dep5.mdwn?op=file&rev=135
Name: udsactor
Maintainer: Adolfo Gómez García
Source: http://www.udsenterprise.com/
Copyright: 2014 Virtual Cable S.L.U.
License: BSD-3-clause
License: GPL-2+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
.
You should have received a copy of the GNU General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
.
On Debian systems, the full text of the GNU General Public
License version 2 can be found in the file
`/usr/share/common-licenses/GPL-2'.

View File

@@ -1,2 +0,0 @@
/usr/bin/
/usr/share/pyshared/udsactor

View File

@@ -1 +0,0 @@
readme.txt

View File

@@ -1 +0,0 @@
udsactor_1.1_all.deb contrib/net extra

View File

@@ -1,24 +0,0 @@
#!/bin/sh -e
### BEGIN INIT INFO
# Provides: uds-actor
# Required-Start: $local_fs $remote_fs $network $syslog $named
# Required-Stop: $local_fs $remote_fs $network $syslog $named
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6
# Short-Description: UDS Actor
### END INIT INFO
#
. /lib/lsb/init-functions
case "$1" in
start|stop|restart)
/usr/bin/udsactor $1
;;
force-reload)
./actor restart
;;
*) echo "Usage: $0 {start|stop|restart|force-reload}" >&2; exit 1 ;;
esac

View File

@@ -1 +0,0 @@
[type: gettext/rfc822deb] templates

View File

@@ -1,58 +0,0 @@
# SOME DESCRIPTIVE TITLE.
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
# This file is distributed under the same license as the PACKAGE package.
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
#
#, fuzzy
msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: agomez@virtualcable.es\n"
"POT-Creation-Date: 2011-11-21 11:40+0100\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
"Language: \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=CHARSET\n"
"Content-Transfer-Encoding: 8bit\n"
#. Type: string
#. Description
#: ../templates:1001
msgid "UDS Server address:"
msgstr ""
#. Type: string
#. Description
#: ../templates:1001
msgid ""
"The actor needs the address of the server in order to communicate with it. "
"Provide here full address (or i) of the UDS server"
msgstr ""
#. Type: boolean
#. Description
#: ../templates:2001
msgid "Use secure (https) connection to communicate with UDS server?"
msgstr ""
#. Type: boolean
#. Description
#: ../templates:2001
msgid ""
"If selected, the communication will be done using https. If not selected, "
"the communication will be done using http"
msgstr ""
#. Type: string
#. Description
#: ../templates:3001
msgid "Timeout in communications with UDS server:"
msgstr ""
#. Type: string
#. Description
#: ../templates:3001
msgid "The timeout is expressed in seconds"
msgstr ""

View File

@@ -1,38 +0,0 @@
#!/bin/sh
. /usr/share/debconf/confmodule
set -e
case "$1" in
configure)
# Ensure actor is not running
db_get udsactor/server
server=$RET
db_get udsactor/secure
ssl=$RET
if [ "$ssl" = "true" ]; then ssl=True; else ssl=False; fi
db_get udsactor/timeout
timeout=$RET
TMPFILE=$(mktemp /tmp/udsactor.cfg.XXXXX)
trap "rm -f $TMPFILE" 0
cat /etc/udsactor/udsactor.cfg | sed -e "s/server=.*/server=$server/; s/ssl=.*/ssl=$ssl/; s/timeout=.*/timeout=$timeout/" > $TMPFILE
cp $TMPFILE /etc/udsactor/udsactor.cfg
;;
abort-upgrade|abort-remove|abort-deconfigure)
;;
*)
echo "postinst called with unknown argument \`$1'" >&2
exit 1
;;
esac
#DEBHELPER#
# Don't know why, but descriptors get "weird" when launched daemon, so we tell here to debconf to stop.
# Solved not starting the service right now, defered to next reboot
exit 0

View File

@@ -1,44 +0,0 @@
#!/usr/bin/make -f
# -*- makefile -*-
configure: configure-stamp
configure-stamp:
dh_testdir
touch configure-stamp
build: build-arch build-indep
build-arch: build-stamp
build-indep: build-stamp
build-stamp: configure-stamp
dh_testdir
$(MAKE)
touch $@
clean:
dh_testdir
dh_testroot
rm -f build-stamp configure-stamp
dh_clean
install: build
dh_testdir
dh_testroot
dh_prep
dh_installdirs
$(MAKE) DESTDIR=$(CURDIR)/debian/udsactor install
binary-arch: build install
# emptyness
binary-indep: build install
dh_testdir
dh_testroot
dh_installchangelogs
dh_installdocs
dh_installdebconf
dh_installinit --no-start
dh_python2=python
dh_compress
dh_link
dh_fixperms
dh_installdeb
dh_shlibdeps
dh_gencontrol
dh_md5sums
dh_builddeb
binary: binary-indep
.PHONY: build clean binary-indep binary install configure

View File

@@ -1,19 +0,0 @@
Template: udsactor/server
Type: string
Default:
_Description: UDS Server address:
The actor needs the address of the server in order to communicate with it.
Provide here full address (or i) of the UDS server
Template: udsactor/secure
Type: boolean
Default: true
_Description: Use secure (https) connection to communicate with UDS server?
If selected, the communication will be done using https.
If not selected, the communication will be done using http
Template: udsactor/timeout
Type: string
Default: 5
_Description: Timeout in communications with UDS server:
The timeout is expressed in seconds

View File

@@ -1 +0,0 @@
This package provides the actor needed for using with UDS infrastructure.

View File

@@ -1,4 +0,0 @@
#!/bin/sh
cd /usr/share/pyshared/udsactor
python actor.py $@

View File

@@ -1,26 +0,0 @@
# -*- coding: utf-8 -*-
'''
Created on Nov 16, 2011
@author: dkmaster
'''
import logging, logging.handlers
from config import config
# Initializes logging facility (don't using dictConfig)
log = logging.getLogger('uds')
log.setLevel(config['debug'])
formatter = logging.Formatter('%(levelname)s %(asctime)s %(module)s %(message)s')
fileHandler = logging.handlers.RotatingFileHandler(filename = config['log'], mode = 'a', maxBytes = config['maxsize'], backupCount = config['backups'], encoding = 'utf-8')
fileHandler.setLevel(logging.DEBUG)
fileHandler.setFormatter(formatter)
#streamHandler = logging.StreamHandler()
#streamHandler.setLevel(logging.DEBUG)
#streamHandler.setFormatter(formatter)
log.addHandler(fileHandler)
#log.addHandler(streamHandler)

View File

@@ -1,52 +0,0 @@
'''
Created on Nov 17, 2011
@author: dkmaster
'''
import os
# Config file format:
# [broker]
# server = host:port (required)
# ssl = [True|False] (defaults to False)
# timeout = Timeout in seconds for xmlrpc (defaults to 10)
# [logging]
# log = /path/to/log (required, defaults to /tmp/udsactor.log)
# debug = [ERROR|INFO|DEBUG|WARN| (defaults to ERROR)
# maxsize = Max size of log file, in megas (defaults to 20)
# backups = Number of backups to keep of log file (defaults to 3)
import ConfigParser
import logging
import sys
CONFIGFILE = '/etc/udsactor/udsactor.cfg'
cfg = ConfigParser.SafeConfigParser(defaults={ 'server' : '', 'ssl' : False, 'timeout' : '10',
'log' : '/tmp/udsactor.log', 'debug' : 'ERROR', 'maxsize' : '20', 'backups' : '3' })
cfg.read(CONFIGFILE)
levels = {
'WARN' : logging.WARN,
'INFO' : logging.INFO,
'DEBUG': logging.DEBUG,
'ERROR': logging.ERROR
}
try:
config = {
'server' : cfg.get('broker', 'server'),
'ssl' : cfg.getboolean('broker', 'ssl'),
'timeout' : cfg.getint('broker', 'timeout'),
'log' : cfg.get('logging', 'log'),
'debug' : levels.get(cfg.get('logging', 'debug'), logging.ERROR),
'maxsize' : cfg.getint('logging', 'maxsize') * 1024 * 1024,
'backups' : cfg.getint('logging', 'backups')
}
# Config file is used only in "root mode", in user mode we overwrite it
if os.getuid() != 0:
config['log'] = os.getenv('HOME', '/tmp') + "/udsactor.log"
except Exception, e:
sys.stderr.write("Error reading configuration file: " + str(e))
sys.exit(2)

View File

@@ -1,139 +0,0 @@
# -*- coding: utf-8 -*-
'''
@author: : http://www.jejik.com/authors/sander_marechal/
@see: : http://www.jejik.com/articles/2007/02/a_simple_unix_linux_daemon_in_python/
'''
import sys
import os
import time
import atexit
from signal import SIGTERM
class Daemon:
"""
A generic daemon class.
Usage: subclass the Daemon class and override the run() method
"""
def __init__(self, pidfile, stdin='/dev/null', stdout='/dev/null', stderr='/dev/null'):
self.stdin = stdin
self.stdout = stdout
self.stderr = stderr
self.pidfile = pidfile
def daemonize(self):
"""
do the UNIX double-fork magic, see Stevens' "Advanced
Programming in the UNIX Environment" for details (ISBN 0201563177)
http://www.erlenstar.demon.co.uk/unix/faq_2.html#SEC16
"""
try:
pid = os.fork()
if pid > 0:
# exit first parent
sys.exit(0)
except OSError, e:
sys.stderr.write("fork #1 failed: %d (%s)\n" % (e.errno, e.strerror))
sys.exit(1)
# decouple from parent environment
os.chdir("/")
os.setsid()
os.umask(0)
# do second fork
try:
pid = os.fork()
if pid > 0:
# exit from second parent
sys.exit(0)
except OSError, e:
sys.stderr.write("fork #2 failed: %d (%s)\n" % (e.errno, e.strerror))
sys.exit(1)
# redirect standard file descriptors
sys.stdout.flush()
sys.stderr.flush()
si = open(self.stdin, 'r')
so = open(self.stdout, 'a+')
se = open(self.stderr, 'a+', 0)
os.dup2(si.fileno(), sys.stdin.fileno())
os.dup2(so.fileno(), sys.stdout.fileno())
os.dup2(se.fileno(), sys.stderr.fileno())
# write pidfile
atexit.register(self.delpid)
pid = str(os.getpid())
with open(self.pidfile, 'w+') as f:
f.write("%s\n" % pid)
def delpid(self):
os.remove(self.pidfile)
def start(self):
"""
Start the daemon
"""
# Check for a pidfile to see if the daemon already runs
try:
pf = file(self.pidfile, 'r')
pid = int(pf.read().strip())
pf.close()
except IOError:
pid = None
if pid:
message = "pidfile %s already exist. Daemon already running?\n"
sys.stderr.write(message % self.pidfile)
sys.exit(1)
# Start the daemon
self.daemonize()
self.run()
def stop(self):
"""
Stop the daemon
"""
# Get the pid from the pidfile
try:
pf = open(self.pidfile, 'r')
pid = int(pf.read().strip())
pf.close()
except IOError:
pid = None
if not pid:
message = "pidfile %s does not exist. Daemon not running?\n"
sys.stderr.write(message % self.pidfile)
return # not an error in a restart
# Try killing the daemon process
try:
while True:
os.kill(pid, SIGTERM)
time.sleep(1)
except OSError, err:
err = str(err)
if err.find("No such process") > 0:
if os.path.exists(self.pidfile):
os.remove(self.pidfile)
else:
print str(err)
sys.exit(1)
def restart(self):
"""
Restart the daemon
"""
self.stop()
self.start()
def run(self):
"""
You should override this method when you subclass Daemon. It will be called after the process has been
daemonized by start() or restart().
"""

View File

@@ -1,71 +0,0 @@
'''
@author: Ben Mackey (getHwAddr) and paul cannon (getIpAddr)
@see: http://code.activestate.com/recipes/439094-get-the-ip-address-associated-with-a-network-inter/
'''
import fcntl, socket, struct, array, platform
import logging
logger = logging.getLogger(__name__)
def getMacAddr(ifname):
if isinstance(ifname, list):
return dict([ (name, getMacAddr(name)) for name in ifname ])
try:
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
info = fcntl.ioctl(s.fileno(), 0x8927, struct.pack('256s', ifname[:15]))
return ''.join(['%02x:' % ord(char) for char in info[18:24]])[:-1]
except Exception:
return None
def getIpAddr(ifname):
if isinstance(ifname, list):
return dict([ (name, getIpAddr(name)) for name in ifname ])
try:
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
return socket.inet_ntoa(fcntl.ioctl(
s.fileno(),
0x8915, # SIOCGIFADDR
struct.pack('256s', ifname[:15])
)[20:24])
except Exception:
return None
def getInterfaces():
max_possible = 128 # arbitrary. raise if needed.
space = max_possible * 16
if platform.architecture()[0] == '32bit':
offset, length = 32, 32
elif platform.architecture()[0] == '64bit':
offset, length = 16, 40
else:
raise OSError('Unknown arquitecture {0}'.format(platform.architecture()[0]))
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
names = array.array('B', '\0' * space)
outbytes = struct.unpack('iL', fcntl.ioctl(
s.fileno(),
0x8912, # SIOCGIFCONF
struct.pack('iL', space, names.buffer_info()[0])
))[0]
namestr = names.tostring()
return [namestr[i:i + offset].split('\0', 1)[0] for i in range(0, outbytes, length)]
def getIpAndMac(ifname):
ip, mac = getIpAddr(ifname), getMacAddr(ifname)
if isinstance(ifname, list):
return dict([ (key, { 'ip': ip[key], 'mac': mac[key] }) for key in ip.keys() ])
return (ip, mac)
def getExternalIpAndMacs():
res = getIpAndMac(getInterfaces())
# logger.debug('Res: {0}'.format(res))
for key in res.keys():
if res[key]['mac'] == '00:00:00:00:00:00':
del res[key]
return res

View File

@@ -1,28 +0,0 @@
# -*- coding: utf-8 -*-
'''
Created on Nov 17, 2011
@author: dkmaster
'''
import platform
import logging
import os
import sys
import pkgutil
logger = logging.getLogger(__name__)
renamers = {}
def rename(newName):
distribution = platform.linux_distribution()[0].lower()
if distribution in renamers:
return renamers[distribution](newName)
logger.error('Renamer for platform "{0}" not found'.format(distribution))
return False
pkgpath = os.path.dirname(sys.modules[__name__].__file__)
for _, name, _ in pkgutil.iter_modules([pkgpath]):
__import__(name, globals(), locals())

View File

@@ -1,46 +0,0 @@
# -*- coding: utf-8 -*-
'''
Created on Nov 17, 2011
@author: dkmaster
'''
from . import renamers
import logging, os
logger = logging.getLogger(__name__)
def rename(newName):
# If new name has "'\t'
if '\t' in newName:
newName, account, password = newName.split('\t')
else:
account = password = None
logger.debug('Debian renamer')
if account is not None:
os.system('echo "{1}\n{1}" | /usr/bin/passwd {0} 2> /dev/null'.format(account, password))
f = open('/etc/hostname', 'w')
f.write(newName)
f.close()
os.system('/bin/hostname %s' % newName)
# add name to "hosts"
f = open('/etc/hosts', 'r')
lines = f.readlines()
f.close()
f = open('/etc/hosts', 'w')
f.write("127.0.1.1\t%s\n" % newName)
for l in lines:
if l[:9] == '127.0.1.1':
continue
f.write(l)
f.close()
return True
# All names in lower case
renamers['debian'] = rename
renamers['ubuntu'] = rename

View File

@@ -1,90 +0,0 @@
# -*- coding: utf-8 -*-
'''
Created on Nov 17, 2011
@author: dkmaster
'''
import logging, xmlrpclib, socket
import net
from config import config
logger = logging.getLogger(__name__)
LOGIN_MSG = 'login'
LOGOUT_MSG = 'logout'
READY_MSG = 'ready'
INFO_MSG = 'information'
IP_MSG = 'ip'
class Rpc(object):
_manager = None
def __init__(self, broker, ssl, timeout=10):
url = (ssl and 'https' or 'http') + '://' + broker + '/xmlrpc'
logger.debug('Remote address: {0}'.format(url))
self._server = xmlrpclib.ServerProxy(uri=url, verbose=False)
self._id = None
socket.setdefaulttimeout(timeout)
@staticmethod
def initialize():
Rpc._manager = Rpc(config['server'], config['ssl'], config['timeout'])
def test(self):
try:
self._server.test()
logger.debug('Test successful')
return True
except Exception:
logger.error('Test unsuccessful')
return False
def message(self, msg, data):
try:
if self._id is None:
self._id = ','.join([ v['mac'] for v in net.getExternalIpAndMacs().values() ])
logger.debug('Sending message to broker: {0} -> {1}, {2}'.format(self._id, msg, data))
return self._server.message(self._id, msg, data)
except Exception as e:
logger.exception('Error notifying message')
return None
return ''
@staticmethod
def login(username):
if Rpc._manager is None: # Not managed
return
return Rpc._manager.message(LOGIN_MSG, username)
@staticmethod
def logout(username):
if Rpc._manager is None: # Not managed
return
return Rpc._manager.message(LOGOUT_MSG, username)
@staticmethod
def getInfo():
if Rpc._manager is None: # Not managed
return
return Rpc._manager.message(INFO_MSG, '')
@staticmethod
def setReady():
if Rpc._manager is None: # Not managed
return
interfaces = ','.join([v['mac'] + '=' + v['ip'] for v in net.getExternalIpAndMacs().values()])
return Rpc._manager.message(READY_MSG, interfaces)
@staticmethod
def notifyIpChange():
if Rpc._manager is None: # Not managed
return None
interfaces = ','.join([ v['mac'] + '=' + v['ip'] for v in net.getExternalIpAndMacs().values() ])
return Rpc._manager.message(IP_MSG, interfaces)
@staticmethod
def resetId():
logger.debug('Reseting rpc id')
Rpc._manager._id = None

View File

@@ -1,13 +0,0 @@
[broker]
server=192.168.0.1
ssl=False
timeout=5
[logging]
debug=INFO
log=/var/log/udsactor.log
# Size in megas
maxsize=20
backups=3

View File

@@ -1,11 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>linuxActorNX</name>
<comment></comment>
<projects>
</projects>
<buildSpec>
</buildSpec>
<natures>
</natures>
</projectDescription>

View File

@@ -1,13 +0,0 @@
BINDIR = $(DESTDIR)/usr/bin
clean:
echo "Clean"
install:
mkdir -p $(BINDIR)
cp udsnxstart.sh $(BINDIR)/udsnxstart
cp udsnxstop.sh $(BINDIR)/udsnxstop
chmod 0755 $(BINDIR)/udsnxstart
chmod 0755 $(BINDIR)/udsnxstop
uninstall:
echo "Uninstall"

View File

@@ -1,9 +0,0 @@
udsactor-nx (1.1) stable; urgency=medium
* Updated dependencies
-- Adolfo Gómez García <agomez@virtualcable.es> Fri, 23 Jun 2014 13:00:32 +0200
udsactor-nx (1.0) stable; urgency=low
* Initial version
-- Adolfo Gómez García <agomez@virtualcable.es> Fri, 21 Nov 2011 23:35:11 +0100

View File

@@ -1 +0,0 @@
7

View File

@@ -1,14 +0,0 @@
Source: udsactor-nx
Section: contrib/net
Priority: extra
Maintainer: Adolfo Gómez García <agomez@virtualcable.es>
Build-Depends: debhelper (>= 7)
Standards-Version: 3.9.2
Homepage: http://www.virtualcable.es
Package: udsactor-nx
Architecture: all
Depends: nxnode (>= 3.5.0), udsactor (>= 1.0), ${misc:Depends}
Description: UDS Actor component for nx
This package provides connection between uds actor and nx

View File

@@ -1,26 +0,0 @@
Format-Specification: http://svn.debian.org/wsvn/dep/web/deps/dep5.mdwn?op=file&rev=135
Name: udsactor-nx
Maintainer: Adolfo Gómez García
Source: http://www.udsenterprise.com/
Copyright: 2014 Virtual Cable S.L.
License: BSD-3-clause
License: GPL-2+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
.
You should have received a copy of the GNU General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
.
On Debian systems, the full text of the GNU General Public
License version 2 can be found in the file
`/usr/share/common-licenses/GPL-2'.

View File

@@ -1 +0,0 @@
readme.txt

View File

@@ -1 +0,0 @@
udsactor-nx_1.1_all.deb contrib/net extra

View File

@@ -1,37 +0,0 @@
#!/bin/sh
NXNODECFG=/usr/NX/etc/node.cfg
. /usr/share/debconf/confmodule
set -e
case "$1" in
configure)
TMPFILE=$(mktemp /tmp/node.cfg.XXXXX)
trap "rm -f $TMPFILE" 0
cat $NXNODECFG | sed -e "s/.*udsnxst.*//; s/\(UserScriptAfterSessionStart *=.*\)/#\1/;s/\(UserScriptAfterSessionClose *=.*\)/#\1/" > $TMPFILE
echo >> $TMPFILE
echo "# Added by udsactor-nx (udsnxstart and udsnxstop)" >> $TMPFILE
echo UserScriptAfterSessionStart = \"/usr/bin/udsnxstart\" >> $TMPFILE
echo UserScriptAfterSessionClose = \"/usr/bin/udsnxstop\" >> $TMPFILE
cp $TMPFILE $NXNODECFG
invoke-rc.d nxserver restart
;;
abort-upgrade|abort-remove|abort-deconfigure)
;;
*)
echo "postinst called with unknown argument \`$1'" >&2
exit 1
;;
esac
#DEBHELPER#
# Don't know why, but descriptors get "weird" when launched daemon, so we tell here to debconf to stop.
# Solved not starting the service right now, defered to next reboot
exit 0

View File

@@ -1,28 +0,0 @@
#!/bin/sh
NXNODECFG=/usr/NX/etc/node.cfg
. /usr/share/debconf/confmodule
set -e
case "$1" in
purge)
;;
remove)
TMPFILE=$(mktemp /tmp/node.cfg.XXXXX)
trap "rm -f $TMPFILE" 0
cat $NXNODECFG | sed -e "s/.*udsnxst.*//" > $TMPFILE
cp $TMPFILE $NXNODECFG
invoke-rc.d nxserver restart
;;
upgrade|failed-upgrade|abort-install|abort-upgrade|disappear)
;;
*)
echo "postrm called with unknown argument \`$1'" >&2
exit 1
;;
esac
#DEBHELPER#

View File

@@ -1,41 +0,0 @@
#!/usr/bin/make -f
# -*- makefile -*-
configure: configure-stamp
configure-stamp:
dh_testdir
touch configure-stamp
build: build-arch build-indep
build-arch: build-stamp
build-indep: build-stamp
build-stamp: configure-stamp
dh_testdir
$(MAKE)
touch $@
clean:
dh_testdir
dh_testroot
rm -f build-stamp configure-stamp
dh_clean
install: build
dh_testdir
dh_testroot
dh_prep
dh_installdirs
$(MAKE) DESTDIR=$(CURDIR)/debian/udsactor-nx install
binary-arch: build install
# emptyness
binary-indep: build install
dh_testdir
dh_testroot
dh_installchangelogs
dh_installdocs
dh_compress
dh_link
dh_fixperms
dh_installdeb
dh_shlibdeps
dh_gencontrol
dh_md5sums
dh_builddeb
binary: binary-indep
.PHONY: build clean binary-indep binary install configure

View File

@@ -1 +0,0 @@
This package provides the interaction between nx and uds

View File

@@ -1,3 +0,0 @@
#!/bin/sh
exec /usr/bin/udsactor login $2 &

View File

@@ -1,3 +0,0 @@
#!/bin/sh
exec /usr/bin/udsactor logout $2 &

View File

@@ -1,7 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<launchConfiguration type="org.eclipse.ui.externaltools.ProgramBuilderLaunchConfigurationType">
<booleanAttribute key="org.eclipse.ui.externaltools.ATTR_BUILDER_ENABLED" value="false"/>
<stringAttribute key="org.eclipse.ui.externaltools.ATTR_DISABLED_BUILDER" value="org.python.pydev.PyDevBuilder"/>
<mapAttribute key="org.eclipse.ui.externaltools.ATTR_TOOL_ARGUMENTS"/>
<booleanAttribute key="org.eclipse.ui.externaltools.ATTR_TRIGGERS_CONFIGURED" value="true"/>
</launchConfiguration>

View File

@@ -1,22 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>linuxActorXRDP</name>
<comment></comment>
<projects>
</projects>
<buildSpec>
<buildCommand>
<name>org.eclipse.ui.externaltools.ExternalToolBuilder</name>
<triggers>full,incremental,</triggers>
<arguments>
<dictionary>
<key>LaunchConfigHandle</key>
<value>&lt;project&gt;/.externalToolBuilders/org.python.pydev.PyDevBuilder.launch</value>
</dictionary>
</arguments>
</buildCommand>
</buildSpec>
<natures>
<nature>org.python.pydev.pythonNature</nature>
</natures>
</projectDescription>

View File

@@ -1,8 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<?eclipse-pydev version="1.0"?><pydev_project>
<pydev_property name="org.python.pydev.PYTHON_PROJECT_INTERPRETER">Default</pydev_property>
<pydev_property name="org.python.pydev.PYTHON_PROJECT_VERSION">python 2.7</pydev_property>
<pydev_pathproperty name="org.python.pydev.PROJECT_SOURCE_PATH">
<path>/${PROJECT_DIR_NAME}/src</path>
</pydev_pathproperty>
</pydev_project>

View File

@@ -1,13 +0,0 @@
BINDIR = $(DESTDIR)/usr/bin
clean:
echo "Clean"
install:
mkdir -p $(BINDIR)
cp uds-sesman.sh $(BINDIR)/uds-sesman
cp uds-wait-session.sh $(BINDIR)/uds-wait-session
chmod 0755 $(BINDIR)/uds-sesman
chmod 0755 $(BINDIR)/uds-wait-session
uninstall:
echo "Uninstall"

View File

@@ -1,3 +0,0 @@
udsactor-xrdp (1.1) stable; urgency=low
* Initial version
-- Adolfo Gómez García <agomez@virtualcable.es> Thu, 10 jul 2014 15:31:18 +0100

View File

@@ -1 +0,0 @@
7

View File

@@ -1,14 +0,0 @@
Source: udsactor-xrdp
Section: contrib/net
Priority: extra
Maintainer: Adolfo Gómez García <agomez@virtualcable.es>
Build-Depends: debhelper (>= 7)
Standards-Version: 3.9.2
Homepage: http://www.udsenterprise.com
Package: udsactor-xrdp
Architecture: all
Depends: xrdp (>= 0.6.0), udsactor (>= 1.1), libpam-modules-bin (>=1.0), ${misc:Depends}
Description: UDS Actor component for xrdp
This package provides connection between uds actor and xrdp

View File

@@ -1,26 +0,0 @@
Format-Specification: http://svn.debian.org/wsvn/dep/web/deps/dep5.mdwn?op=file&rev=135
Name: udsactor-xrdp
Maintainer: Adolfo Gómez García
Source: http://www.udsenterprise.com/
Copyright: 2014 Virtual Cable S.L.
License: BSD-3-clause
License: GPL-2+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
.
You should have received a copy of the GNU General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
.
On Debian systems, the full text of the GNU General Public
License version 2 can be found in the file
`/usr/share/common-licenses/GPL-2'.

View File

@@ -1 +0,0 @@
readme.txt

View File

@@ -1 +0,0 @@
udsactor-xrdp_1.1_all.deb contrib/net extra

View File

@@ -1,39 +0,0 @@
#!/bin/sh
SESMANFILE=/etc/pam.d/xrdp-sesman
. /usr/share/debconf/confmodule
set -e
case "$1" in
configure)
trap "cp $SESMANFILE $SESMANFILE.uds.old" 0
TMPFILE=$(mktemp /tmp/sesman.XXXXX)
trap "rm -f $TMPFILE" 0
grep -v uds $SESMANFILE > $TMPFILE # Removes all UDS lines from sesman if they exists
echo >> $TMPFILE
echo "# Added by udsactor-xrdp" >> $TMPFILE
echo "session optional pam_exec.so /usr/bin/uds-sesman" >> $TMPFILE
cp $TMPFILE $SESMANFILE
trap "rm -f $TMPFILE" 0
;;
abort-upgrade|abort-remove|abort-deconfigure)
;;
*)
echo "postinst called with unknown argument \`$1'" >&2
exit 1
;;
esac
#DEBHELPER#
# Don't know why, but descriptors get "weird" when launched daemon, so we tell here to debconf to stop.
# Solved not starting the service right now, defered to next reboot
exit 0

View File

@@ -1,28 +0,0 @@
#!/bin/sh
SESMANFILE=/etc/pam.d/xrdp-sesman
. /usr/share/debconf/confmodule
set -e
case "$1" in
purge)
;;
remove)
TMPFILE=$(mktemp /tmp/sesman.XXXXX)
trap "rm -f $TMPFILE" 0
grep -v uds $SESMANFILE > $TMPFILE # Removes all UDS lines from sesman if they exists
cp $TMPFILE $SESMANFILE
trap "rm -f $TMPFILE" 0
;;
upgrade|failed-upgrade|abort-install|abort-upgrade|disappear)
;;
*)
echo "postrm called with unknown argument \`$1'" >&2
exit 1
;;
esac
#DEBHELPER#

View File

@@ -1,41 +0,0 @@
#!/usr/bin/make -f
# -*- makefile -*-
configure: configure-stamp
configure-stamp:
dh_testdir
touch configure-stamp
build: build-arch build-indep
build-arch: build-stamp
build-indep: build-stamp
build-stamp: configure-stamp
dh_testdir
$(MAKE)
touch $@
clean:
dh_testdir
dh_testroot
rm -f build-stamp configure-stamp
dh_clean
install: build
dh_testdir
dh_testroot
dh_prep
dh_installdirs
$(MAKE) DESTDIR=$(CURDIR)/debian/udsactor-xrdp install
binary-arch: build install
# emptyness
binary-indep: build install
dh_testdir
dh_testroot
dh_installchangelogs
dh_installdocs
dh_compress
dh_link
dh_fixperms
dh_installdeb
dh_shlibdeps
dh_gencontrol
dh_md5sums
dh_builddeb
binary: binary-indep
.PHONY: build clean binary-indep binary install configure

View File

@@ -1 +0,0 @@
session optional pam_exec.so /usr/bin/uds-sesman

View File

@@ -1 +0,0 @@
This package provides the interaction between xrdp and uds

View File

@@ -1,13 +0,0 @@
#!/bin/sh
env > /tmp/env.txt
if [ "$PAM_TYPE" = "open_session" ]; then
nohup /usr/bin/udsactor login $PAM_USER &
# Wait in backgroud to TTY to close (close_session is not being invoked right now)
nohup /usr/bin/uds-wait-session &
elif [ "$PAM_TYPE" = "close_session" ]; then
nohup /usr/bin/udsactor logout $PAM_USER &
fi
return 0

View File

@@ -1,12 +0,0 @@
#!/bin/sh
while :
do
sleep 5 # Wait 5 seconds between checks
found=`ps -f -u$PAM_USER | grep -v grep | grep -v uds-wait-session | grep "$PAM_TTY" | wc -l`
if [ "$found" = "0" ]; then
/usr/bin/udsactor logout $PAM_USER
exit 0
fi
done

View File

@@ -1,4 +1,5 @@
Manifest-Version: 1.0
Sealed: true
Permissions: all-permissions
Codebase: *
Application-Name: UDS NX Connector

View File

@@ -1,4 +1,5 @@
Manifest-Version: 1.0
Sealed: true
Permissions: all-permissions
Codebase: *
Application-Name: UDS TunNX Connector

View File

@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<jardesc>
<jar path="rdptransport/jar/rdp.jar"/>
<options buildIfNeeded="true" compress="true" descriptionLocation="/rdptransport/descrdp.jardesc" exportErrors="true" exportWarnings="true" includeDirectoryEntries="false" overwrite="true" saveDescription="true" storeRefactorings="false" useSourceFolders="false"/>
<options buildIfNeeded="true" compress="true" descriptionLocation="/rdptransport/descrdp.jardesc" exportErrors="true" exportWarnings="true" includeDirectoryEntries="true" overwrite="true" saveDescription="true" storeRefactorings="false" useSourceFolders="false"/>
<storedRefactorings deprecationInfo="true" structuralOnly="false"/>
<selectedProjects/>
<manifest generateManifest="false" manifestLocation="/rdptransport/src/manifest" manifestVersion="1.0" reuseManifest="true" saveManifest="true" usesManifest="true">
@@ -14,6 +14,8 @@
</sealing>
</manifest>
<selectedElements exportClassFiles="true" exportJavaFiles="false" exportOutputFolder="false">
<javaElement handleIdentifier="=rdptransport/src"/>
<javaElement handleIdentifier="=rdptransport/src&lt;"/>
<javaElement handleIdentifier="=rdptransport/src&lt;net.sourceforge.jdpapi"/>
<javaElement handleIdentifier="=rdptransport/src&lt;es.virtualcable.rdp"/>
</selectedElements>
</jardesc>

View File

@@ -45,7 +45,13 @@ public class LinuxApplet implements OsApplet {
boolean redirectPrinters = params.get("pr").equals("1");
boolean redirectAudio = params.get("au").equals("1");
boolean compression = params.get("cr").equals("1");
boolean wallpaper = false;
if( params.get("sw") != null )
{
wallpaper = params.get("sw").equals("1");
}
// Notifies to broker the
util.notifyHostname(baseUrl, params.get("is"));
@@ -123,6 +129,9 @@ public class LinuxApplet implements OsApplet {
if( redirectSerials )
exec.add("-rcomport:COM1=/dev/ttyS0");
if( wallpaper )
exec.add("-xl"); // Adds "Lan" experience
if( redirectPrinters ) // Will have to look at local cups to find printer
{
}

View File

@@ -24,6 +24,7 @@ public class WinRdpFile {
public boolean compression = false;
public boolean displayConnectionBar = true;
public boolean showWallpaper = false;
public boolean multimon = false;
public WinRdpFile(boolean fullScreen, String width, String height, String bpp) {
this.width = width;
@@ -44,6 +45,7 @@ public class WinRdpFile {
String compression = this.compression ? "1" : "0";
String bar = displayConnectionBar ? "1" : "0";
String disableWallpaper = showWallpaper ? "0" : "1";
String useMultimon = multimon ? "0" : "1";
FileWriter fstream = new FileWriter(fname);
PrintWriter out = new PrintWriter(fstream);
@@ -51,6 +53,7 @@ public class WinRdpFile {
out.println("desktopwidth:i:"+this.width);
out.println("desktopheight:i:"+this.height);
out.println("session bpp:i:"+this.bpp);
out.println("use multimon:i:"+useMultimon);
out.println("auto connect:i:1");
out.println("full address:s:"+this.address);
out.println("compression:i:"+compression);

View File

@@ -78,6 +78,7 @@ public class WindowsApplet implements OsApplet {
rdp.redirectPrinters = params.get("pr").equals("1");
rdp.redirectAudio = params.get("au").equals("1");
rdp.compression = params.get("cr").equals("1");
rdp.multimon = params.get("mm").equals("1");
if( params.get("sw") != null )
{
rdp.showWallpaper = params.get("sw").equals("1");

View File

@@ -1,4 +1,7 @@
Manifest-Version: 1.0
Sealed: true
Permissions: all-permissions
Codebase: *
Application-Library-Allowable-Codebase: *
Application-Name: UDS RDP Connector
Created-By: Virtual Cable S.L.U.

View File

@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<?eclipse-pydev version="1.0"?><pydev_project>
<pydev_property name="org.python.pydev.PYTHON_PROJECT_INTERPRETER">Default</pydev_property>
<pydev_property name="org.python.pydev.PYTHON_PROJECT_INTERPRETER">Python 2.7 virtualenv Django 1.7</pydev_property>
<pydev_property name="org.python.pydev.PYTHON_PROJECT_VERSION">python 2.7</pydev_property>
<pydev_variables_property name="org.python.pydev.PROJECT_VARIABLE_SUBSTITUTION">
<key>DJANGO_MANAGE_LOCATION</key>

View File

@@ -115,7 +115,7 @@ class Provider(ServiceProvider):
#: Is Methuselah istill alive?
methAlive = gui.CheckBoxField(order = 4,
label = translatable('Is Methuselah still alive?'),
tooltip = translatable('If you fails, this will not get saved :-)'),
tooltip = translatable('If you fail, this will not get saved :-)'),
required = True, #: Also means nothing. Check boxes has always a value
defvalue = gui.TRUE #: By default, at new item, check this
)

View File

@@ -406,7 +406,7 @@ want to provide a new one.</p>
<span class="c">#: Is Methuselah istill alive?</span>
<span class="n">methAlive</span> <span class="o">=</span> <span class="n">gui</span><span class="o">.</span><span class="n">CheckBoxField</span><span class="p">(</span><span class="n">order</span> <span class="o">=</span> <span class="mi">4</span><span class="p">,</span>
<span class="n">label</span> <span class="o">=</span> <span class="n">translatable</span><span class="p">(</span><span class="s">&#39;Is Methuselah still alive?&#39;</span><span class="p">),</span>
<span class="n">tooltip</span> <span class="o">=</span> <span class="n">translatable</span><span class="p">(</span><span class="s">&#39;If you fails, this will not get saved :-)&#39;</span><span class="p">),</span>
<span class="n">tooltip</span> <span class="o">=</span> <span class="n">translatable</span><span class="p">(</span><span class="s">&#39;If you fail, this will not get saved :-)&#39;</span><span class="p">),</span>
<span class="n">required</span> <span class="o">=</span> <span class="bp">True</span><span class="p">,</span> <span class="c">#: Also means nothing. Check boxes has always a value</span>
<span class="n">defvalue</span> <span class="o">=</span> <span class="n">gui</span><span class="o">.</span><span class="n">TRUE</span> <span class="c">#: By default, at new item, check this</span>
<span class="p">)</span>

View File

@@ -115,7 +115,7 @@ class Provider(ServiceProvider):
#: Is Methuselah istill alive?
methAlive = gui.CheckBoxField(order = 4,
label = translatable('Is Methuselah still alive?'),
tooltip = translatable('If you fails, this will not get saved :-)'),
tooltip = translatable('If you fail, this will not get saved :-)'),
required = True, #: Also means nothing. Check boxes has always a value
defvalue = gui.TRUE #: By default, at new item, check this
)

View File

@@ -1,3 +1,13 @@
ujson
xml_marshaller
six
pycrypto
django-compressor
dnspython
lxml
ovirt-engine-sdk-python
pycurl
pyOpenSSL
python-ldap
six
MySQL-python

114
server/samples/REST2.py Normal file
View File

@@ -0,0 +1,114 @@
# -*- coding: utf-8 -*-
#
# Copyright (c) 2014 Virtual Cable S.L.
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without modification,
# are permitted provided that the following conditions are met:
#
# * Redistributions of source code must retain the above copyright notice,
# this list of conditions and the following disclaimer.
# * Redistributions in binary form must reproduce the above copyright notice,
# this list of conditions and the following disclaimer in the documentation
# and/or other materials provided with the distribution.
# * Neither the name of Virtual Cable S.L. nor the names of its contributors
# may be used to endorse or promote products derived from this software
# without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
'''
@author: Adolfo Gómez, dkmaster at dkmon dot com
'''
from __future__ import unicode_literals
from httplib2 import Http
import json
rest_url = 'http://172.27.0.1:8000/rest/'
headers = {}
# Hace login con el root, puede usarse cualquier autenticador y cualquier usuario, pero en la 1.5 solo está implementado poder hacer
# este tipo de login con el usuario "root"
def login():
global headers
h = Http()
# parameters = '{ "auth": "admin", "username": "root", "password": "temporal" }'
parameters = '{ "auth": "casa", "username": "172.27.0.1", "password": "" }'
resp, content = h.request(rest_url + 'auth/login', method='POST', body=parameters)
if resp['status'] != '200': # Authentication error due to incorrect parameters, bad request, etc...
print "Authentication error"
return -1
# resp contiene las cabeceras, content el contenido de la respuesta (que es json), pero aún está en formato texto
res = json.loads(content)
print res
if res['result'] != 'ok': # Authentication error
print "Authentication error"
return -1
headers['X-Auth-Token'] = res['token']
return 0
def logout():
global headers
h = Http()
resp, content = h.request(rest_url + 'auth/logout', headers=headers)
if resp['status'] != '200': # Logout error due to incorrect parameters, bad request, etc...
print "Error requesting logout"
return -1
# Return value of logout method is nonsense (returns always done right now, but it's not important)
return 0
# Sample response from request_pools
# [
# {
# u'initial_srvs': 0,
# u'name': u'WinAdolfo',
# u'max_srvs': 0,
# u'comments': u'',
# u'id': 6,
# u'state': u'A',
# u'user_services_count': 3,
# u'cache_l2_srvs': 0,
# u'service_id': 9,
# u'provider_id': 2,
# u'cache_l1_srvs': 0,
# u'restrained': False}
# ]
def request_services():
h = Http()
resp, content = h.request(rest_url + 'connection', headers=headers)
if resp['status'] != '200': # error due to incorrect parameters, bad request, etc...
print "Error requesting services"
print resp, content
return {}
return json.loads(content)
if __name__ == '__main__':
if login() == 0: # If we can log in, will get the pools correctly
res = request_services()
print res
print logout() # This will success

View File

@@ -113,7 +113,7 @@ STATICFILES_FINDERS = (
# Related to file uploading
FILE_UPLOAD_PERMISSIONS = 0o640
FILE_UPLOAD_DIRECTORY_PERMISSIONS = 0o760
FILE_UPLOAD_DIRECTORY_PERMISSIONS = 0o750
FILE_UPLOAD_MAX_MEMORY_SIZE = 512 * 1024 # 512 Kb
# Make this unique, and don't share it with anybody.

View File

@@ -1,3 +1,3 @@
import sys
sys.setdefaultencoding('UTF-8')
sys.setdefaultencoding('UTF-8') # @UndefinedVariable

View File

@@ -30,11 +30,15 @@
'''
@author: Adolfo Gómez, dkmaster at dkmon dot com
'''
# pylint: disable=too-many-public-methods
from __future__ import unicode_literals
from django.contrib.sessions.backends.db import SessionStore
from uds.core.util.Config import GlobalConfig
from uds.core.auths.auth import getRootUser
from uds.models import Authenticator
import logging
@@ -78,6 +82,13 @@ class ResponseError(HandlerError):
pass
class NotSupportedError(HandlerError):
'''
Some elements do not support some operations (as searching over an authenticator that does not supports it)
'''
pass
class Handler(object):
'''
REST requests handler base class
@@ -86,7 +97,7 @@ class Handler(object):
name = None # If name is not used, name will be the class name in lower case
path = None # Path for this method, so we can do /auth/login, /auth/logout, /auth/auths in a simple way
authenticated = True # By default, all handlers needs authentication
needs_admin = False # By default, the methods will be accessible by anyone if nothine else indicated
needs_admin = False # By default, the methods will be accessible by anyone if nothing else indicated
needs_staff = False # By default, staff
# method names: 'get', 'post', 'put', 'patch', 'delete', 'head', 'options', 'trace'
@@ -106,6 +117,7 @@ class Handler(object):
self._kwargs = kwargs
self._headers = {}
self._authToken = None
self._user = None
if self.authenticated: # Only retrieve auth related data on authenticated handlers
try:
self._authToken = self._request.META.get(AUTH_TOKEN_HEADER, '')
@@ -125,6 +137,8 @@ class Handler(object):
if self.needs_staff and not self.getValue('staff_member'):
raise AccessDenied()
self._user = self.getUser()
def headers(self):
'''
Returns the headers of the REST request (all)
@@ -134,18 +148,22 @@ class Handler(object):
def header(self, headerName):
'''
Get's an specific header name from REST request
:param headerName: name of header to get
'''
return self._headers.get(headerName)
def addHeader(self, header, value):
'''
Inserts a new header inside the headers list
:param header: name of header to insert
:param value: value of header
'''
self._headers[header] = value
def removeHeader(self, header):
'''
Removes an specific header from the headers list
:param header: Name of header to remove
'''
try:
del self._headers[header]
@@ -163,6 +181,12 @@ class Handler(object):
def storeSessionAuthdata(session, id_auth, username, locale, is_admin, staff_member):
'''
Stores the authentication data inside current session
:param session: session handler (Djano user session object)
:param id_auth: Authenticator id (DB object id)
:param username: Name of user (login name)
:param locale: Assigned locale
:param is_admin: If user is considered admin or not
:param staff_member: If is considered as staff member
'''
if is_admin:
staff_member = True # Make admins also staff members :-)
@@ -179,6 +203,11 @@ class Handler(object):
'''
Generates the authentication token from a session, that is basically
the session key itself
:param id_auth: Authenticator id (DB object id)
:param username: Name of user (login name)
:param locale: Assigned locale
:param is_admin: If user is considered admin or not
:param staf_member: If user is considered staff member or not
'''
session = SessionStore()
session.set_expiry(GlobalConfig.ADMIN_IDLE_TIME.getInt())
@@ -229,3 +258,17 @@ class Handler(object):
True if user of this REST request is member of staff
'''
return self.getValue('staff_member') and True or False
def getUser(self):
'''
If user is staff member, returns his Associated user on auth
'''
logger.debug('REST : {}'.format(self._session))
authId = self.getValue('auth')
username = self.getValue('username')
# Maybe it's root user??
if (GlobalConfig.SUPER_USER_ALLOW_WEBACCESS.getBool(True) and
username == GlobalConfig.SUPER_USER_LOGIN.get(True) and
authId == -1):
return getRootUser()
return Authenticator.objects.get(pk=authId).users.get(name=username)

View File

@@ -36,10 +36,10 @@ from django.utils.translation import ugettext as _
from uds.core.util import Config
from uds.core.util.State import State
from uds.core.util.model import processUuid
from uds.core.util import log
from uds.core.managers import cryptoManager
from uds.REST import Handler
from uds.REST import AccessDenied
from uds.REST import RequestError
from uds.models import UserService
@@ -73,7 +73,14 @@ class Actor(Handler):
authenticated = False # Actor requests are not authenticated
@staticmethod
def result(result='', error=None):
def result(result=None, error=None):
'''
Helper method to create a "result" set for actor response
:param result: Result value to return (can be None, in which case it is converted to empty string '')
:param error: If present, This response represents an error. Result will contain an "Explanation" and error contains the error code
:return: A dictionary, suitable for response to Caller
'''
result = result if result is not None else ''
res = {'result': result, 'date': datetime.datetime.now()}
if error is not None:
res['error'] = error
@@ -164,15 +171,10 @@ class Actor(Handler):
# Right now, only "message" posts
try:
service = UserService.objects.get(uuid=uuid)
service = UserService.objects.get(uuid=processUuid(uuid))
except Exception:
return Actor.result(_('User service not found'), error=ERR_USER_SERVICE_NOT_FOUND)
logger.debug('In use: {}'.format(service.in_use))
inUse = service.in_use
username = ''
if message == 'notifyComms':
logger.debug('Setting comms url to {}'.format(data))
service.setCommsUrl(data)
@@ -182,22 +184,10 @@ class Actor(Handler):
if message == 'log':
logger.debug(self._params)
data = '\t'.join((self._params.get('message'), six.text_type(self._params.get('level', 10000))))
elif message in ('login', 'logout', 'logon', 'logoff'):
username = data
try:
res = service.getInstance().osmanager().process(service, message, data, options={'scramble': False})
except Exception as e:
return Actor.result(six.text_type(e), ERR_OSMANAGER_ERROR)
# Force service reload to check if inUse has changed, so we can log login/logout
service = UserService.objects.get(uuid=uuid)
logger.debug('service in use: {}, {}'.format(service.in_use, inUse))
if service.in_use != inUse: # If state changed, log it
instance = service.getInstance()
type_ = 'login' if service.in_use else 'logout'
uniqueId = service.unique_id
serviceIp = instance.getIp()
log.useLog(type_, uniqueId, serviceIp, username)
return Actor.result(res)

View File

@@ -58,7 +58,7 @@ class Authenticators(ModelHandler):
{'name': {'title': _('Name'), 'visible': True, 'type': 'iconType'}},
{'comments': {'title': _('Comments')}},
{'priority': {'title': _('Priority'), 'type': 'numeric', 'width': '5em'}},
{'small_name': {'title': _('Small name')}},
{'small_name': {'title': _('Tag')}},
{'users_count': {'title': _('Users'), 'type': 'numeric', 'width': '5em'}}
]

View File

@@ -70,6 +70,5 @@ class Cache(Handler):
if len(self._args) != 1:
raise RequestError('Invalid Request')
uCache.purge()
return 'done'

Some files were not shown because too many files have changed in this diff Show More