Compare commits

...

1083 Commits
v3.0 ... master

Author SHA1 Message Date
Adolfo Gómez García
c07c21b6a9
updating user interface manager 2022-10-31 20:53:30 +01:00
Adolfo Gómez García
937240a9fc
Refactoring Authenticators related and minor type checking fixes 2022-10-31 19:24:14 +01:00
Adolfo Gómez García
0cf33501b6
some minor test fixes 2022-10-31 14:10:10 +01:00
Adolfo Gómez García
15576fdc22
Updating user interface and making tests 2022-10-31 01:47:55 +01:00
Adolfo Gómez García
adb4b5326a
Adding user interface tests and refactoring user interface 2022-10-30 23:14:13 +01:00
Adolfo Gómez García
284508632c
Merge remote-tracking branch 'origin/v3.6' 2022-10-28 14:44:34 +02:00
Adolfo Gómez García
dd08257fb9
Merge remote-tracking branch 'origin/v3.5' into v3.6 2022-10-28 14:42:35 +02:00
Adolfo Gómez García
9d0df6cfae
small fix for client detecti 2022-10-28 14:42:09 +02:00
Adolfo Gómez García
71a0a228fb
merged backport of uds password encription 2022-10-27 14:55:43 +02:00
Adolfo Gómez García
910094065e
Merge remote-tracking branch 'origin/v3.6' 2022-10-27 14:47:03 +02:00
Adolfo Gómez García
7bd0d571e6
increased security by encrypting with own key, different on each instalation 2022-10-27 14:46:34 +02:00
Adolfo Gómez García
ab6c55ec58
Merge remote-tracking branch 'origin/v3.6' 2022-10-26 18:33:26 +02:00
Adolfo Gómez García
ad269b3c28
added initial export command for relevant UDS entities 2022-10-26 18:32:52 +02:00
Adolfo Gómez García
00ae824baf
Merge remote-tracking branch 'origin/v3.6' 2022-10-26 16:40:46 +02:00
Adolfo Gómez García
f3dd5753a3
fixed mfa_data name on db 2022-10-26 16:40:04 +02:00
Adolfo Gómez García
c4fcf7c57e
Merge remote-tracking branch 'origin/v3.6' 2022-10-21 00:56:54 +02:00
Adolfo Gómez García
13336b966e
updating delayed task 2022-10-21 00:56:12 +02:00
Adolfo Gómez García
7a64235440
Merge remote-tracking branch 'origin/v3.6' 2022-10-19 15:15:46 +02:00
Adolfo Gómez García
a76989d885
fixed not opening html5 2022-10-19 15:14:52 +02:00
Adolfo Gómez García
6b712d59a3
Merge remote-tracking branch 'origin/v3.6' 2022-10-19 14:20:18 +02:00
Adolfo Gómez García
5f0e5a5dfe
Merge remote-tracking branch 'origin/v3.5' into v3.6 2022-10-19 14:19:46 +02:00
Adolfo Gómez García
cfbce5aef5
fixed caching calendars 2022-10-19 14:19:30 +02:00
Adolfo Gómez García
92960d47ed
fixing merge issues 2022-10-18 20:47:26 +02:00
Adolfo Gómez García
8648fc605d
small rdp fix for bandit 2022-10-17 18:21:32 +02:00
Adolfo Gómez García
6a71a505b3
Merge remote-tracking branch 'origin/v3.6' 2022-10-17 16:05:05 +02:00
Adolfo Gómez García
d2cb4356f0
Added user interface default value 2022-10-17 13:51:35 +02:00
Adolfo Gómez García
4153fa0fd9
fixes after merge 3.6 2022-10-16 18:54:24 +02:00
Adolfo Gómez García
daf4bbcc37
Merge remote-tracking branch 'origin/v3.6' 2022-10-16 18:47:51 +02:00
Adolfo Gómez García
4f4f1f24fd
fixes for transports 2022-10-16 18:46:56 +02:00
Adolfo Gómez García
ffde47af94
Merge remote-tracking branch 'origin/v3.6' 2022-10-14 19:52:11 +02:00
Adolfo Gómez García
65d38d8722
updated translations 2022-10-14 19:51:58 +02:00
Adolfo Gómez García
db5a08b0c7
Merge remote-tracking branch 'origin/v3.6' 2022-10-14 19:51:53 +02:00
Adolfo Gómez García
2b767e6bf9
small transport fix¡ 2022-10-14 19:51:43 +02:00
Adolfo Gómez García
b16cea984c
Updated mfa string 2022-10-14 19:07:41 +02:00
Adolfo Gómez García
7769351d42
adding spice support for proxmox 2022-10-14 02:07:12 +02:00
Adolfo Gómez García
c2c5bc8aa1
Merged and fixed 2022-10-14 00:47:37 +02:00
Adolfo Gómez García
bf635a5e9a
small html fixes 2022-10-14 00:28:18 +02:00
Adolfo Gómez García
ae2ffccbc3
Added ask credentials dialog 2022-10-13 20:02:02 +02:00
Adolfo Gómez García
a005bf1ca0
fixed incorrect import 2022-10-13 15:05:32 +02:00
Adolfo Gómez García
013558eb77
Merge remote-tracking branch 'origin/v3.6' 2022-10-13 14:50:04 +02:00
Adolfo Gómez García
4de443395d
Updated translations 2022-10-13 14:49:38 +02:00
Adolfo Gómez García
9f2bc5417f
Fixed choiceField bug & MFA table 2022-10-13 14:47:37 +02:00
Adolfo Gómez García
9deb2dcd74
fixing up actor things 2022-10-13 00:04:26 +02:00
Adolfo Gómez García
2908b99435
Merge remote-tracking branch 'origin/v3.6' 2022-10-05 23:56:54 +02:00
Adolfo Gómez García
c6d1bf450c
Fixed choicefield generator for strings (was generating "name" instead of "text") 2022-10-05 23:52:28 +02:00
Adolfo Gómez García
26d26315ac
Merge remote-tracking branch 'origin/v3.6' 2022-10-05 23:06:23 +02:00
Adolfo Gómez García
cf21936f41
Added report for audit log for administration 2022-10-05 23:05:36 +02:00
Adolfo Gómez García
bcf185d54a
Merge remote-tracking branch 'origin/v3.6' 2022-10-05 19:36:09 +02:00
Adolfo Gómez García
5d9c8ee53f
better audit log 2022-10-05 19:35:45 +02:00
Adolfo Gómez García
e1acdf1c85
Merge remote-tracking branch 'origin/v3.6' 2022-10-05 19:16:53 +02:00
Adolfo Gómez García
7d3bfb5d3b
replaced "-" with ":" for checking if a save field is optional so we can provide the default value" 2022-10-05 19:16:30 +02:00
Adolfo Gómez García
186bbb11e3
Merge remote-tracking branch 'origin/v3.6' 2022-10-05 18:08:05 +02:00
Adolfo Gómez García
b474e63924
updated translations 2022-10-05 18:06:48 +02:00
Adolfo Gómez García
09bbc7f22b
Merge remote-tracking branch 'origin/v3.6' 2022-10-05 17:58:15 +02:00
Adolfo Gómez García
d48747abff
Added administration audit and fixed some translations 2022-10-05 17:54:07 +02:00
Adolfo Gómez García
57f2c35af0
Several Fixes:
* Upgraded typing information on models
* Removed unused DBFile
* renamed osmanager.png wrong name
2022-10-01 06:45:41 +02:00
Adolfo Gómez García
8c40320b64
Merge remote-tracking branch 'origin/v3.6' 2022-09-29 16:32:56 +02:00
Adolfo Gómez García
8b3ad295cc
Added MAC controled by uds for proxmox 2022-09-28 15:33:54 +02:00
Adolfo Gómez García
c03c479a14
Merge remote-tracking branch 'origin/v3.6' 2022-09-19 14:24:54 +02:00
Adolfo Gómez García
aa677353ad
fixed tree command 2022-09-19 14:23:44 +02:00
Adolfo Gómez García
9c6c4078b1
Fixed showConfig 2022-09-19 14:04:53 +02:00
Adolfo Gómez García
22cee394ee
Merge remote-tracking branch 'origin/v3.6' 2022-09-18 15:09:47 +02:00
Adolfo Gómez García
9fba2b45ad
Added "ERROR" user services on report with log 2022-09-18 15:09:17 +02:00
Adolfo Gómez García
8f4f6bc5cb
Merge remote-tracking branch 'origin/v3.6' 2022-09-17 00:14:59 +02:00
Adolfo Gómez García
71582fc415
fixed tree yaml generation 2022-09-16 23:27:12 +02:00
Adolfo Gómez García
0d1d38c18a
added showconfig in yaml 2022-09-16 22:34:40 +02:00
Adolfo Gómez García
4ec8841a57
added tree command to allow an full overview of uds data 2022-09-16 18:45:37 +02:00
Adolfo Gómez García
2ecab27b16
Merge remote-tracking branch 'origin/v3.6' 2022-09-16 02:05:23 +02:00
Adolfo Gómez García
8c6390733c
added showconfig command 2022-09-16 00:53:56 +02:00
Adolfo Gómez García
ade53fc893
Merge remote-tracking branch 'origin/v3.6' 2022-09-15 14:06:44 +02:00
Adolfo Gómez García
98f56ee58b
restored deleted line by mistake on auth 2022-09-15 13:06:13 +02:00
Adolfo Gómez García
1c01c35a87
Renamed config value 2022-09-14 12:09:06 +02:00
Adolfo Gómez García
673d1b6813
Added "Ultimate Security". When enabled, UDS will not cache encrypted credentials on server, so no credential can be redirected 2022-09-13 16:14:54 +02:00
Adolfo Gómez García
1ba12bb82d
Updated translations 2022-09-12 15:04:33 +02:00
Adolfo Gómez García
c6dfd3f362
Refactorizing gui variables - types 2022-09-12 14:41:15 +02:00
Adolfo Gómez García
f7888468c0
Refactorizing gui variables 2022-09-12 14:21:55 +02:00
Adolfo Gómez García
ce8bb30cf1
Merge remote-tracking branch 'origin/v3.6' 2022-09-12 12:40:16 +02:00
Adolfo Gómez García
f90f108869
Fixed UserInterface new guiField acceptance of values 2022-09-12 12:37:21 +02:00
Adolfo Gómez García
115d8562e1 Refactorized groups manager and fixed ipInNetwork
Signed-off-by: Adolfo Gómez García <dkmaster@dkmon.com>
2022-09-09 02:13:20 +02:00
Adolfo Gómez García
f6607d0416 Merged allow users remove from 3.6 2022-09-08 12:21:00 +02:00
Adolfo Gómez García
411bddd79d Merge remote-tracking branch 'origin/v3.6' 2022-09-08 12:20:35 +02:00
Adolfo Gómez García
88c3f9077b small cosmetic fix 2022-09-08 12:20:21 +02:00
Adolfo Gómez García
bd13a39845 erge remote-tracking branch 'origin/v3.6' 2022-09-08 12:16:03 +02:00
Adolfo Gómez García
2a01df542d Added "allow reset" and "allow release" to metapool. Automatically enabled is ALL member pools allows. 2022-09-08 12:15:18 +02:00
Adolfo Gómez García
c976536b5f added a new test and small fixes 2022-09-06 15:25:05 +02:00
Adolfo Gómez García
0721c833fb Fixed settings and security (changed order for security middleware to be after globalrequest to fill ips 2022-09-05 15:00:37 +02:00
Adolfo Gómez García
7b877e3aea Merge remote-tracking branch 'origin/v3.6' 2022-09-05 12:53:50 +02:00
Adolfo Gómez García
2733444355 Merge remote-tracking branch 'origin/v3.5' into v3.6 2022-09-05 12:53:31 +02:00
Adolfo Gómez García
cf6820aa2b Fixed security 2022-09-05 12:48:54 +02:00
Adolfo Gómez García
62f9f8f676 Merge remote-tracking branch 'origin/v3.6' 2022-09-02 16:47:40 +02:00
Adolfo Gómez García
6692e5ce6d Merge remote-tracking branch 'origin/v3.5' into v3.6 2022-09-02 16:45:25 +02:00
Adolfo Gómez García
1a85f60f4f Fixed "Database error" from OpenGnsys to include some more helpfull information 2022-09-02 16:45:11 +02:00
Adolfo Gómez García
2d6f55ef0b more tests and added a few exludes to coverage 2022-09-01 16:14:20 +02:00
Adolfo Gómez García
42b3826115 Added context to coverage and added first model test 2022-09-01 14:39:30 +02:00
Adolfo Gómez García
cb722c5e89 adding "build" to actor 2022-09-01 10:28:02 +02:00
Adolfo Gómez García
32b35c9651 fixed tests 2022-08-31 15:24:08 +02:00
Adolfo Gómez García
e33ea33797 Merge remote-tracking branch 'origin/v3.6' 2022-08-31 15:22:36 +02:00
Adolfo Gómez García
38b3318704 updated translations 2022-08-31 15:22:15 +02:00
Adolfo Gómez García
ccec281e0d Fixed text of maxServices 2022-08-31 15:09:55 +02:00
Adolfo Gómez García
4611c35b0d Merge remote-tracking branch 'origin/v3.6' 2022-08-31 13:54:55 +02:00
Adolfo Gómez García
8473b80978 fixed maxDeployed beinf overwriten 2022-08-31 13:52:45 +02:00
Adolfo Gómez García
230187d9ee small fix on service unmarshall 2022-08-31 13:52:11 +02:00
Adolfo Gómez García
c06c3df327 Merge remote-tracking branch 'origin/v3.6' 2022-08-31 12:52:37 +02:00
Adolfo Gómez García
092bb83001 Added "maxServices" to OpenGnsys to limit number of possible services provided by a single UDS Service 2022-08-31 12:45:33 +02:00
Adolfo Gómez García
5c6303fec0 Added more tests
* Fixed pytest to not look for classes
* Added 'destroy_after' property to user service for convenience
* Small cosmetic fixes
2022-08-31 00:10:57 +02:00
Adolfo Gómez García
b05c5b1396 Merge remote-tracking branch 'origin/v3.6' 2022-08-30 21:53:42 +02:00
Adolfo Gómez García
ac62aed420 upgrading cache updater to take into account maxDeployed to stop creating cache services 2022-08-30 21:53:03 +02:00
Adolfo Gómez García
8b540c350a Added more tests and a couple of cosmetic fixes 2022-08-30 17:40:29 +02:00
Adolfo Gómez García
db12077304 Adding more tests and fixes 2022-08-29 15:21:12 +02:00
Adolfo Gómez García
70488199b9 Merge remote-tracking branch 'origin/v3.6' 2022-08-29 15:20:50 +02:00
Adolfo Gómez García
3bdf4c18ad Fixed detecting canceling hanged 2022-08-29 15:20:43 +02:00
Adolfo Gómez García
e16be78ad5 Fixed remove or cancel detecting "hanged" canceling operations 2022-08-29 15:20:09 +02:00
Adolfo Gómez García
09c5cc2f43 Merge remote-tracking branch 'origin/v3.6' 2022-08-28 19:59:20 +02:00
Adolfo Gómez García
28319b216f updated compat level to 10 2022-08-28 19:23:04 +02:00
Adolfo Gómez García
07e6c3d0a8 unique ids testing 2022-08-28 13:41:57 +02:00
Adolfo Gómez García
96abb71d9c more tests 2022-08-28 13:23:04 +02:00
Adolfo Gómez García
7de259af87 adding more tests 2022-08-28 01:31:09 +02:00
Adolfo Gómez
1567996ebc
Delete LICENSE.txt 2022-08-27 20:59:25 +02:00
Adolfo Gómez
4edb3b3f0c
Create LICENSE 2022-08-27 20:59:08 +02:00
Adolfo Gómez García
07987504c3 added LICENSE.txt 2022-08-27 20:57:12 +02:00
Adolfo Gómez García
5f93b68c25 Modified transport to adapt for accept future client scripts in more langs 2022-08-27 19:09:12 +02:00
Adolfo Gómez García
d0e9c96573 Added new test and make pytests use parallel execution of tests using pytest-xdist 2022-08-25 22:28:57 +02:00
Adolfo Gómez García
a52ad44ef1 added basic web test and download testing 2022-08-25 17:55:51 +02:00
Adolfo Gómez García
69b778c922 Adding more tests and fixes 2022-08-24 22:16:47 +02:00
Adolfo Gómez García
5f12c2e7b3 Merge remote-tracking branch 'origin/v3.6' 2022-08-24 11:09:54 +02:00
Adolfo Gómez García
1a4a41a6b9 fixed logout building absolute url 2022-08-24 11:09:20 +02:00
Adolfo Gómez García
739b0c7f81 fixed logout absolute url building on logout 2022-08-24 11:08:56 +02:00
Adolfo Gómez García
78c7039c54 Merge remote-tracking branch 'origin/v3.6' 2022-08-23 15:23:25 +02:00
Adolfo Gómez García
e5e8ad5fbd Adding radius challenge MFA provided by Daniel Torregrosa (Thanks!) 2022-08-23 15:22:48 +02:00
Adolfo Gómez García
21d2a6fb27 Done actor initialize tests and fixed actor v3 initialization 2022-08-22 15:46:15 +02:00
Adolfo Gómez García
fa3e30c518 fixing tests 2022-08-21 19:37:32 +02:00
Adolfo Gómez García
c6be2562ee added test for initialize for managed machines 2022-08-21 14:23:03 +02:00
Adolfo Gómez García
4c19247a2c Adding more actor tests 2022-08-20 18:40:05 +02:00
Adolfo Gómez García
a6b502e0ba more fixes 2022-08-19 21:09:45 +02:00
Adolfo Gómez García
b12730d160 more test prepartion and fixes 2022-08-19 20:20:29 +02:00
Adolfo Gómez García
07031850e5 Advancing on tests 2022-08-19 00:46:38 +02:00
Adolfo Gómez García
a42857038c Fixes on migrations & finishing supporting test methods 2022-08-19 00:13:45 +02:00
Adolfo Gómez García
d19969fce3 Fixed migration field names on squashed migration. ManyToManyFields where not renamed on empty tables, so i had to move "manually" the creation of the fields on squashed one. Not a big issue, but strange. 2022-08-19 00:13:01 +02:00
Adolfo Gómez García
195e13682c Adding xxhash as fast alternative for some hash calcs (as cache i.e.) 2022-08-18 20:05:43 +02:00
Adolfo Gómez García
95b9b79b02 Adding testing elements 2022-08-18 19:46:22 +02:00
Adolfo Gómez García
225fed3012 Merge remote-tracking branch 'origin/v3.6' 2022-08-18 13:56:46 +02:00
Adolfo Gómez García
86ebd7766e Merge remote-tracking branch 'origin/v3.5' into v3.6 2022-08-18 13:56:32 +02:00
Adolfo Gómez García
83394f0d34 Fixed XEN/XCP-NG network moving on service 2022-08-18 13:56:07 +02:00
Adolfo Gómez García
d5eafb1179 Refactorized transport to adapt parameter typing 2022-08-17 23:42:33 +02:00
Adolfo Gómez García
11b56571d2 Removing old v2 actor rests. Not supported anymore 2022-08-17 20:26:51 +02:00
Adolfo Gómez García
18de1193b4 Updating tests and fied sample settings
- Fixed taskManager runner (added new parameters)
- refactoring and generating base rest testing
2022-08-17 20:15:32 +02:00
Adolfo Gómez García
d8164a9b4d Merge remote-tracking branch 'origin/v3.6' 2022-08-17 19:03:45 +02:00
Adolfo Gómez García
4f0ea76666 Merge remote-tracking branch 'origin/v3.5' into v3.6 2022-08-17 15:06:49 +02:00
Adolfo Gómez García
c34fc41f56 unmanaged fix 2022-08-17 14:55:33 +02:00
Adolfo Gómez García
18e9cab9ef fixed local log 2022-08-17 14:33:44 +02:00
Adolfo Gómez García
4d3aa1d17c Merge remote-tracking branch 'origin/v3.6' 2022-08-17 14:13:17 +02:00
Adolfo Gómez García
6053e34d1d Merge remote-tracking branch 'origin/v3.5' into v3.6 2022-08-17 14:12:52 +02:00
Adolfo Gómez García
90aa455586 fixed unmanaged 2022-08-17 14:12:13 +02:00
Adolfo Gómez García
f274ae2fe3 fixed a bit the tests and tests tools 2022-08-16 21:40:46 +02:00
Adolfo Gómez García
195d2a1336 More request definition cleanups 2022-08-16 14:30:20 +02:00
Adolfo Gómez García
12846f9b1f Small XenApi Fixes, requests cleanup 2022-08-16 14:29:38 +02:00
Adolfo Gómez García
748d8d7464 Replaced session PickleSerializer with Json-bases serializer (custom one). More secure 2022-08-16 13:08:47 +02:00
Adolfo Gómez García
0ed1f3ccee Added coverage support on testing 2022-08-16 00:18:32 +02:00
Adolfo Gómez García
fe712d27b7 adding services fixtures 2022-08-16 00:10:48 +02:00
Adolfo Gómez García
c56666ed4b small test fixes 2022-08-15 23:34:52 +02:00
Adolfo Gómez García
01184582b3 Fixing up testing and make them usable from vscode sidebar 2022-08-15 23:31:23 +02:00
Adolfo Gómez García
76745e8624 Fixing up bandit recomendations & minor typo errors 2022-08-15 14:10:17 +02:00
Adolfo Gómez García
17b040d9b3 adding tests 2022-08-15 00:29:39 +02:00
Adolfo Gómez García
07e1c6214e Added Test Service 2022-08-14 23:36:22 +02:00
Adolfo Gómez García
de9bbfc896 removeing deprecated pyqt methods 2022-08-14 21:57:28 +02:00
Adolfo Gómez García
d84977dee0 Merge remote-tracking branch 'origin/v3.6' 2022-08-14 21:53:33 +02:00
Adolfo Gómez García
11041ff44f Merge remote-tracking branch 'origin/v3.5' into v3.6 2022-08-14 21:52:40 +02:00
Adolfo Gómez García
bc2328a239 fixing up sqlite 2022-08-14 21:52:24 +02:00
Adolfo Gómez García
98826504d6 fixing up sqlite 2022-08-14 21:52:06 +02:00
Adolfo Gómez García
54ea57f330 added cache to checkIdle on macos 2022-08-12 22:49:19 +02:00
Adolfo Gómez García
cb4b2184a4 finishin operations for macos 2022-08-12 20:50:58 +02:00
Adolfo Gómez García
99fbb35512 Merge branch 'master' of github.com:dkmstr/openuds 2022-08-08 15:27:40 +02:00
Adolfo Gómez García
1374375ab9 Creating a couple of "test services" so we can make some automated tests 2022-08-08 15:27:30 +02:00
Adolfo Gómez García
909ef91181 Creating a couple of "test services" so we can make some automated tests 2022-08-08 15:27:11 +02:00
Adolfo Gómez García
01f9a1f9cd fixed for usersession 2022-08-07 13:32:07 +02:00
Adolfo Gómez García
78a3216b51 adding initial tracking of individial sessions on user services 2022-08-07 13:24:33 +02:00
Adolfo Gómez García
3a990e19a6 Merge remote-tracking branch 'origin/v3.5' into v3.6 2022-08-06 20:19:36 +02:00
Adolfo Gómez García
d9d3bc452c fixed login/logout 2022-08-06 20:19:23 +02:00
Adolfo Gómez García
e5c8b9c763 Merge remote-tracking branch 'origin/v3.6' 2022-08-06 19:30:31 +02:00
Adolfo Gómez García
e51e13b821 Merge remote-tracking branch 'origin/v3.6' 2022-08-06 19:30:01 +02:00
Adolfo Gómez García
8a150439ae Merge remote-tracking branch 'origin/v3.5' into v3.6 2022-08-06 19:29:43 +02:00
Adolfo Gómez García
ec89a2cfa8 adding session id to uds actor 2022-08-06 19:23:51 +02:00
Adolfo Gómez García
08f14bff57 Fixing up unmanaged actor 2022-08-05 13:33:57 +02:00
Adolfo Gómez García
653bff420f Fixed logout notification 2022-08-05 13:19:47 +02:00
Adolfo Gómez García
73a3c89e04 Fixed logout notification 2022-08-05 13:05:52 +02:00
Adolfo Gómez García
e79753748e Merge remote-tracking branch 'origin/v3.5' into v3.6 2022-08-04 21:56:39 +02:00
Adolfo Gómez García
adaabf9d83 Fixing up unmanaged actor 2022-08-04 21:37:33 +02:00
Adolfo Gómez García
0ed8bd6027 Merge branch 'master' of github.com:dkmstr/openuds 2022-08-04 15:55:52 +02:00
Adolfo Gómez García
ff25b4945a Started MacOS Unmanaged Support 2022-08-04 15:55:47 +02:00
Adolfo Gómez García
3a2a2a4669 Merge remote-tracking branch 'origin/v3.6' 2022-08-04 15:08:10 +02:00
Adolfo Gómez García
a8a9b24596 exit_url is now relative by default 2022-08-04 15:07:52 +02:00
Adolfo Gómez García
552ba3796b adding __slots__ to optimize a bit code 2022-08-02 15:26:30 +02:00
Adolfo Gómez García
a6c6bca2fd Merge remote-tracking branch 'origin/v3.6' 2022-08-01 14:39:34 +02:00
Adolfo Gómez García
f24c77f20a removed mic redirect on mac py default for xfreerdp (2.8 is "crashing"?) 2022-08-01 14:37:39 +02:00
Adolfo Gómez García
a3c27dbd72 minor fixes 2022-08-01 14:10:55 +02:00
Adolfo Gómez García
ec7cf91579 small fix to remove "remember_device" if not set 2022-07-29 17:06:49 +02:00
Adolfo Gómez García
d2fa5e38d0 small fix to remove "remember_device" if not set 2022-07-29 16:59:33 +02:00
Adolfo Gómez García
c98f8e31d5 Merge remote-tracking branch 'origin/v3.6' 2022-07-29 16:42:50 +02:00
Adolfo Gómez García
ada5374db5 fixed showing MFA on list 2022-07-29 16:42:24 +02:00
Adolfo Gómez García
301d68b1a2 fixed authenticators rest 2022-07-29 16:38:03 +02:00
Adolfo Gómez García
46b6bb2305 Fixes 2022-07-29 16:23:53 +02:00
Adolfo Gómez García
93ba05f6cb Fixes to MFAs 2022-07-29 16:20:14 +02:00
Adolfo Gómez García
e3976794d9 some minor refactors & used sys.intern as key for rest api 2022-07-28 13:22:02 +02:00
Adolfo Gómez García
94cf5582e2 Added RH-based unmanaged actor 2022-07-26 13:33:09 +02:00
Adolfo Gómez García
f10b370eff Added Calendar Actions to remove ALL cache items 2022-07-18 18:03:51 +02:00
Adolfo Gómez García
692c8601bf Merge remote-tracking branch 'origin/v3.6' 2022-07-15 10:27:02 +02:00
Adolfo Gómez García
afcfffbd29 Merge remote-tracking branch 'origin/v3.5' into v3.6 2022-07-15 10:26:47 +02:00
Adolfo Gómez García
3cfbdc86e0 Small cryptomanager typing fix 2022-07-15 10:26:02 +02:00
Adolfo Gómez García
063fa46899 Merge remote-tracking branch 'origin/v3.6' 2022-07-14 12:49:41 +02:00
Adolfo Gómez García
d1329849f3 Merge remote-tracking branch 'origin/v3.5' into v3.6 2022-07-14 12:49:29 +02:00
Adolfo Gómez García
ba759b3652 Fixed Proxmox MAC generation for internal DB (Case sensitive...) 2022-07-14 12:49:14 +02:00
Adolfo Gómez García
1e3478314b Reformating 2022-07-14 12:48:54 +02:00
Adolfo Gómez García
02aec9ebea Moved required client versio ton core __init__,py 2022-07-13 13:14:20 +02:00
Adolfo Gómez García
e33d63158a updated antular 2022-07-10 13:03:47 +02:00
Adolfo Gómez García
33258b0dcc Merge remote-tracking branch 'origin/v3.6' 2022-07-10 12:58:44 +02:00
Adolfo Gómez García
f5d2776478 Adde "custom html" support for MFA input code page 2022-07-06 17:41:09 +02:00
Adolfo Gómez García
0496117fc1 Fixing up mfa to include request on more methods 2022-07-06 14:34:42 +02:00
Adolfo Gómez García
b8e0dbf0c5 Merge remote-tracking branch 'origin/v3.6' 2022-07-06 13:24:41 +02:00
Adolfo Gómez García
89864b11c2 Fixed window upen 2022-07-06 13:20:10 +02:00
Adolfo Gómez García
fcdf599e18 Fixed HTML5 window opening & MFA 2022-07-06 13:17:35 +02:00
Adolfo Gómez García
05b6bebf36 bumping version to 3.6 2022-07-05 15:25:58 +02:00
Adolfo Gómez García
cdbc8d7ba1 bumping to v3.6 2022-07-05 15:20:44 +02:00
Adolfo Gómez García
072a722b09 Added udsactor-unamanged for rpm and bumped version to 3.6 2022-07-05 15:03:41 +02:00
Adolfo Gómez García
2d2e2d7b1f Upgrading version to next intermediary release 2022-07-05 14:52:17 +02:00
Adolfo Gómez García
1008bf988a upgraded migrations to adapt to MFA 2022-07-05 14:33:34 +02:00
Adolfo Gómez García
8ec815a75b Merge remote-tracking branch 'origin/v3.5-mfa' 2022-07-04 22:11:06 +02:00
Adolfo Gómez García
f4da75cea9 Adding MFA support to existing auths 2022-07-04 22:10:06 +02:00
Adolfo Gómez García
1c65722d24 added mfaData to admin 2022-07-04 21:29:41 +02:00
Adolfo Gómez García
2736390f95 Merge remote-tracking branch 'origin/v3.5-mfa' 2022-07-02 00:18:09 +02:00
Adolfo Gómez García
8783db925f fixed rest of MFA 2022-07-02 00:17:23 +02:00
Adolfo Gómez García
8b8bf7a321 Merge remote-tracking branch 'origin/v3.5-mfa' 2022-07-01 20:23:27 +02:00
Adolfo Gómez García
5e61871091 Added network to MFA and added initGui suppor for "providers" 2022-07-01 20:23:13 +02:00
Adolfo Gómez García
9a65d13890 test 2022-06-30 17:14:20 +02:00
Adolfo Gómez García
af2c01af66 fixing up merges from 3.5-mfa 2022-06-30 16:50:10 +02:00
Adolfo Gómez García
80b26446f6 translations 2022-06-30 16:45:13 +02:00
Adolfo Gómez García
a0ac50d9c2 small label fixes 2022-06-30 16:24:46 +02:00
Adolfo Gómez García
091a834074 Merge remote-tracking branch 'origin/v3.5-mfa' 2022-06-29 23:22:27 +02:00
Adolfo Gómez García
6094f55182 small MFA fixes for generic SMS 2022-06-29 23:17:52 +02:00
Adolfo Gómez García
11d9c77a79 Tested correct working of generic SMS sending using HTTP 2022-06-29 23:14:26 +02:00
Adolfo Gómez García
76e67b1f63 Fixing up MFA 2022-06-29 22:05:45 +02:00
Adolfo Gómez García
64fc61a2d6 Added generic SMS using HTTP server 2022-06-28 20:47:47 +02:00
Adolfo Gómez García
7b921ac161 Merge remote-tracking branch 'origin/v3.5-mfa' 2022-06-28 16:40:51 +02:00
Adolfo Gómez García
57b19757b9 fixed MFA 2022-06-28 16:40:35 +02:00
Adolfo Gómez García
0d281af982 merged 3.5-mfa till now 2022-06-28 16:38:25 +02:00
Adolfo Gómez García
365e2c56d3 Fixed mitration from MFA 2022-06-28 16:30:14 +02:00
Adolfo Gómez García
29fd2c068a Merge remote-tracking branch 'origin/v3.5-mfa' 2022-06-28 16:22:28 +02:00
Adolfo Gómez García
aec2f5b57f Added "not tested" generic SMS sending using an HTTP server 2022-06-28 14:50:39 +02:00
Adolfo Gómez García
4ba8bc9c5a Integrating mfa branch on 4.0. Initial changes. Work to do 2022-06-27 21:58:21 +02:00
Adolfo Gómez García
77e021a371 Fixed auth mfaIdentifier to provide userName 2022-06-27 21:30:59 +02:00
Adolfo Gómez García
2a25a8f70a removed nonsense comment copied from "sample" code used to create notifier 2022-06-24 16:53:59 +02:00
Adolfo Gómez García
b99a8de8c6 Added metadata config fields for SAML 2022-06-24 16:53:33 +02:00
Adolfo Gómez García
f922bbcd2e Removed legacy actors 2022-06-24 16:52:58 +02:00
Adolfo Gómez García
4db98684d3 refactorized 2022-06-24 13:27:45 +02:00
Adolfo Gómez García
a948d5eeb1 Added email MFA 2022-06-24 13:26:39 +02:00
Adolfo Gómez García
c7e6857492 If user has already been authorized, no mfa is allowed 2022-06-24 11:28:46 +02:00
Adolfo Gómez García
aaa4216862 Fixed MFA & Added remember me 2022-06-23 20:24:56 +02:00
Adolfo Gómez García
098396be87 Updared admin interface 2022-06-23 16:46:19 +02:00
Adolfo Gómez García
d02c693202 Fixed mfas rest path 2022-06-23 16:42:46 +02:00
Adolfo Gómez García
cb11a26fbe updated mfa icon 2022-06-23 16:23:27 +02:00
Adolfo Gómez García
43934d425f added timeout value 2022-06-23 15:56:14 +02:00
Adolfo Gómez García
5b499de983 Initial MFA done 2022-06-23 15:14:39 +02:00
Adolfo Gómez García
00d9f5759d Merge remote-tracking branch 'origin/v3.5' into v3.5-mfa 2022-06-23 14:05:25 +02:00
Adolfo Gómez García
a3bcedc38f Merge remote-tracking branch 'origin/v3.5' 2022-06-23 13:25:21 +02:00
Adolfo Gómez García
c6a40ac182 fixed global logout on federated auth 2022-06-23 12:51:41 +02:00
Adolfo Gómez García
7d9ffca559 Fixex internal db with sqlite 2022-06-23 12:23:22 +02:00
Adolfo Gómez García
ec02f63cac advancing on MFA implementation 2022-06-23 12:16:08 +02:00
Adolfo Gómez García
0de655d14f Adding MFA authorization page 2022-06-22 23:39:11 +02:00
Adolfo Gómez García
7ab6d439cb Fixed migration tree 2022-06-22 21:53:00 +02:00
Adolfo Gómez García
68e327847b Created migrations 2022-06-22 21:40:43 +02:00
Adolfo Gómez García
81ea07f0a0 Created migrations 2022-06-22 21:40:23 +02:00
Adolfo Gómez García
d7540c3305 Adding MFA 2022-06-22 17:04:18 +02:00
Adolfo Gómez García
2eff59908a Merge remote-tracking branch 'origin/v3.5' 2022-06-21 14:28:30 +02:00
Adolfo Gómez García
f43b9c7bfd Fixed small actor network card check and removed required of network for interface select 2022-06-20 19:42:36 +02:00
Adolfo Gómez García
a135e3ae9b Removed cache of SP metadata 2022-06-20 15:10:27 +02:00
Adolfo Gómez García
28db2f4e93 Added security options to SAML 2022-06-20 15:09:33 +02:00
Adolfo Gómez García
972c48ddee Merge branch 'v3.5' of github.com:dkmstr/openuds into v3.5 2022-06-17 22:27:37 +02:00
Adolfo Gómez García
118e642700 Fixed frame over buttons ons unmanaged setup 2022-06-17 22:27:23 +02:00
Adolfo Gómez
dfa441871b Fixed logger on Windows (import mistake) 2022-06-17 22:07:25 +02:00
Adolfo Gómez
18c5e3a242 Fixed logger on Windows (import mistake) 2022-06-17 21:59:24 +02:00
Adolfo Gómez García
3a4d571a6c Fixed actor tools changes for typeinfo 2022-06-17 13:54:52 +02:00
Adolfo Gómez García
3cc42e1e73 Adding udsuser to preconnect 2022-06-16 12:52:27 +02:00
Adolfo Gómez García
ffe9baa9a5 Adding udsuser to preconnect 2022-06-16 12:49:28 +02:00
Adolfo Gómez García
0b05009d3f Adding support for several network cards ond unmanaged 2022-06-14 16:51:37 +02:00
Adolfo Gómez García
fefd53c84f Merge remote-tracking branch 'origin/v3.5' 2022-06-13 11:25:25 +02:00
Adolfo Gómez García
b34b12ec9f Fixed RDP Transport with RDS Sessions 2022-06-13 11:24:44 +02:00
Adolfo Gómez García
1fb8956679 Merge remote-tracking branch 'origin/v3.5' 2022-06-07 22:05:20 +02:00
Adolfo Gómez García
fb70524cb3 fixed sampling points 2022-06-07 21:03:49 +02:00
Adolfo Gómez García
4c66401e4f Fixes to reports 2022-06-07 15:38:57 +02:00
Adolfo Gómez García
364ebd6f3a Fixed several reports 2022-06-06 22:29:42 +02:00
Adolfo Gómez García
d96a5e69b0 Merge remote-tracking branch 'origin/v3.5' 2022-06-06 21:42:55 +02:00
Adolfo Gómez García
493cbbb4e7 fixed samplingPoints 2022-06-06 21:42:04 +02:00
Adolfo Gómez García
b9330fd28a Merge remote-tracking branch 'origin/v3.5' 2022-06-06 21:26:42 +02:00
Adolfo Gómez García
5277a74c1c Backport of 4.0 report fixes 2022-06-06 21:26:29 +02:00
Adolfo Gómez García
b7d0fef8bb Stats reports fixes 2022-06-06 21:26:07 +02:00
Adolfo Gómez García
6cf8eb3e77 Fixed admin lang change 2022-06-06 19:06:11 +02:00
Adolfo Gómez García
214c04d636 Remaking counters stats 2022-06-06 19:04:11 +02:00
Adolfo Gómez García
1e01339b93 Fixed language change on admin 2022-06-06 19:03:47 +02:00
Adolfo Gómez García
8f260f5efb Merge remote-tracking branch 'origin/v3.5' 2022-06-03 13:49:23 +02:00
Adolfo Gómez García
2695a5ccdc small cosmetic fix 2022-06-03 13:44:37 +02:00
Adolfo Gómez García
9343f7c263 Added CERTIFICATE_BUNDLE_PATH possible variable on environment to check certificates 2022-06-03 13:44:00 +02:00
Adolfo Gómez García
7775964d62 Added never cache to indes 2022-05-26 15:57:14 +02:00
Adolfo Gómez García
3b0e100021 Merge remote-tracking branch 'origin/v3.5' 2022-05-26 15:37:37 +02:00
Adolfo Gómez García
a207e8f65f Fixed csrf_field name 2022-05-26 15:36:56 +02:00
Adolfo Gómez García
123b2243db updated main 2022-05-26 15:22:30 +02:00
Adolfo Gómez García
c9ef435d78 Merge remote-tracking branch 'origin/v3.5' 2022-05-26 15:20:25 +02:00
Adolfo Gómez García
0a0f2771ae Updated error page logic 2022-05-26 15:00:50 +02:00
Adolfo Gómez García
2f403d3336 Added configurable logout url 2022-05-23 21:36:52 +02:00
Adolfo Gómez García
9c0f2a1859 small README fix 2022-05-23 21:23:10 +02:00
Adolfo Gómez García
ab35451121 Creating tests 2022-05-22 21:51:43 +02:00
Adolfo Gómez García
b0327c4fa0 Creating tests 2022-05-22 21:51:11 +02:00
Adolfo Gómez García
928a7aa58f Creating tests 2022-05-22 21:50:51 +02:00
Adolfo Gómez García
f9e2ccb7d3 Merge remote-tracking branch 'origin/v3.5' 2022-05-20 09:08:13 +02:00
Adolfo Gómez García
8db0e515a5 merged 3.5 user frontend 2022-05-20 09:04:25 +02:00
Adolfo Gómez García
ceb5fd9bde updated csrf info 2022-05-20 09:03:45 +02:00
Adolfo Gómez García
fd0fbf63f0 Added help to configuration 2022-05-19 20:32:28 +02:00
Adolfo Gómez García
8d3653825a Removed Proxy, cleaned some more config variables, and added help to config variables. Refactorized a few config 2022-05-19 18:05:11 +02:00
Adolfo Gómez García
8836815186 improved safeHTML method 2022-05-19 09:17:42 +02:00
Adolfo Gómez García
2eb840e1c7 Merge remote-tracking branch 'origin/v3.5' 2022-05-19 09:15:42 +02:00
Adolfo Gómez García
7bfa6a6c4f Updated admin interface 2022-05-19 09:13:28 +02:00
Adolfo Gómez García
858b79614b Added improved safeHTML method to frontend 2022-05-19 09:11:10 +02:00
Adolfo Gómez García
859f18883f Updated user frontend 2022-05-17 16:48:40 +02:00
Adolfo Gómez García
66f62bcda0 Merge remote-tracking branch 'origin/v3.5' 2022-05-17 16:45:06 +02:00
Adolfo Gómez García
6b8e828835 adding messaging config 2022-05-17 16:45:04 +02:00
Adolfo Gómez García
45b47ce702 Updated user interface 2022-05-17 16:42:06 +02:00
Adolfo Gómez García
d56ce0c653 advancing on notifications 2022-05-15 22:48:17 +02:00
Adolfo Gómez García
801a4ef1a7 Adding level to notifiers and fixed up admin angular 2022-05-15 22:25:17 +02:00
Adolfo Gómez García
12c32bde14 fixed SAML auth 2022-05-10 15:35:52 +02:00
Adolfo Gómez García
002b51a656 Merge remote-tracking branch 'origin/v3.5' 2022-05-10 15:32:28 +02:00
Adolfo Gómez García
dd98ba5653 Remove clear of session on login (nonsense)0 2022-05-10 15:31:29 +02:00
Adolfo Gómez García
3405797bb8 Adding messaging 2022-05-09 21:04:36 +02:00
Adolfo Gómez García
5ce7d008e6 Merge remote-tracking branch 'origin/v3.5' 2022-04-29 16:06:12 +02:00
Adolfo Gómez García
0fe5b32224 Fixed RDP usb redir 2022-04-29 14:59:16 +02:00
Adolfo Gómez García
3ff7d1ea88 Changed script name to be authCallback URL 2022-04-28 18:16:22 +02:00
Adolfo Gómez García
91921537ce Adding tests 2022-04-27 00:37:23 +02:00
Adolfo Gómez García
0f587a4ec1 Merge remote-tracking branch 'origin/v3.5' 2022-04-25 14:31:45 +02:00
Adolfo Gómez García
a0adc1ded3 redirect to logout 2022-04-25 14:29:40 +02:00
Adolfo Gómez García
4f5cc505d3 redirect to logout 2022-04-25 14:28:18 +02:00
Adolfo Gómez García
8bac68b55b Fixed locked on machines_multi 2022-04-25 14:23:46 +02:00
Adolfo Gómez García
b5412e70fd Fixed Lock of service multi 2022-04-25 14:18:46 +02:00
Adolfo Gómez García
6a178478b4 Updated signatures for type checking on all models 2022-04-24 19:07:44 +02:00
Adolfo Gómez García
f3af6a13ff Merge remote-tracking branch 'origin/v3.5' 2022-04-24 17:14:33 +02:00
Adolfo Gómez García
75cd3c4845 Chanced a couple of declarations 2022-04-24 17:13:38 +02:00
Adolfo Gómez García
4067a5c423 Updating typy hints, etc... 2022-04-24 17:04:47 +02:00
Adolfo Gómez García
fbd7edf709 updating rest 2022-04-24 16:54:07 +02:00
Adolfo Gómez García
e8400b8702 updating models 2022-04-24 16:53:10 +02:00
Adolfo Gómez García
e8c45b568d Fixing up some typos 2022-04-24 16:52:45 +02:00
Adolfo Gómez García
3a16b75e82 fixed requests typo 2022-04-23 20:29:12 +02:00
Adolfo Gómez García
586e1c3789 moving REST dispatcher to its own file 2022-04-23 20:23:28 +02:00
Adolfo Gómez García
67f115e50f Merge remote-tracking branch 'origin/v3.5' 2022-04-12 22:54:01 +02:00
Adolfo Gómez García
540a2b83be Added brand to configjs so we can use it on a future 2022-04-12 22:30:32 +02:00
Adolfo Gómez García
b0255a980c Merge remote-tracking branch 'origin/v3.5' 2022-04-12 21:37:06 +02:00
Adolfo Gómez García
aa4d157c30 Fixed request session timeout 2022-04-12 21:36:17 +02:00
Adolfo Gómez García
aaa0f004ee Merge remote-tracking branch 'origin/v3.5' 2022-04-12 14:34:19 +02:00
Adolfo Gómez García
69ca93586a Fixed transport & groups deletion 2022-04-12 14:34:06 +02:00
Adolfo Gómez García
5a47d09c1a Merge remote-tracking branch 'origin/v3.5' 2022-04-08 15:29:49 +02:00
Adolfo Gómez García
cf283bba0f Fixed calendar action delete all groups 2022-04-08 15:29:13 +02:00
Adolfo Gómez García
0525bd4317 Merge remote-tracking branch 'origin/v3.5' 2022-04-06 21:32:31 +02:00
Adolfo Gómez García
9abaada7cb Fixed perms 2022-04-06 21:32:16 +02:00
Adolfo Gómez García
b359892454 images 2022-04-06 20:19:11 +02:00
Adolfo Gómez García
7d5ff93946 Merge remote-tracking branch 'origin/v3.5' 2022-04-06 14:22:53 +02:00
Adolfo Gómez García
927a86c835 Added USB redirection policy for windows 2022-04-06 14:21:52 +02:00
Adolfo Gómez García
4e78c2837c Fixed address passing 2022-04-04 21:20:22 +02:00
Adolfo Gómez García
502cebfc3a Merge remote-tracking branch 'origin/v3.5' 2022-04-04 21:16:37 +02:00
Adolfo Gómez García
2b5aa9c9a4 Fixed address passing to tunnel 2022-04-04 21:12:54 +02:00
Adolfo Gómez García
0f3f50f63c Added ThreadPoolExecutor to check handshakes... 2022-03-30 15:54:09 +02:00
Adolfo Gómez García
69192a2a1b Merge remote-tracking branch 'origin/v3.5' 2022-03-30 15:43:38 +02:00
Adolfo Gómez García
0ca85c5749 Changed check handshake method 2022-03-30 15:43:30 +02:00
Adolfo Gómez García
b3047e366d Fixed 3.5 tunnel DOS attacks tolerance 2022-03-30 15:11:00 +02:00
Adolfo Gómez García
4577552773 Fixed log 2022-03-29 22:36:27 +02:00
Adolfo Gómez García
bec985e360 Restored timeout 2022-03-29 22:14:18 +02:00
Adolfo Gómez García
ccb2dfbdbe Merge remote-tracking branch 'origin/v3.5' 2022-03-29 22:13:50 +02:00
Adolfo Gómez García
d2ef6e3704 Restored timeout 2022-03-29 22:12:43 +02:00
Adolfo Gómez García
b50b27d96e Remove external timeout 2022-03-29 22:06:17 +02:00
Adolfo Gómez García
bf4bb3f704 Merge remote-tracking branch 'origin/v3.5' 2022-03-29 22:01:32 +02:00
Adolfo Gómez García
5fb4461934 Remove external timeout 2022-03-29 22:01:10 +02:00
Adolfo Gómez García
5b4d017c53 Merge branch 'master' of github.com:dkmstr/openuds 2022-03-29 13:10:46 +02:00
Adolfo Gómez García
70b3544f2a added timeout to oppened tunnel to avoid possible DOS 2022-03-29 13:10:37 +02:00
Adolfo Gómez García
564b9db013 Merge remote-tracking branch 'origin/v3.5' 2022-03-29 13:08:54 +02:00
Adolfo Gómez García
1ff0a623db added timeout to oppened tunnel to avoid possible DOS 2022-03-29 13:08:49 +02:00
Adolfo Gómez García
2f5f87e122 added timeout to oppened tunnel to avoid possible DOS 2022-03-29 13:08:34 +02:00
Adolfo Gómez García
a9c32debd2 Merge remote-tracking branch 'origin/v3.5' 2022-03-28 14:00:20 +02:00
Adolfo Gómez García
d9be83863c increaded backlog 2022-03-28 13:59:37 +02:00
Adolfo Gómez García
c675acc2e7 increaded backlog 2022-03-28 13:58:56 +02:00
Adolfo Gómez García
5fed04d64d Included request on parameters, needed on 3.5 2022-03-24 14:21:20 +01:00
Adolfo Gómez García
0662100c30 Merge remote-tracking branch 'origin/v3.5' 2022-03-23 21:34:29 +01:00
Adolfo Gómez García
8a2e2deaf1 small phisical machine fix 2022-03-23 21:32:29 +01:00
Adolfo Gómez García
86990638dc Added new count method for LIMITED services 2022-03-23 21:28:49 +01:00
Adolfo Gómez García
74ad88d1bc Merge remote-tracking branch 'origin/v3.5' 2022-03-21 15:09:29 +01:00
Adolfo Gómez García
40b9572233 fixed tunnel to log bad handshake as hex 2022-03-21 15:08:39 +01:00
Adolfo Gómez García
de71785c76 Merge remote-tracking branch 'origin/v3.5' 2022-03-20 23:10:43 +01:00
Adolfo Gómez García
27cbf920d5 Fixed a couple of things 2022-03-20 23:10:35 +01:00
Adolfo Gómez García
5836b33299 Added new way of counting "active" machines (taking into account the removable and removing services also) 2022-03-17 14:53:32 +01:00
Adolfo Gómez García
9ca143c2db Merge remote-tracking branch 'origin/v3.5' 2022-03-15 20:26:02 +01:00
Adolfo Gómez García
282495ce0f Fixed OSS 2022-03-15 20:22:13 +01:00
Adolfo Gómez García
2b33ffc656 Fixed OSS 2022-03-15 20:07:19 +01:00
Adolfo Gómez García
72700075ef Small tunnel fix 2022-03-15 16:33:15 +01:00
Adolfo Gómez García
ccdd15ed50 Merge remote-tracking branch 'origin/v3.5' 2022-03-15 16:30:23 +01:00
Adolfo Gómez García
e0149900a7 Added protection on broken pipe to tunnel 2022-03-15 16:28:13 +01:00
Adolfo Gómez García
7bed6ac171 Small tunnel fix and installer info 2022-03-15 13:38:50 +01:00
Adolfo Gómez García
1d62dbbacd Added new admin interface supporting notifiers 2022-03-14 20:59:04 +01:00
Adolfo Gómez García
d04068e19f Creating notifiers 2022-03-14 17:03:00 +01:00
Adolfo Gómez García
66aa7ccef3 small type checking fix 2022-03-14 14:44:16 +01:00
Adolfo Gómez García
c0c54f9ccd Merge remote-tracking branch 'origin/v3.5' 2022-03-14 14:43:57 +01:00
Adolfo Gómez García
0d77e86af2 small type checking fix 2022-03-14 14:42:40 +01:00
Adolfo Gómez García
b41a8e38cf Fixed GetRootUser 2022-03-13 15:41:45 +01:00
Adolfo Gómez García
410b0952e9 fixed "autoimported" module 2022-03-13 15:02:07 +01:00
Adolfo Gómez García
b9f57c47b0 Adde generic factory and added module loader to jobs 2022-03-11 16:39:39 +01:00
Adolfo Gómez García
07b0b00b90 Done refactoring module loader 2022-03-10 21:05:59 +01:00
Adolfo Gómez García
6e69246ca8 Added moduleLoaders to almost everything now 2022-03-10 20:32:40 +01:00
Adolfo Gómez García
a5554ed85a Adding generic importers to simplify module loading 2022-03-10 18:58:16 +01:00
Adolfo Gómez García
6c17b77841 Addded generic Factory for UDS Modules 2022-03-09 23:17:19 +01:00
Adolfo Gómez García
05a04997d6 Improved passwords security on DB 2022-03-07 23:10:10 +01:00
Adolfo Gómez García
b477b78d61 Merge remote-tracking branch 'origin/v3.5' 2022-03-06 15:41:26 +01:00
Adolfo Gómez García
a179522f4c Fixed crypto key loading 2022-03-06 15:40:49 +01:00
Adolfo Gómez García
2b6193a1ec Fixed SAMLResponse conversion under some circunstances 2022-03-02 15:51:59 +01:00
Adolfo Gómez García
0e257c779b Converted HTTP-POSt to HTTP-Request on SAML logout 2022-03-01 12:58:09 +01:00
Adolfo Gómez García
43eb09e9e2 Fixed logout binding to redirect 2022-02-28 16:48:01 +01:00
Adolfo Gómez García
6eab070bd1 Merge remote-tracking branch 'origin/v3.5' 2022-02-27 23:42:42 +01:00
Adolfo Gómez García
21c2976d82 Fixed copyright for debian 2022-02-27 23:41:50 +01:00
Adolfo Gómez García
3f148f3bf0 notifications table 2022-02-25 03:05:27 +01:00
Adolfo Gómez García
f3c2015210 Fixed migrations from 3.5 2022-02-25 03:02:54 +01:00
Adolfo Gómez García
afd653422e Merge remote-tracking branch 'origin/v3.5' 2022-02-23 21:57:08 +01:00
Adolfo Gómez García
ee30ab4604 Fixed authcallbacks 2022-02-23 21:54:23 +01:00
Adolfo Gómez García
aad3336717 Migrated SAML auth to OneLogin library 2022-02-23 21:10:45 +01:00
Adolfo Gómez García
29e1694fce Removed lasso and added OneLogin saml library 2022-02-23 16:56:54 +01:00
Adolfo Gómez García
1fba4d3f9f Fixed check of ip 2022-02-23 14:17:29 +01:00
Adolfo Gómez García
5084fec43f Fixed SQLITE DB problems 2022-02-22 13:26:24 +01:00
Adolfo Gómez García
0ce1a565ab merged 3.5 temporal fix for login redirection 2022-02-21 14:34:58 +01:00
Adolfo Gómez García
6cc1a8823d Merge remote-tracking branch 'origin/v3.5' 2022-02-21 14:29:08 +01:00
Adolfo Gómez García
04e24d406f Added small fix to allow tempora user redirect 2022-02-21 14:28:49 +01:00
Adolfo Gómez García
3667c82529 added a new ldap constant to ldaputil 2022-02-20 00:24:38 +01:00
Adolfo Gómez García
8cd050f71d Fixed changes to allow redirects 2022-02-19 16:08:11 +01:00
Adolfo Gómez García
88905b4e63 Refactor of assigned an unused 2022-02-18 15:51:49 +01:00
Adolfo Gómez García
67db932b0f Updating authentication response methods to include a possible url on login failure 2022-02-17 21:44:10 +01:00
Adolfo Gómez García
1be8edec92 Added getRootDSE method to ldaputils 2022-02-17 15:50:27 +01:00
Adolfo Gómez García
65087f5d47 Added SAML auth as open 2022-02-16 21:12:48 +01:00
Adolfo Gómez García
5388d03213 gitignore al ldaputil small comment fix 2022-02-15 22:44:09 +01:00
Adolfo Gómez García
6da7a4134e Merge remote-tracking branch 'origin/v3.5' 2022-02-15 22:43:33 +01:00
Adolfo Gómez García
f58ef9b6d3 Removed sympy inclusion err 2022-02-15 15:16:04 +01:00
Adolfo Gómez García
18d4147d59 Changed OS Detection system 2022-02-15 15:05:55 +01:00
Adolfo Gómez García
b77330ac8f Added base notification mechanics 2022-02-13 19:38:40 +01:00
Adolfo Gómez García
7fca229537 Merge remote-tracking branch 'origin/v3.5' 2022-02-10 14:47:06 +01:00
Adolfo Gómez García
ccd429454e Updated translations due to recent fixes 2022-02-10 14:46:27 +01:00
Adolfo Gómez García
a2e5e00aa6 Merge remote-tracking branch 'origin/v3.5' 2022-02-10 13:33:50 +01:00
Adolfo Gómez García
5ce7ddc3a7 Fixed HTML5 transports and advanced tab translation for label 2022-02-10 13:32:05 +01:00
Adolfo Gómez García
02fcff2c94 refactorized alerts to messaging 2022-02-08 21:30:00 +01:00
Adolfo Gómez García
9e5b06e835 Adding notifier to allow sending some kind of event to outside recipients (as emails, telegram, ...) 2022-02-08 20:24:34 +01:00
Adolfo Gómez García
c7f96251ac Added level to notifier 2022-02-08 19:08:46 +01:00
Adolfo Gómez García
1b9fd22ba1 Merge remote-tracking branch 'origin/v3.5' 2022-02-07 16:12:51 +01:00
Adolfo Gómez García
3dd73f4723 Vertical label now appears "badly" with waseyprint. Disabled by now 2022-02-07 16:02:16 +01:00
Adolfo Gómez García
c3531f3e7e Fixed saving stats events (field conversion ignored original field name) 2022-02-07 15:54:38 +01:00
Adolfo Gómez García
fdd1b7235a Adding notifier base model. This will allow us to send remote notifications 2022-02-07 13:23:58 +01:00
Adolfo Gómez García
0d50e5ef93 Merged 3.5 fix on migrations 2022-02-06 04:02:38 +01:00
Adolfo Gómez García
ba7b1c0198 Fixed 0038 migration to include config moving 2022-02-06 04:01:29 +01:00
Adolfo Gómez García
c4a886c28d Fixed squashed migrations 2022-02-06 03:58:54 +01:00
Adolfo Gómez García
0355ef9591 squashed all previous to 3.5 migrations 2022-02-06 03:44:59 +01:00
Adolfo Gómez García
e0fa75cb00 squashed all previous to 3.5 migrations 2022-02-06 03:44:49 +01:00
Adolfo Gómez García
3b991e0749 Fixed ip lengths to allow future ipv6 support 2022-02-06 03:24:38 +01:00
Adolfo Gómez García
dd4dc738b4 Merge remote-tracking branch 'origin/v3.5' 2022-02-05 17:51:06 +01:00
Adolfo Gómez García
d5c9ee341d Fixed tunnel version 2022-02-05 17:50:55 +01:00
Adolfo Gómez García
ba90dae5d6 Fixed Tunnel version 2022-02-05 17:50:34 +01:00
Adolfo Gómez García
f58cc159a7 Removed comments of old code 2022-02-05 17:31:31 +01:00
Adolfo Gómez García
fee413aa23 Added basic HA check on metapools, after adding "isAvailable" to all existing services 2022-02-01 16:16:57 +01:00
Adolfo Gómez García
189db28dc5 Added migration to add HA to metapool 2022-02-01 16:05:44 +01:00
Adolfo Gómez García
86a237ccac Homogenized services response dict 2022-02-01 15:47:29 +01:00
Adolfo Gómez García
9041e48080 Added end notification to UDS 2022-02-01 13:49:34 +01:00
Adolfo Gómez García
4893fa4fbe Fixed counters 2022-02-01 13:10:13 +01:00
Adolfo Gómez García
082ef6830d Merge remote-tracking branch 'origin/v3.5' 2022-01-30 19:34:19 +01:00
Adolfo Gómez García
f7cd474264 Fixed double open on meta poools 2022-01-30 18:21:32 +01:00
Adolfo Gómez García
2a7b112437 Merge remote-tracking branch 'origin/v3.5' 2022-01-29 21:45:46 +01:00
Adolfo Gómez García
a4390f7918 upgrading service 2022-01-29 21:44:14 +01:00
Adolfo Gómez García
a255b52628 added info (apart of prefix to uuid) if pool is meta or not 2022-01-29 21:43:14 +01:00
Adolfo Gómez García
8d93144e24 Fixed meta pools non being correctly checked 2022-01-28 11:54:18 +01:00
Adolfo Gómez García
27d158f514 Fixed metapool admin 2022-01-28 11:14:32 +01:00
Adolfo Gómez García
e043a79721 Ported to asyncio uds tunnel. 2022-01-27 13:10:07 +01:00
Adolfo Gómez García
2f37caaf22 Merge remote-tracking branch 'origin/v3.5' 2022-01-27 12:17:16 +01:00
Adolfo Gómez García
2b4e771709 Fixed autorun check from api 2022-01-27 12:17:00 +01:00
Adolfo Gómez García
77b6eff8e4 Removing curio from tunneler, so we do not have an unneeded dependency 2022-01-26 14:32:41 +01:00
Adolfo Gómez García
7d8ae689b5 Moving from curio to asyncio. 2022-01-26 12:18:41 +01:00
Adolfo Gómez García
143b9b675b Merge remote-tracking branch 'origin/v3.5' 2022-01-21 12:07:24 +01:00
Adolfo Gómez García
3ebc0dd26f Fixed certs locations for some platforms 2022-01-21 12:04:54 +01:00
Adolfo Gómez García
ecb876157a small fix 2022-01-20 11:16:23 +01:00
Adolfo Gómez García
f40c2ed618 Added isAvailable for all services 2022-01-19 14:11:37 +01:00
Adolfo Gómez García
61a32e13a2 Merge remote-tracking branch 'origin/v3.5' 2022-01-18 14:12:47 +01:00
Adolfo Gómez García
79739bf9b8 Removed unused .desktop file for thinpro 2022-01-18 14:12:31 +01:00
Adolfo Gómez García
c14ae284b6 Merge remote-tracking branch 'origin/v3.5' 2022-01-18 13:34:46 +01:00
Adolfo Gómez García
f702c144fc small thinpro fix 2022-01-18 13:34:33 +01:00
Adolfo Gómez García
7fc51ce513 Added isAvailable for more services 2022-01-18 13:21:44 +01:00
Adolfo Gómez García
0208c9b3f9 Merge remote-tracking branch 'origin/v3.5' 2022-01-18 13:18:43 +01:00
Adolfo Gómez García
ce2d2b1c2e added installer for thinpro 7.2 2022-01-18 13:18:24 +01:00
Adolfo Gómez García
18a49cece3 Merge remote-tracking branch 'origin/v3.5' 2022-01-18 11:44:16 +01:00
Adolfo Gómez García
790c204b6a fixed uds client actor launching 2022-01-17 13:46:14 +01:00
Adolfo Gómez García
d80cf4052e removed -s 2022-01-17 13:43:51 +01:00
Adolfo Gómez García
03cdec8c31 Merge remote-tracking branch 'origin/v3.5' 2022-01-14 14:26:08 +01:00
Adolfo Gómez García
6a86b0ff04 Updated translations 2022-01-14 12:37:14 +01:00
Adolfo Gómez García
1667c8b4a8 adding "isAvaliable" method for services 2022-01-13 13:32:36 +01:00
Adolfo Gómez García
8018c7bed7 Merge remote-tracking branch 'origin/v3.5' 2022-01-12 13:35:02 +01:00
Adolfo Gómez García
0d412c4a9a Modified thinpro image tar from bz2 to gz 2022-01-12 13:25:26 +01:00
Adolfo Gómez García
ac9e6dafdf added thinpro installer generator 2022-01-12 13:20:33 +01:00
Adolfo Gómez García
58f4cd8356 Merge remote-tracking branch 'origin/v1.5' 2022-01-12 12:08:50 +01:00
Adolfo Gómez García
efd0ca3f88 Fixed tunnel stop comms 2022-01-11 15:36:18 +01:00
Adolfo Gómez García
edb4a32496 Updated translations 2022-01-10 14:34:09 +01:00
Adolfo Gómez García
e41c0f32bb Merge remote-tracking branch 'origin/v3.5' 2022-01-04 10:39:12 +01:00
Adolfo Gómez García
b239ff6cab Removed "harcoded" msrdc path for mac 2022-01-04 10:38:30 +01:00
Adolfo Gómez García
5de90bf421 Merge remote-tracking branch 'origin/v3.5' 2022-01-03 14:36:06 +01:00
Adolfo Gómez García
d55d1bc619 Added localized MSRDP as possible path 2022-01-03 14:35:48 +01:00
Adolfo Gómez García
493abb6228 Merge remote-tracking branch 'origin/v3.5' 2022-01-03 14:24:07 +01:00
Adolfo Gómez García
917a201483 Added localized MSRDP as possible path 2022-01-03 14:23:52 +01:00
Adolfo Gómez García
a071e2e8f5 Merge remote-tracking branch 'origin/v3.5' 2022-01-03 14:10:26 +01:00
Adolfo Gómez García
4809252434 Changed concurrent removal to take into account real removals, not removal checks 2022-01-03 14:07:46 +01:00
Adolfo Gómez García
12e74c16b5 * Explained why stop shuld be ignored if no user service is found
* Small type checking addons
* Added method to allow "check" the availability of a service, currently used before removal
* Fixed removal so concurrent removal refers to real removals, not to marked for removal
2022-01-03 14:02:41 +01:00
Adolfo Gómez García
6d873ceccd Merge remote-tracking branch 'origin/v3.5' 2021-12-22 14:05:47 +01:00
Adolfo Gómez García
8be0d9702a Fixed sessions providers for html5rdp 2021-12-22 14:04:49 +01:00
Adolfo Gómez García
26f45b429f Merge remote-tracking branch 'origin/v3.5' 2021-12-22 13:37:06 +01:00
Adolfo Gómez García
36acb0b0c0 Fixed transports sorting on metapools 2021-12-22 13:10:07 +01:00
Adolfo Gómez García
420b78d45d Fixed STOP "eating" on application stop 2021-12-21 15:58:46 +01:00
Adolfo Gómez García
e1ccc62dab Fixed minvalue for max services 2021-12-21 15:53:35 +01:00
Adolfo Gómez García
49b2bd8772 Merge remote-tracking branch 'origin/v3.5' 2021-12-21 11:19:47 +01:00
Adolfo Gómez García
6b0d98d4eb Fixed radius auth not using "appliaction Prefix" for extracting groups from Class Attribute (now accepts group=... and {appPrefix}group=.... as group markers 2021-12-21 11:14:57 +01:00
Adolfo Gómez García
354061f55c Merge remote-tracking branch 'origin/v3.5' 2021-12-20 12:12:28 +01:00
Adolfo Gómez García
7bec7bd7cc Fixed HTMLRDP for access to RDP session with automanaged users 2021-12-20 12:04:16 +01:00
Adolfo Gómez García
49975ab5d2 Upgrading for new django 4.0 2021-12-10 15:12:32 +01:00
Adolfo Gómez García
44f219402e removed orjson, uds uses numbers as key on dict and orjson does not supports it 2021-12-10 13:45:49 +01:00
Adolfo Gómez García
b3a8ae8abe Migrating to Django 4.0 (fixes) 2021-12-10 13:41:10 +01:00
Adolfo Gómez García
9ac2aaef81 Improved AutoAttributes & small typo fix on proxmox publication 2021-12-10 13:06:33 +01:00
Adolfo Gómez García
de0a2e2a34 Merge remote-tracking branch 'origin/v3.5' 2021-12-10 13:05:45 +01:00
Adolfo Gómez García
270957fab5 Updated settings sample 2021-12-10 13:04:54 +01:00
Adolfo Gómez García
1702cd910a Merge remote-tracking branch 'origin/v3.5' 2021-11-30 13:54:33 +01:00
Adolfo Gómez García
47c6ca42f1 added Content-Security-Policy to security 2021-11-30 13:54:15 +01:00
Adolfo Gómez García
78639af1a5 Merge remote-tracking branch 'origin/v3.5' 2021-11-30 13:32:56 +01:00
Adolfo Gómez García
c1f6ed376b added Content-Security-Policy to security 2021-11-30 13:32:37 +01:00
Adolfo Gómez García
8bebce4c6e added Content-Security-Policy to security 2021-11-30 13:31:12 +01:00
Adolfo Gómez García
e18f3746b4 Merge remote-tracking branch 'origin/v3.5' 2021-11-30 12:30:31 +01:00
Adolfo Gómez García
250ade6aee Fixed assignement of new services if pool is at 100% usage 2021-11-30 12:18:04 +01:00
Adolfo Gómez García
10bde45004 Merge remote-tracking branch 'origin/v3.5' 2021-11-26 11:59:07 +01:00
Adolfo Gómez García
bde63f7b4f Added check for database connection problem on config 2021-11-26 11:52:49 +01:00
Adolfo Gómez García
057a26ea7b Completed network filtering for authentication, and improbed network filtering on transports (better undestanding now) 2021-11-23 11:55:55 +01:00
Adolfo Gómez García
e8dae69f6f Several actiosn:
* Added Disabled as an option state for an authenticator
* Added networks to check source to authenticators
* Generalized network access, now is usable from transports and from authenticators
* Fixed configjs to adapt to new model
2021-11-22 13:39:08 +01:00
Adolfo Gómez García
91923654f0 Added orjson as json "first option" for REST API (python json else) 2021-11-21 18:10:49 +01:00
Adolfo Gómez García
a0365e1277 Merge remote-tracking branch 'origin/v3.5' 2021-11-19 14:14:12 +01:00
Adolfo Gómez García
eb4be53508 Fixed cache time and points on system chart info 2021-11-19 14:10:36 +01:00
Adolfo Gómez García
3003066a91 Removed "erroring" machine is it has any exception on connection 2021-11-18 15:35:04 +01:00
Adolfo Gómez García
10805ded7e Removed "erroring" machine is it has any exception on connection 2021-11-18 15:26:23 +01:00
Adolfo Gómez García
4b6ad6a2ed Merge remote-tracking branch 'origin/v3.5' 2021-11-16 14:20:07 +01:00
Adolfo Gómez García
21c221a6db Added check for circular connections on Xen when using backup server 2021-11-16 14:19:46 +01:00
Adolfo Gómez García
1857134f42 Fixed admin 2021-11-15 12:15:06 +01:00
Adolfo Gómez García
e06f13fc84 Updating validators 2021-11-12 12:14:16 +01:00
Adolfo Gómez García
6a14917ec5 Updating validators 2021-11-12 11:35:09 +01:00
Adolfo Gómez García
85aab86b02 Fixed token length and remade migration 2021-11-12 10:48:11 +01:00
Adolfo Gómez García
eeae98ca79 Added token alias to secure unmanaged machine token 2021-11-11 13:50:58 +01:00
Adolfo Gómez García
11f6eec913 Merge remote-tracking branch 'origin/v3.5' 2021-11-11 12:07:49 +01:00
Adolfo Gómez García
835dc05e63 Added scheduled action to pool so we can remove "old assigned machines" with a programmed action 2021-11-11 12:07:19 +01:00
Adolfo Gómez García
e4d40b651e Merge remote-tracking branch 'origin/v3.5' 2021-11-10 10:57:09 +01:00
Adolfo Gómez García
4cc4af5bd1 Fixed special case for admin form field of numeric fields without limits 2021-11-10 10:56:05 +01:00
Adolfo Gómez García
986a82f225 Fixed special case for admin form field of numeric fields without limits 2021-11-10 10:32:15 +01:00
Adolfo Gómez García
a05390ed6c Merge remote-tracking branch 'origin/v3.5' 2021-11-08 13:48:17 +01:00
Adolfo Gómez García
90b64c1721 Changed parameter _USERNAME_ for _USER_ on URL Transport (as in tooltip) 2021-11-08 13:28:09 +01:00
Adolfo Gómez García
c89c8d0523 Merge remote-tracking branch 'origin/v3.5' 2021-11-08 13:20:11 +01:00
Adolfo Gómez García
f403d4ff3e Fixed Min-Max admin values checking && set proxmox vmid as readonly 2021-11-08 13:18:58 +01:00
Adolfo Gómez García
c5071cf348 Fixed Min-Max admin values checking && set proxmox vmid as readonly 2021-11-08 13:16:44 +01:00
Adolfo Gómez García
7f4453bd37 Added stats to udsfs 2021-11-08 11:55:59 +01:00
Adolfo Gómez García
e3568bc580 Updating UDSFS 2021-11-05 12:51:04 +01:00
Adolfo Gómez García
f273d262ac A few more advancements 2021-11-04 14:03:17 +01:00
Adolfo Gómez García
b55df32db0 Advancing on UDSFS 2021-11-04 12:46:40 +01:00
Adolfo Gómez García
6792283e44 Merge remote-tracking branch 'origin/v3.5' 2021-11-03 15:21:43 +01:00
Adolfo Gómez García
679956702b Fixed legacy textx 2021-11-03 14:54:58 +01:00
Adolfo Gómez García
98d7a24656 Fixed check certificate on python 3.6 2021-11-03 14:39:58 +01:00
Adolfo Gómez García
33764e5c1c Merge remote-tracking branch 'origin/v3.5' 2021-11-02 11:59:09 +01:00
Adolfo Gómez García
b67771d5f3 Fixed HTMLRDP parameters 2021-11-02 11:56:21 +01:00
Adolfo Gómez García
2d1897f720 Merge remote-tracking branch 'origin/v3.5' 2021-11-02 11:06:06 +01:00
Adolfo Gómez García
672c35c903 Fixed admin date && updated translations 2021-11-02 11:05:38 +01:00
Adolfo Gómez García
be013ac6dc Adding type checking on fuse before proceding to use it 2021-11-01 22:28:45 +01:00
Adolfo Gómez García
398837c20f Adding type checking on fuse before proceding to use it 2021-11-01 22:26:18 +01:00
Adolfo Gómez García
a6f1e95cc0 Adding type checking on fuse before proceding to use it 2021-11-01 18:44:11 +01:00
Adolfo Gómez García
a957e368e7 Experimenting with use for adding an "UDS FS" so we can explore several UDS contained data easily 2021-11-01 00:40:54 +01:00
Adolfo Gómez García
6df1bc0a50 Removed Legacy client messages from frontend 2021-10-29 11:38:39 +02:00
Adolfo Gómez García
937465b2f2 Adding stats events for os manager relevant events (init, ready and release right now) 2021-10-28 16:17:26 +02:00
Adolfo Gómez García
e9df8c5cb1 Merge remote-tracking branch 'origin/v3.5' 2021-10-28 12:39:59 +02:00
Adolfo Gómez García
01119d1914 Fixed armhf appimage generation 2021-10-28 11:19:49 +02:00
Adolfo Gómez García
4f107ad464 Cleaning up things 2021-10-27 16:27:03 +02:00
Adolfo Gómez García
5b5a4e31e7 Merge remote-tracking branch 'origin/v3.5' 2021-10-27 13:06:45 +02:00
Adolfo Gómez García
98685c6e6a added back notifiedReady 2021-10-27 13:06:39 +02:00
Adolfo Gómez García
a4d1ecb95f Added call to "notifyReady" on osmanager ready notification 2021-10-27 13:05:41 +02:00
Adolfo Gómez García
cb064f9af5 Removing all actor 2.2 support 2021-10-27 12:54:45 +02:00
Adolfo Gómez García
604f1c4a89 Removing old UDS Actor 2.2 support 2021-10-27 12:20:41 +02:00
Adolfo Gómez García
590f3191ac Removing "globalRequest" cache and passing through received request object to authenticators 2021-10-26 21:15:07 +02:00
Adolfo Gómez García
e999e5acf8 Removed outdated documentation 2021-10-26 16:31:54 +02:00
Adolfo Gómez García
101f846f0d Merge remote-tracking branch 'origin/v3.5' 2021-10-25 14:45:18 +02:00
Adolfo Gómez García
237f7e5b77 Added igel port 2021-10-25 14:42:42 +02:00
Adolfo Gómez García
edb74ab9c6 Removed "legacy" 2.7 UDS Client (not working anymore on 3.5)
Fixed igel templates
2021-10-25 14:36:14 +02:00
Adolfo Gómez García
3ec0c15039 Merge remote-tracking branch 'origin/v3.5' 2021-10-25 14:07:39 +02:00
Adolfo Gómez García
86eb1a9421 Added "cloud marked" icons for tunneled transports 2021-10-25 12:56:18 +02:00
Adolfo Gómez García
ce433c0661 Merge remote-tracking branch 'origin/v3.5' 2021-10-23 22:37:07 +02:00
Adolfo Gómez García
c09ea0eb63 Moved security part from request to security middleware 2021-10-23 22:36:12 +02:00
Adolfo Gómez García
b185024aeb Merge remote-tracking branch 'origin/v3.5' 2021-10-22 14:41:24 +02:00
Adolfo Gómez García
ea79ccbee1 Added igel package creation scripts 2021-10-22 14:37:53 +02:00
Adolfo Gómez García
3a9312efe0 Fixed requests "getIdent" to retorn an unique id even in case of running as a asyncio task 2021-10-20 21:52:30 +02:00
Adolfo Gómez García
27535d4b43 Merge remote-tracking branch 'origin/v3.5' 2021-10-19 18:23:31 +02:00
Adolfo Gómez García
da82a26dd8 Now when we save a service pool, ensures that max_srvs is at leat 1 for services with cache 2021-10-19 18:21:32 +02:00
Adolfo Gómez García
1eeab5f75f Merge remote-tracking branch 'origin/v3.5' 2021-10-18 18:01:27 +02:00
Adolfo Gómez García
c129c83ca0 Added -s also to udsactor user space 2021-10-18 18:00:05 +02:00
Adolfo Gómez García
b2adafdec7 Merge remote-tracking branch 'origin/v3.5' 2021-10-18 17:17:16 +02:00
Adolfo Gómez García
d8e6de8c1e Removed unused variable 2021-10-18 17:16:17 +02:00
Adolfo Gómez García
9c6a72d3ac Merge remote-tracking branch 'origin/v3.5' 2021-10-18 17:09:00 +02:00
Adolfo Gómez García
e0d79cb590 Added -s to UDSClient python3 parameter, so local libs does not interfere with package 2021-10-18 17:04:44 +02:00
Adolfo Gómez García
59bd6c1649 Reversed the order for change password on 3.5 UDS 2021-10-18 16:59:59 +02:00
Adolfo Gómez García
564f0e17de added check for "emtpy" usernames or groups on creation 2021-10-18 13:05:53 +02:00
Adolfo Gómez García
842212f186 Removed ssh-tunnel not used on 3.5 release 2021-10-17 01:43:01 +02:00
Adolfo Gómez García
11342914cc Merge remote-tracking branch 'origin/v3.5' 2021-10-15 10:58:11 +02:00
Adolfo Gómez García
e4b609c4ce Fixed key for debian packages on client appimage recipe 2021-10-15 10:57:43 +02:00
Adolfo Gómez García
741855030f Removed "prints" :) 2021-10-15 10:44:22 +02:00
Adolfo Gómez García
293b7f02ad added small comment for future to actor v3 2021-10-13 11:19:44 +02:00
Adolfo Gómez García
fddd54fa99 Added correcto management of "logout" in case of an unmanaged machine "reboot" 2021-10-08 12:30:00 +02:00
Adolfo Gómez García
cd640af37f Added correcto management of "logout" in case of an unmanaged machine "reboot" 2021-10-08 12:28:37 +02:00
Adolfo Gómez García
b2f2deebce Merge remote-tracking branch 'origin/v3.5' 2021-10-08 00:57:22 +02:00
Adolfo Gómez García
6f99b63731 Locales 2021-10-08 00:57:08 +02:00
Adolfo Gómez García
6b3355f819 Added locking multi_ip machines if accessed from outside UDS flag & logic 2021-10-07 13:47:03 +02:00
Adolfo Gómez García
660cfdcd0e Adding console login/logout logic on static machines 2021-10-07 12:49:40 +02:00
Adolfo Gómez García
47df6c58fc Cosmetic chage to actorv3 2021-10-06 15:21:50 +02:00
Adolfo Gómez García
91c90766a3 Updated translations 2021-10-06 15:10:35 +02:00
Adolfo Gómez García
840a7a02bd Merge remote-tracking branch 'origin/v3.5' 2021-10-06 12:39:06 +02:00
Adolfo Gómez García
2a834460d1 Fixing up html5rdp 2021-10-06 12:38:45 +02:00
Adolfo Gómez García
f80b00667e Upgrading versions 2021-10-05 13:26:55 +02:00
Adolfo Gómez García
ef9325aab9 Start of v4.0. 3.5 is closed now 2021-10-05 12:29:29 +02:00
Adolfo Gómez García
5bd77676ca Fixed log of user correctly authenticated, but not belongs to any group 2021-10-05 12:23:13 +02:00
Adolfo Gómez García
8ef97a7773 Fix for client with python 3.6 2021-10-01 12:35:20 +02:00
Adolfo Gómez García
abafa7bfac Added group state "Inactive" 2021-09-29 14:50:40 +02:00
Adolfo Gómez García
dcb7b3e28e Make 3.5 client compatible with python 3.6 2021-09-29 13:42:26 +02:00
Adolfo Gómez García
41aa22fadd Removed optional parameter "transport" from ticket REST api creation. This is due to the fact than the transport needs to be checked on Client browser (user ip, SO, etc...) 2021-09-29 11:04:51 +02:00
Adolfo Gómez García
d02974ad87 Error page was not displayed correctly 2021-09-29 10:46:58 +02:00
Adolfo Gómez García
b2a067300c Added sample ticket auth test 2021-09-29 00:14:02 +02:00
Adolfo Gómez García
afbc75bff0 Added boolean True as valid force value 2021-09-29 00:13:33 +02:00
Adolfo Gómez García
4c453d2b1f Added more info to ticket timedout error on tunnel 2021-09-24 14:42:01 +02:00
Adolfo Gómez García
26f33626c2 Updated translations 2021-09-24 13:52:17 +02:00
Adolfo Gómez García
cb8284d076 Updated RDP scripts (simple cosmetic changes) 2021-09-23 16:53:17 +02:00
Adolfo Gómez García
ef3dd893d9 Added nicedcv protocol && a couple of aliases parameters for user_interface future migration 2021-09-21 16:43:27 +02:00
Adolfo Gómez García
d531a1612a Added "visibleFrom" to authenticators, so we can add custom filters for showing them on login screen 2021-09-16 13:30:38 +02:00
Adolfo Gómez García
de9c06bc2c Fixed "realname overwrite" on internaldb auth 2021-09-15 13:15:55 +02:00
Adolfo Gómez García
2400cc99cd Updated translations 2021-09-15 12:47:08 +02:00
Adolfo Gómez García
7f5c3c3bbd Fixed new remove all groups description & fixed not removing pinbar on tunnel rdp 2021-09-14 11:02:37 +02:00
Adolfo Gómez García
710f2fb0e4 Fixed task manager stop 2021-09-09 13:59:42 +02:00
Adolfo Gómez García
ede23ad793 Improved check of tunneled requests 2021-09-09 12:56:25 +02:00
Adolfo Gómez García
9a3913cc42 Added scheduled action "Remove all transports" and "remove all groups" 2021-09-07 13:55:16 +02:00
Adolfo Gómez García
5bf98782ea Added autocomplete to field types 2021-09-07 13:31:30 +02:00
Adolfo Gómez García
3a69c9205e Removed nonsense security check right now... 2021-09-07 12:15:44 +02:00
Adolfo Gómez García
3615db877e Fix small error on new singleton for taskManager 2021-09-06 13:39:40 +02:00
Adolfo Gómez García
2286ccaca1 Fixed about 2021-09-06 12:36:58 +02:00
Adolfo Gómez García
f90bf3a421 Added sedcurity middleware also 2021-09-04 22:17:41 +02:00
Adolfo Gómez García
df815776da Added asgi from newer model 2021-09-04 21:29:16 +02:00
Adolfo Gómez García
54f7fd21dc Better singleton pattern (more reusable) 2021-09-04 17:16:57 +02:00
Adolfo Gómez García
8e3d90e7f3 Removed "experimental" from AD group on OS Manager and fix on actor runner 2021-09-03 13:38:39 +02:00
Adolfo Gómez García
afa9e0aab6 Upgraded angular version of js 2021-09-03 02:25:01 +02:00
Adolfo Gómez García
77b0c7c8e1 added comment to user interface 2021-09-03 01:31:02 +02:00
Adolfo Gómez García
23afd01004 Fixed log removal 2021-09-02 13:27:27 +02:00
Adolfo Gómez García
c30a67d363 Fixed admin 2021-08-31 14:13:17 +02:00
Adolfo Gómez García
aa2d268453 Fixed admin interface small bug 2021-08-31 13:44:13 +02:00
Adolfo Gómez García
de40c72d9e Fixed "disabled" tag to allow login with only federated auths 2021-08-24 17:02:36 +02:00
Adolfo Gómez García
d0b30b561c Updated cache decorator and updated signatures of modified plugins 2021-08-24 14:07:35 +02:00
Adolfo Gómez García
e485374836 Formating and type fixing 2021-08-24 12:15:10 +02:00
Adolfo Gómez García
3934f2b88d Formating and type fixing all transports 2021-08-24 11:51:56 +02:00
Adolfo Gómez García
c72bcf4200 More formating 2021-08-23 14:59:07 +02:00
Adolfo Gómez García
1b7076e645 Changed "app.exec_" by "app.exec" for future pyqt6 2021-08-21 23:06:19 +02:00
Adolfo Gómez García
e637f208bd Changed app.exec_ by app.exec (future PyQt6) 2021-08-21 23:05:20 +02:00
Adolfo Gómez García
75e54618bb Removed duplicated download 2021-08-19 12:21:39 +02:00
Adolfo Gómez García
04864e3846 Fixed to ensure cache is uptated after template creation 2021-08-19 01:21:09 +02:00
Adolfo Gómez García
a52be141ea Added proxmox connection error check and try to handle y gracefully 2021-08-17 13:04:20 +02:00
Adolfo Gómez García
afcbd058d1 Formating & fixing type checkings 2021-08-14 15:47:21 +02:00
Adolfo Gómez García
8285e2daad More formating & minor typing fixes 2021-08-13 15:11:22 +02:00
Adolfo Gómez García
03bfb3efbb Formating & minor typing fixes 2021-08-13 14:53:23 +02:00
Adolfo Gómez García
8c4b84e7db removed statsManager and used directly "StatsManager.manager()" 2021-08-13 14:09:46 +02:00
Adolfo Gómez García
4f8fe793cc Updated translations 2021-08-13 13:34:38 +02:00
Adolfo Gómez García
286b320257 Updated openstack to look for correct volume api
Updated admin to make optional the "vnc" for user services
2021-08-13 13:33:39 +02:00
Adolfo Gómez García
68411f0726 UDS 3.4 now uses volumev3 for non legacy openstack connections (legacy maintains v2) 2021-08-11 18:59:18 +02:00
Adolfo Gómez García
1be49a6e0e Separated processes manager from main uds_tunnel 2021-08-05 12:53:44 +02:00
Adolfo Gómez García
c21c0b44ce Added guacamole rdp parameter for future suppport 2021-08-04 18:59:51 +02:00
Adolfo Gómez García
46aa9139a0 Fixed Guacamole dict 2021-08-02 13:14:57 +02:00
Adolfo Gómez García
574b19a905 Fixed bug on user services page load and updated translations 2021-07-29 13:13:43 +02:00
Adolfo Gómez García
612646bd1c Fixed userService name on ServiceNotReady exception && small fix to comment 2021-07-29 12:24:24 +02:00
Adolfo Gómez García
10d9279b89 Added default value as TRUE to font smoothing for RDP 2021-07-28 14:08:16 +02:00
Adolfo Gómez García
a8a5063083 Updated Guacamole to only accept authenticated tunnel connections
* Added handshake check BEFORE opening SSL tunnel
2021-07-28 12:57:58 +02:00
Adolfo Gómez García
29b6613c95 Updated space 2021-07-27 12:51:10 +02:00
Adolfo Gómez García
8aa7dc3c6f Added PORT to RDP connections 2021-07-27 12:40:12 +02:00
Adolfo Gómez García
e75d373d03 Service multi is fixed
(Also small tunnel beautify)
2021-07-23 14:00:21 +02:00
Adolfo Gómez García
91d2398ade Fixed multy phisical machines service to add a "custom" maximum duration for assignation 2021-07-21 13:59:12 +02:00
Adolfo Gómez García
f4e953c9c9 Fixed type checkings and detection of client launched when machine not ready 2021-07-20 13:32:28 +02:00
Adolfo Gómez García
f14f36b0d0 Merge remote-tracking branch 'origin/v3.0' 2021-07-19 13:27:00 +02:00
Adolfo Gómez García
d1e51c0103 Upgrading actor for unmanaged && fixed linux operation 2021-07-19 13:26:36 +02:00
Adolfo Gómez García
6fd307e86e small fixes (typing) 2021-07-19 12:42:26 +02:00
Adolfo Gómez García
51407b54ee Small spelling fixes 2021-07-19 01:16:18 +02:00
Adolfo Gómez García
91f90c8630 Small sample fix 2021-07-18 15:45:03 +02:00
Adolfo Gómez García
ca5b54c8e2 Added hidden dark theme to administration 2021-07-14 13:49:58 +02:00
Adolfo Gómez García
8d74055357 Added "copy" feature to admin tables 2021-07-13 22:50:55 +02:00
Adolfo Gómez García
8e81d51a43 Fixed Admin tunnel tokens 2021-07-13 15:11:38 +02:00
Adolfo Gómez García
5ff6cdaf69 Fixed tunnel token headers && tunnel proxy typo 2021-07-13 15:00:00 +02:00
Adolfo Gómez García
13cbfe26c7 Fixes (Basically formating & type checking fixes 2021-07-13 13:36:42 +02:00
Adolfo Gómez García
d497235eeb * Added config parameter for "check removal processes hanged" and removed six from RDP client scripts (and regenerated signatures) 2021-07-13 11:53:22 +02:00
Adolfo Gómez García
7d8bcf2168 Fix small admin issue 2021-07-12 16:39:45 +02:00
Adolfo Gómez García
5706f9d681 Fixed drop down menus on mouse over 2021-07-12 15:12:11 +02:00
Adolfo Gómez García
cd06597918 Formatting fixes 2021-07-12 12:58:45 +02:00
Adolfo Gómez García
49ce5622d6 Correctly added Tokens table permissions type 2021-07-12 12:58:26 +02:00
Adolfo Gómez García
de5031febf Fixed memory cache cleanup 2021-07-12 12:57:48 +02:00
Adolfo Gómez García
b29baf2a29 Small fis on service pool 2021-07-10 21:16:33 +02:00
Adolfo Gómez García
aaa909fff0 Added tunnel info to normalize return values & log values 2021-07-10 13:19:45 +02:00
Adolfo Gómez García
99ee0b00fc Added actor token to admin 2021-07-09 13:13:31 +02:00
Adolfo Gómez García
f2643df05f added typos to cryptography 2021-07-08 22:31:25 +02:00
Adolfo Gómez García
2520cce429 Fixed error on status check for "respawneable" services 2021-07-08 17:47:12 +02:00
Adolfo Gómez García
962015c355 Added types to crypto 2021-07-08 17:46:46 +02:00
Adolfo Gómez García
582ba01014 Added minimun number to show "filter" on service list 2021-07-08 14:42:58 +02:00
Adolfo Gómez García
eec8588628 Updated translations 2021-07-08 14:31:44 +02:00
Adolfo Gómez García
37f59e952d Added translated filter string 2021-07-08 14:18:15 +02:00
Adolfo Gómez García
46bab75a92 Added crpytomanager typing 2021-07-08 14:17:59 +02:00
Adolfo Gómez García
8f7421ef9d Updated translations 2021-07-08 13:00:22 +02:00
Adolfo Gómez García
a7584f9e8e Fixed admin 2021-07-08 12:57:36 +02:00
Adolfo Gómez García
fad735bb87 Added ticket compat with 3.0 2021-07-08 12:22:36 +02:00
Adolfo Gómez García
5ba704ac8a Fixed Version number for actor 2021-07-08 10:40:56 +02:00
Adolfo Gómez García
3c5ef5817f Added tooo long machines on removing state as hanged 2021-07-06 14:46:21 +02:00
Adolfo Gómez García
de0db84a5d Added tooo long machines on removing state as hanged 2021-07-06 14:45:01 +02:00
Adolfo Gómez García
548b6e813d Fixed Proxmox concurrencly on vmid assignation problem 2021-07-06 12:39:22 +02:00
Adolfo Gómez García
31b513a7ef Type checking updates 2021-07-06 11:33:04 +02:00
Adolfo Gómez García
fa7ce3de0b Added more info to terminated connection on UDS tunnel 2021-07-05 18:12:46 +02:00
Adolfo Gómez García
3a7e7b8dfc Fixed Client on non standard ports 2021-07-05 18:03:22 +02:00
Adolfo Gómez García
c9488329b9 Fixed Client on non standard ports 2021-07-05 17:54:02 +02:00
Adolfo Gómez García
55c4574021 Added redirect to login on session timeout 2021-07-05 13:48:56 +02:00
Adolfo Gómez García
59179584f2 Fixed tunnel redirect 2021-07-05 10:46:43 +02:00
Adolfo Gómez García
92de3b01dd Removed "plugin download" event, not used 2021-07-04 16:50:42 +02:00
Adolfo Gómez García
c62d62dd65 commented the events generated and logged by UDS 2021-07-04 15:17:51 +02:00
Adolfo Gómez García
e02318e665 Enhacing tunnel data logging info 2021-07-04 13:25:42 +02:00
Adolfo Gómez García
612ae63cf2 Added events to HTML5 connection also (only conneciton event right now) 2021-07-04 13:04:11 +02:00
Adolfo Gómez García
cb44662134 commenting changes on tunnel 2021-07-03 22:01:42 +02:00
Adolfo Gómez García
a359ff2263 Fixing tunnel & client for mac 2021-07-03 21:48:38 +02:00
Adolfo Gómez García
9ca3a7cdeb Fixed proxy sent stats to UDS 2021-07-03 21:16:17 +02:00
Adolfo Gómez García
1736cae1c1 Fixed image upload 2021-07-03 20:59:23 +02:00
Adolfo Gómez García
727ffe0365 Added a basic bot check to request middleware to forbid bots access 2021-07-03 16:25:07 +02:00
Adolfo Gómez García
b031e0aa3c adding fixes on closing tunnel 2021-07-03 13:02:34 +02:00
Adolfo Gómez García
d7886a1281 adding fixes on closing tunnel 2021-07-03 12:58:26 +02:00
Adolfo Gómez García
09e88b60f5 Updated launcher so, if launcher is closed, all tunnels are also closed 2021-07-03 12:30:46 +02:00
Adolfo Gómez García
6af0617c2a Upgrading client for MAC multi open compatibility 2021-07-02 15:18:35 +02:00
Adolfo Gómez García
1417a66b21 Small fixes on OpenNebula complains 2021-07-02 12:45:16 +02:00
Adolfo Gómez García
9ba4234313 Removed NX 2021-07-02 11:06:23 +02:00
Adolfo Gómez García
e85e4c4e54 Merge remote-tracking branch 'origin/v3.0' 2021-07-02 11:02:11 +02:00
Adolfo Gómez García
4be9e9ea69 Added more info to UDSClient and small typo fixed 2021-07-01 22:04:24 +02:00
Adolfo Gómez García
e38cd73f30 Added user agent 2021-07-01 21:46:00 +02:00
Adolfo Gómez García
43b785eb73 Added more info on ticket error 2021-07-01 21:42:25 +02:00
Adolfo Gómez García
9c4a4ed35c Fixed RDP for MacOS 2021-07-01 21:38:21 +02:00
Adolfo Gómez García
02737c0e8d Fixed guacamole auth url 2021-06-29 16:57:01 +02:00
Adolfo Gómez García
8bbd897cd0 Added ticket check 2021-06-29 16:26:10 +02:00
Adolfo Gómez García
c98933b6ed Fixed guacamole urls && small pam fix 2021-06-29 14:48:04 +02:00
Adolfo Gómez García
6e0292e76e Fixed guacamole new url && added 0000... as admin alias for auths 2021-06-29 13:02:09 +02:00
Adolfo Gómez García
8e6fced2ac Added second-log to login in case invalid username/password is detected 2021-06-29 11:33:58 +02:00
Adolfo Gómez García
c5a02686c4 added "auth_id" as alias for "authId" on login
Changed "uds_auth" to "uds_token"
2021-06-28 19:02:44 +02:00
Adolfo Gómez García
bddb9355c8 Adding tunnelers tokens for increased security 2021-06-28 15:36:52 +02:00
Adolfo Gómez García
25736f61b8 Removed requests "tests" and updated tunnel to use an authId 2021-06-28 13:12:49 +02:00
Adolfo Gómez García
2ee4a7bcaa Several fixes:
* Added tunnel & guacaomle "fake" authid for next security
* Fixed proxy detection & use
2021-06-28 13:05:48 +02:00
Adolfo Gómez García
0da916b57c Updated middleware 2021-06-28 11:02:47 +02:00
Adolfo Gómez García
03012dbaa7 Upgraded to Angular v12. This will be the last release supporting IE11 2021-06-27 22:06:16 +02:00
Adolfo Gómez García
4ae95e1930 Upgraded to Angular 12. Dropped support for admin for IE11 2021-06-27 21:57:15 +02:00
Adolfo Gómez García
906901753e Added "purge" to delete vm from UDS on proxmox 2021-06-25 13:51:24 +02:00
Adolfo Gómez García
109783a430 Fixed texts for client 2021-06-25 13:26:56 +02:00
Adolfo Gómez García
655a6447ba Improved Proxmox query efficiency for machines in a pookl 2021-06-25 13:21:09 +02:00
Adolfo Gómez García
52ac406853 Test migration removal 2021-06-24 12:35:47 +02:00
Adolfo Gómez García
55f9820f37 Fixed migration problem with user & group, when changing from unique_together to constrains on Meta model 2021-06-24 12:27:43 +02:00
Adolfo Gómez García
856d645652 merged 0041 and 0042 migrations 2021-06-24 12:02:41 +02:00
Adolfo Gómez García
fd789581ed Kept by now user and group unique_toguether 2021-06-24 12:02:23 +02:00
Adolfo Gómez García
a67ba2972b Updated translations 2021-06-24 11:25:49 +02:00
Adolfo Gómez García
acd1dd4702 No needed anymore here. It's already on client 2021-06-24 08:21:30 +02:00
Adolfo Gómez García
b914980793 Removing unique_together and index_together for newer Index and UniqueConstrains 2021-06-23 20:58:00 +02:00
Adolfo Gómez García
eab51248cd Fixed service launcher 2021-06-23 20:04:48 +02:00
Adolfo Gómez García
2834120b35 Fixing up status checking 2021-06-23 17:53:13 +02:00
Adolfo Gómez García
83a407d350 Added, for 3.5, check certificate as "no" for backwards compatibility (will be yes by default on 4.0 release) 2021-06-23 16:21:02 +02:00
Adolfo Gómez García
4f45caa2e9 :Merge branch 'master' of github.com:dkmstr/openuds 2021-06-23 16:17:31 +02:00
Adolfo Gómez García
011145e911 Upgraded tunnel.py to last real one 2021-06-23 16:17:23 +02:00
Adolfo Gómez
046f5836f7 Fixed logging 2021-06-23 15:59:15 +02:00
Adolfo Gómez García
4424f2a497 Fixing up client 2021-06-23 15:58:37 +02:00
Adolfo Gómez García
97841d655b more info on subprocesses 2021-06-23 15:14:12 +02:00
Adolfo Gómez García
f20a5a33b0 Fixed debian package dependency && update client tools to add some more debug info 2021-06-23 15:01:34 +02:00
Adolfo Gómez García
d1fb59ab77 Some minor cosmetic changes for UDSClient 2021-06-22 17:12:31 +02:00
Adolfo Gómez García
174d836f45 Merge remote-tracking branch 'origin/v3.0' 2021-06-22 12:11:11 +02:00
Adolfo Gómez García
a070f6878b Removed all 2.7 client due to "portables" clients being available 2021-06-22 11:35:50 +02:00
Adolfo Gómez García
d51b22096e Added check debug logging with a file 2021-06-21 18:00:57 +02:00
Adolfo Gómez García
9e0fbca339 Adding early stage unlinks... 2021-06-21 17:56:16 +02:00
Adolfo Gómez García
3e67ef2f6b Adding early stage unlinks...[F 2021-06-21 17:50:12 +02:00
Adolfo Gómez García
e7fe802b1d fixed bug on wait for tasks 2021-06-21 17:39:35 +02:00
Adolfo Gómez García
6f90a7ce83 fixed bug on wait for tasks 2021-06-21 17:15:51 +02:00
Adolfo Gómez García
25fec929a9 adding some debug to client 2021-06-21 17:11:32 +02:00
Adolfo Gómez García
1abe95c492 adding some debug to client 2021-06-21 17:04:57 +02:00
Adolfo Gómez García
d438fcf298 Updating client to allow wait for subprocesses also 2021-06-21 16:54:34 +02:00
Adolfo Gómez García
539e96d264 Added service initialization exceptio catch-and-retry 2021-06-21 15:28:24 +02:00
Adolfo Gómez García
d30a3a5e4c added tunnel rest url as no redirect url 2021-06-21 15:27:32 +02:00
Adolfo Gómez García
a302541df5 Fixed macos transports to search xfreerdp in path instead of using /usr/local/bin and added homebrew paths to default system ones 2021-06-21 11:21:46 +02:00
Adolfo Gómez García
9cdab65845 Fixed path fixing :) 2021-06-21 11:05:38 +02:00
Adolfo Gómez García
b9c55437ad fixed messages for MAC os 2021-06-21 10:58:37 +02:00
Adolfo Gómez García
0b0c72e65b Added /opt/homebrew/bin as path in mac os x for newer brew installs 2021-06-21 10:53:09 +02:00
Adolfo Gómez García
aef8c637ec added python-3-certifi as dependency for packages (now we do not use QtNetwork anymore for problems in M1) 2021-06-19 17:05:12 +02:00
Adolfo Gómez García
4ed3cbc787 Working on M1 with rosseta, so removed check (that does not recognizes m1 when running app with rosseta) 2021-06-19 17:01:39 +02:00
Adolfo Gómez García
60f69be354 More checks 2021-06-19 15:57:53 +02:00
Adolfo Gómez García
8e815c3316 some more fixes 2021-06-19 15:38:19 +02:00
Adolfo Gómez García
9180d04aaf Fix for show errors 2021-06-19 15:26:05 +02:00
Adolfo Gómez García
6e60a66ae9 Simplifying for M1 2021-06-19 15:16:49 +02:00
Adolfo Gómez García
58cfa779d1 Refactoring UDS Client to allow more possibilities 2021-06-19 14:45:51 +02:00
Adolfo Gómez García
eed4bc5fb7 Updating new UDSClient 2021-06-19 13:29:43 +02:00
Adolfo Gómez García
3ed3f03d25 Changed UDSClient to remove QApp Network access and used urllib instead 2021-06-19 12:41:51 +02:00
Adolfo Gómez García
21f811d995 Added cleanup of intermediary building folders 2021-06-18 10:50:08 +02:00
Adolfo Gómez García
985746139b Fixed Makefile && install script for different platforms 2021-06-17 18:32:22 +02:00
Adolfo Gómez García
9e4a9cc2fd * Added deadline "disabling" on osmanagers, so if we dont want to close sessions for expired users, we can do it 2021-06-17 14:21:40 +02:00
Adolfo Gómez García
c1d5e4b130 src/ 2021-06-17 13:19:47 +02:00
Adolfo Gómez García
21143ab7f2 Merge branch 'master' of github.com:dkmstr/openuds 2021-06-17 12:09:06 +02:00
Adolfo Gómez García
b62dfad922 Added i686 to appimage portable 2021-06-17 12:08:55 +02:00
Adolfo Gómez García
0b3bcbc63d Fixed UDSClientDir to /tmp (BTW, appimage-builder does not work on btrfs with compressed files due to squashfs) 2021-06-17 11:14:05 +02:00
Adolfo Gómez
b4a1e6a903 Merge branch 'master' of https://github.com/dkmstr/openuds 2021-06-16 18:31:13 +02:00
Adolfo Gómez
df9cb4eb6a Updated sysprep checking from info to debug 2021-06-16 18:31:06 +02:00
Adolfo Gómez García
7f4e7e3309 Merge branch 'master' of github.com:dkmstr/openuds 2021-06-16 18:28:17 +02:00
Adolfo Gómez García
741787f95b Fixed building of portables uds clients with freerdp + x2go client 2021-06-16 18:28:10 +02:00
Adolfo Gómez
7b0ad08685 Merge branch 'master' of https://github.com/dkmstr/openuds 2021-06-16 14:34:57 +02:00
Adolfo Gómez
25b663e069 Adding 'windows installations' checks before running uds service 2021-06-16 14:34:52 +02:00
Adolfo Gómez García
1bb258d9dc Fixed WOL for multi manual assigment 2021-06-15 16:22:47 +02:00
Adolfo Gómez García
d5f29bd20f Added ignore certificate for getting server stats on localhost 2021-06-15 13:32:22 +02:00
Adolfo Gómez García
69fe9e0d38 * User preferences is deprecated (to be removed)
* NX is disabled in code (to be removed on 4.0)
* Increeased URL size for "URL" transport to 256 (was 64 only)
2021-06-15 11:49:16 +02:00
Adolfo Gómez García
41c94913f8 added full clients appimage 2021-06-11 12:02:26 +02:00
Adolfo Gómez García
0dce270a9e Created portable udsclient using appimage. Now also for raspberry pi 2021-06-10 17:25:23 +02:00
Adolfo Gómez García
594d431af7 Created portable udsclient using appimage 2021-06-10 17:02:11 +02:00
Adolfo Gómez García
71242eba10 moving appimage creator to linux folder 2021-06-10 16:17:21 +02:00
Adolfo Gómez García
2dded06dc5 Added app image creation recipe for UDSClient + freerdp 2021-06-10 12:15:45 +02:00
Adolfo Gómez García
38490e184e Updated criptography part to be compatible with older releases of crpytography package 2021-06-09 17:47:49 +02:00
Adolfo Gómez García
9e462478fc Removed six dependency for client-py3 and related 2021-06-09 12:39:06 +02:00
Adolfo Gómez García
44d8b2b754 Several upgrades for newer distributions:
* Removed pycrypto dependencies for UDSClient
* added "-platform xcb" for uds executables for Actor & client3
2021-06-09 12:12:31 +02:00
Adolfo Gómez García
5884cde35c a couple of comments 2021-06-08 20:58:55 +02:00
Adolfo Gómez García
3b18597d8e Removed PyCrypto code and translated to cryptography code 2021-06-08 19:08:41 +02:00
Adolfo Gómez García
f6ddc7eef1 Added ID to machine info on service creation 2021-06-08 18:44:52 +02:00
Adolfo Gómez García
ed61fbf7b8 No, if a child dies, UDS Tunnel will regenerate a new process and try to clean the old one 2021-06-08 11:48:53 +02:00
Adolfo Gómez García
fb088ecc02 Updated UDSClient
* Reformated code
* Fixed UDS Rest API Route to /uds/rest/... instead of /rest/... (will not be compatible with 2.x anymore)
2021-06-07 21:10:57 +02:00
Adolfo Gómez García
5396d04555 Merge remote-tracking branch 'origin/v3.0' 2021-06-07 21:02:30 +02:00
Adolfo Gómez García
68b3b50acf Merge branch 'master' of github.com:dkmstr/openuds 2021-06-04 13:25:45 +02:00
Adolfo Gómez García
9d6560a56e fixed version 2021-06-04 12:07:07 +02:00
Adolfo Gómez García
25363269a6 Merge remote-tracking branch 'origin/v3.0' 2021-06-04 11:50:51 +02:00
Adolfo Gómez García
8aca8ead3d Merge remote-tracking branch 'origin/v3.0' 2021-06-03 21:02:36 +02:00
Adolfo Gómez García
f184fa778d Refactorized ldap and added "ignores" to non recognized correct values 2021-06-03 11:43:56 +02:00
Adolfo Gómez García
21f6df36b0 Refactor for all middlewares (now are all on same place..) 2021-06-01 13:17:53 +02:00
Adolfo Gómez García
394ceb9e66 Added radius authenticator for UDS 2021-06-01 12:41:58 +02:00
Adolfo Gómez García
5f8abdfa41 Merge remote-tracking branch 'origin/v3.0' 2021-05-31 11:33:13 +02:00
Adolfo Gómez García
b8af381042 Fixed autocomplete 2021-05-31 11:32:58 +02:00
Adolfo Gómez García
cb92be3c66 Simplifying several "is True" 2021-05-27 13:04:18 +02:00
Adolfo Gómez García
8fc5c759d8 Merge remote-tracking branch 'origin/v3.0' 2021-05-27 10:58:18 +02:00
Adolfo Gómez García
6c936a7dfa Fixed report definition, so filename can be changed (not an class variable anymore) and added sample xlsx report onlist of users (only sample, commmented out) 2021-05-25 19:03:55 +02:00
Adolfo Gómez García
0cc40198b2 Merge remote-tracking branch 'origin/v3.0' 2021-05-25 10:41:25 +02:00
Adolfo Gómez García
9789a2f868 Updated admin for pool charts 2021-05-21 14:42:11 +02:00
Adolfo Gómez García
e8733e74d1 Added graphs to servicePool 2021-05-21 14:17:49 +02:00
Adolfo Gómez García
c6d281580b Added soft shutdown first for ProxMox 2021-05-21 12:18:55 +02:00
Adolfo Gómez García
1050ada43b Improved internaldb password security (sha3_256) and added extra security to uds cookie 2021-05-21 11:38:41 +02:00
Adolfo Gómez García
f39bc9c5ba Added stats collector a global value for all stats 2021-05-19 12:22:24 +02:00
Adolfo Gómez García
c987915c41 Added stats collector a global value for all stats 2021-05-19 12:20:35 +02:00
Adolfo Gómez García
12b8354a8e Merge remote-tracking branch 'origin/v3.0' 2021-05-19 12:20:11 +02:00
Adolfo Gómez García
e7d1df5ba3 added "global" stats counter to optimize graphs on dashboard 2021-05-19 11:45:40 +02:00
Adolfo Gómez García
e87727b48f fixed counters types not being added for new counter type 2021-05-17 12:59:23 +02:00
Adolfo Gómez García
13ec1877de added number of services in cache for stats 2021-05-17 12:41:35 +02:00
Adolfo Gómez García
1b4060a727 Fixed pylance complains about runtime created variables 2021-05-17 12:13:06 +02:00
Adolfo Gómez García
d8e713ad51 Imported dns.reversename (not imported before) for IP Authenticator reverse resolution 2021-05-17 11:59:54 +02:00
Adolfo Gómez García
cdca39779b Fixed Complains about curio "runtime" types 2021-05-17 11:59:24 +02:00
Adolfo Gómez García
265d4f5103 added admin part for charts 2021-05-12 17:03:28 +02:00
Adolfo Gómez García
b85a702437 Added new index to stats_c and readded the graphs from uds 2.2 2021-05-12 14:40:58 +02:00
Adolfo Gómez García
e2d7fb0790 Reformated SimpleLDAP && fixed mypy complains about runtime variables
Added max session length for user and administrator, without the needing of editing the settings.py
2021-05-11 12:48:36 +02:00
Adolfo Gómez García
a573d2d55b added (at last), the check of invalid IP/hostname values on RDS servers or Phisical Machines 2021-05-10 10:47:00 +02:00
Adolfo Gómez García
de50fef63c Merge remote-tracking branch 'origin/v3.0' 2021-05-07 12:36:20 +02:00
Adolfo Gómez García
0133ddc2b5 Merge remote-tracking branch 'origin/v3.0' 2021-05-06 07:55:00 +02:00
Adolfo Gómez García
cddfd735b2 Merge remote-tracking branch 'origin/v3.0' 2021-05-04 13:07:10 +02:00
Adolfo Gómez García
3f6d12c89f Adding osDetector to UDSClient 2021-05-04 13:05:53 +02:00
Adolfo Gómez García
98293bba75 Merge remote-tracking branch 'origin/v3.0' 2021-05-04 13:05:31 +02:00
Adolfo Gómez García
07738e3dc2 Added support for detecting if UDS Client is launched correctly 2021-04-30 11:13:52 +02:00
Adolfo Gómez García
2b5543905a added "accesedByClient" property so we can check, from web, if local plugin is installed.... 2021-04-29 13:01:07 +02:00
Adolfo Gómez García
87c2ea8add added status checker to web API 2021-04-29 12:09:03 +02:00
Adolfo Gómez García
2a2a2b2ad0 small type checking fix & expresion fix 2021-04-28 10:47:35 +02:00
Adolfo Gómez García
47ef12ef6a Removed Crypto library remmanents. Old 2.2 RSA keys are no longer supported on 3.5 2021-04-28 10:42:45 +02:00
Adolfo Gómez García
451b8f6fb9 Fixes for mypy complains 2021-04-27 11:46:10 +02:00
Adolfo Gómez García
bd2b0cd171 Fixing mypy complains 2021-04-27 11:32:04 +02:00
Adolfo Gómez García
18a8c81af6 Merge remote-tracking branch 'origin/v3.0' 2021-04-26 11:56:20 +02:00
Adolfo Gómez García
09c65b2598 added proxy support for OpenStack & OpenStack legacy 2021-04-23 11:30:45 +02:00
Adolfo Gómez García
6e438bf4cb Added squashed migration from 26 to 38 2021-04-22 17:56:50 +02:00
Adolfo Gómez García
7502fe3bcc Removed squashed migrations 2021-04-22 17:43:29 +02:00
Adolfo Gómez García
e9a719a2eb Added metapools capacity of show grouped pools transports 2021-04-22 14:44:48 +02:00
Adolfo Gómez García
ce73d4e29f Updated admin fix from 3.0 2021-04-22 11:58:52 +02:00
Adolfo Gómez García
ffeaf9e22c Merge remote-tracking branch 'origin/v3.0' 2021-04-22 11:56:16 +02:00
Adolfo Gómez García
1e184a3a34 small fix on graphs (cosmetic) 2021-04-21 23:56:52 +02:00
Adolfo Gómez García
74d4349266 fixed signature of osManager publication method 2021-04-20 14:39:57 +02:00
Adolfo Gómez García
26c9f0edc8 Fixed scheduler next execution (typo make it wait DAYS instead of SECONDS!!! 2021-04-20 14:27:53 +02:00
Adolfo Gómez García
797a5df4a9 Fixed admin imgchoice 2021-04-20 13:30:13 +02:00
Adolfo Gómez García
8fbdda7b56 Merge remote-tracking branch 'origin/v3.0' 2021-04-19 12:59:44 +02:00
Adolfo Gómez García
9f04bdab05 Added custom parameters for freerdp mac clients.
distinct from linux custom parameters.
2021-04-16 11:21:21 +02:00
Adolfo Gómez García
5597af7d85 merged vnc from 3.0 2021-04-13 12:50:03 +02:00
Adolfo Gómez García
697c3e1c52 Merge remote-tracking branch 'origin/v3.0' 2021-04-13 12:47:27 +02:00
Adolfo Gómez García
ae7f867482 fixed default value from html5rdp to any instead of rdp and fixed onw parameter 2021-04-13 11:45:43 +02:00
Adolfo Gómez García
f595219405 added fix for vscode complaining about alias && merged 2021-04-08 17:47:03 +02:00
Adolfo Gómez García
d66e59bd50 small spelling typo fix 2021-04-08 10:23:54 +02:00
Adolfo Gómez García
cc12b7d5f6 Added "backport of new tunnel" to old python 2.7 client 2021-04-07 16:48:24 +02:00
Adolfo Gómez García
d67a9d6ddc fixed reference to Dani Torregrosa (sorry for the mispelling :) ) 2021-04-07 12:32:25 +02:00
Adolfo Gómez García
5ff3c58149 added Dani sugested changes for MSRDP of Microsoft on MacOsX 2021-04-07 10:36:57 +02:00
Adolfo Gómez García
9340e3c3c1 added "backup host" to xen server in case of connection failure to main server 2021-04-06 12:12:57 +02:00
Adolfo Gómez García
4357ef3be8 Merge remote-tracking branch 'origin/v3.0' 2021-04-05 13:21:46 +02:00
Adolfo Gómez García
a3905c0c6c added time to enter credentials before closing new connections though tunnel 2021-04-05 11:24:30 +02:00
Adolfo Gómez García
03fc488f33 Fixed provider of Physical machines MANDATORY flag for advanced config 2021-03-29 12:52:58 +02:00
Adolfo Gómez García
2aee4e9417 Added log if could not resolve ip on PhisicalMachines multi 2021-03-25 12:37:43 +01:00
Adolfo Gómez García
b8494f51ac More fixes for WOL on Phisical Machines 2021-03-24 17:33:39 +01:00
Adolfo Gómez García
93a12c180e More fixes for WOL on Phisical Machines 2021-03-24 17:18:34 +01:00
Adolfo Gómez García
26aa9f6db7 Enhaced "wolURL" check 2021-03-24 12:13:26 +01:00
Adolfo Gómez García
3f881b3e17 Added support for name resolutions on service_multi && fixed max page limit from 50 to 100 2021-03-24 11:54:03 +01:00
Adolfo Gómez García
0a0b4cb740 Merge remote-tracking branch 'origin/v3.0' 2021-03-23 16:42:38 +01:00
Adolfo Gómez García
5df8f640d8 Added config for WOL on UDS 2021-03-23 16:12:51 +01:00
Adolfo Gómez García
8c68da806a Added config for WOL on UDS 2021-03-23 15:38:02 +01:00
Adolfo Gómez García
b9ba304493 Added "ignore port check" if WOLAPP is configured 2021-03-23 12:25:04 +01:00
Adolfo Gómez García
52d3ffeac3 added config to actor block attacks 2021-03-12 15:10:39 +01:00
Adolfo Gómez García
868ff2817a Merge remote-tracking branch 'origin/v3.0' 2021-03-12 15:07:50 +01:00
Adolfo Gómez García
51916e0949 Merge remote-tracking branch 'origin/v3.0' 2021-03-12 11:42:02 +01:00
Adolfo Gómez García
e517281c6a Merge remote-tracking branch 'origin/v3.0' 2021-03-11 14:27:57 +01:00
Adolfo Gómez García
c90f9c40fd Merge remote-tracking branch 'origin/v3.0' 2021-03-11 14:15:01 +01:00
Adolfo Gómez García
c6213ff37c Merge remote-tracking branch 'origin/v3.0' 2021-03-10 18:13:42 +01:00
Adolfo Gómez
3908c875d3
Merge pull request #65 from glyptodon/easy-compat
Ensure guacamole-auth-uds is compatible with third-party branding extensions.
2021-03-05 23:42:55 +01:00
Michael Jumper
c28c6c7b98 Complete removal of code partially removed by commit 073ce3d. 2021-03-05 12:13:21 -08:00
Michael Jumper
fe3fd6c35b Remove UDS icon (conflicts with any third-party branding). 2021-03-05 12:11:53 -08:00
Adolfo Gómez García
a035633b58 Merge remote-tracking branch 'origin/v3.0' 2021-03-04 17:05:19 +01:00
Adolfo Gómez García
688acb0631 Added extra security control to guacamole tickets 2021-03-04 12:13:38 +01:00
Adolfo Gómez García
0bc1f72dc8 Merge remote-tracking branch 'origin/v3.0' 2021-03-03 12:31:45 +01:00
Adolfo Gómez García
5d52061041 Merge remote-tracking branch 'origin/v3.0' 2021-03-03 12:27:39 +01:00
Adolfo Gómez García
190079fddc Merge remote-tracking branch 'origin/v3.0' 2021-03-01 13:12:59 +01:00
Adolfo Gómez García
9f44e7fd25 Merge remote-tracking branch 'origin/v3.0' 2021-03-01 13:08:47 +01:00
Adolfo Gómez García
ff685119ae Merge remote-tracking branch 'origin/v3.0' 2021-03-01 13:07:33 +01:00
Adolfo Gómez García
388cb2644b fixing up service_multi 2021-03-01 13:07:31 +01:00
Adolfo Gómez García
bda4057173 Merge remote-tracking branch 'origin/v3.0' 2021-03-01 13:01:06 +01:00
Adolfo Gómez García
7aec9a116e added "post-login-as-sysadmin" possibility of run windows script 2021-03-01 12:13:28 +01:00
Adolfo Gómez García
f57fea4699 Merge remote-tracking branch 'origin/v3.0' 2021-03-01 11:47:02 +01:00
Adolfo Gómez García
d52bc68015 Merge remote-tracking branch 'origin/v3.0' 2021-03-01 11:42:14 +01:00
Adolfo Gómez García
8ab1342775 merged chango of timeouts on 3.0 2021-03-01 11:14:02 +01:00
Adolfo Gómez García
f602d641a0 Merge remote-tracking branch 'origin/v3.0' 2021-03-01 10:42:34 +01:00
Adolfo Gómez García
3e07cf53e4 added remove control characters of an unicode string 2021-02-25 13:45:37 +01:00
Adolfo Gómez García
2968bc7d41 Merge remote-tracking branch 'origin/v3.0' 2021-02-25 10:39:53 +01:00
Adolfo Gómez García
6a209c0836 Added new resolutions for RDP display 2021-02-25 10:39:12 +01:00
Adolfo Gómez García
9568a9b180 Merge remote-tracking branch 'origin/v3.0' 2021-02-24 15:18:04 +01:00
Adolfo Gómez García
91fcbe7336 Fixed "image" parameter for wake remote machine 2021-02-23 14:19:47 +01:00
Adolfo Gómez García
2fd5b40809 Fixed Phisical machines issues & updated macos screen calc algorithn 2021-02-22 14:25:27 +01:00
Adolfo Gómez García
4e161b15f4 Merge remote-tracking branch 'origin/v3.0' 2021-02-17 16:02:29 +01:00
Adolfo Gómez García
328d35a289 Merged 3.0 HTML5 RDP changes 2021-02-17 15:40:43 +01:00
Adolfo Gómez García
af52727862 Merge remote-tracking branch 'origin/v3.0' 2021-02-17 15:35:36 +01:00
Adolfo Gómez García
672897f828 fixed test redirect && fixed frequency 2021-02-16 13:17:10 +01:00
Adolfo Gómez García
073ce3df12 removed old unused code 2021-02-16 10:20:28 +01:00
Adolfo Gómez García
09125bb1fa Merge remote-tracking branch 'origin/v3.0' 2021-02-15 12:14:39 +01:00
Adolfo Gómez García
f3e7e21149 Added log in case of file access problems 2021-02-15 11:38:59 +01:00
Adolfo Gómez García
348258daf2 Merge remote-tracking branch 'origin/v3.0' 2021-02-14 22:11:27 +01:00
Adolfo Gómez García
49a6e01477 Merge remote-tracking branch 'origin/v3.0' 2021-02-11 09:43:15 +01:00
Adolfo Gómez
9f2354191c
Merge pull request #64 from glyptodon/simplify-config
Replace complex "udsfile" logic with simplified "uds-base-url" property.
2021-02-11 09:34:50 +01:00
Adolfo Gómez
6804982b0b
Merge pull request #63 from glyptodon/revalidate-data
Re-validate UDS data for each connection attempt.
2021-02-11 09:33:39 +01:00
Michael Jumper
857f8602b8 Replace complex "udsfile" logic with simplified "uds-base-url" property. 2021-02-10 16:58:03 -08:00
Michael Jumper
584dee9fcd Re-validate UDS data for each connection attempt. 2021-02-10 16:45:01 -08:00
Adolfo Gómez García
e7bf7b0258 added "hidden" mac address treatment to phisical machines 2021-02-10 14:43:36 +01:00
Adolfo Gómez García
46d056de5d Merge remote-tracking branch 'origin/v3.0' 2021-02-09 12:39:13 +01:00
Adolfo Gómez García
92e13c48de Added support for linux environmenv var expansion on parameters for freerdp 2021-02-08 12:53:42 +01:00
Adolfo Gómez García
d93e5dc566 Merge remote-tracking branch 'origin/v3.0' 2021-02-05 14:32:10 +01:00
Adolfo Gómez García
0b8a9444d1 upgraded user gui 2021-02-05 10:59:23 +01:00
Adolfo Gómez García
cea271a2ce Added typing to scheduler 2021-02-01 12:53:34 +01:00
Adolfo Gómez García
d2d190e8a4 Retry scheduler cleanup in case of locked db 2021-01-29 11:54:48 +01:00
Adolfo Gómez García
5b8ff497fa Improved sql for scheduler main loop 2021-01-29 11:53:38 +01:00
Adolfo Gómez García
ae6d36b86a manually imported changes to v3.0 on spool names variables 2021-01-28 14:06:03 +01:00
Adolfo Gómez García
600f50f203 Merge remote-tracking branch 'origin/v3.0' 2021-01-28 14:00:31 +01:00
Adolfo Gómez García
caf1d5d825 Adding support for custom connection userServices data for RDP 2021-01-28 13:09:43 +01:00
Adolfo Gómez García
99d3393a33 Merge remote-tracking branch 'origin/v3.0' 2021-01-26 16:07:49 +01:00
Adolfo Gómez García
1d06bd02c0 fixing tunnel on privileges dropping 2021-01-25 15:19:49 +01:00
Adolfo Gómez García
41991590ca added support for running as root and drop to an user later 2021-01-25 14:58:50 +01:00
Adolfo Gómez García
4313368f78 small fixes for tunnel 2021-01-25 12:47:00 +01:00
Adolfo Gómez García
50660d92e5 fixed tunnel to allow sending to broker connection stats on termination 2021-01-25 11:12:10 +01:00
Adolfo Gómez García
c796f5aaac fixed sample tunnel configuration 2021-01-25 08:42:50 +01:00
Adolfo Gómez García
9e88ff5daa * Added "no compression" to ssl options for tunnel
* Updated headers & reformated rest.py
2021-01-23 21:50:40 +01:00
Adolfo Gómez García
cb5a6f2430 Fixed osDetector name 2021-01-22 09:01:52 +01:00
Adolfo Gómez
0f87c022f3 Headers & comments fix 2021-01-22 09:00:59 +01:00
Adolfo Gómez García
69f1c88c3d Fixed headers 2021-01-22 07:28:17 +01:00
Adolfo Gómez García
6fc6fa0fe1 Remove pycrypto and only using cryptopraphy 2021-01-22 07:17:18 +01:00
Adolfo Gómez García
f634d4ef1a Added .env files for vscode editing 2021-01-22 07:16:53 +01:00
Adolfo Gómez García
f933181369 Merge remote-tracking branch 'origin/v3.0' 2021-01-21 11:00:45 +01:00
Adolfo Gómez
f0b6726e19 Merge branch 'master' of https://github.com/dkmstr/openuds 2021-01-20 12:42:38 +01:00
Adolfo Gómez
8424c14052 added certifi certificates to CA list for Qt on UDS Client 2021-01-20 12:42:30 +01:00
Adolfo Gómez García
97f709bf52 fixed opengnsys connector callbacks. 2021-01-20 09:00:25 +01:00
Adolfo Gómez García
c26c8d9df9 Removed OLD template (code cleanup) 2021-01-20 08:48:21 +01:00
Adolfo Gómez García
9f81d0a066 Upgraded angular version of interfaces to v11 2021-01-19 09:13:07 +01:00
Adolfo Gómez García
bb626889fb Working on next OpenGnsys service provider release 2021-01-19 08:47:05 +01:00
Adolfo Gómez García
d8fb0deef2 Working on next OpenGnsys service provider release 2021-01-19 08:46:00 +01:00
Adolfo Gómez García
743773e256 Working on new tunnel, translating client mods to new tunnel server 2021-01-18 11:24:34 +01:00
Adolfo Gómez García
4adc058e1a Updating client logic to new gen tunnel server 2021-01-18 07:51:47 +01:00
Adolfo Gómez García
f364b283e6 added tunnel check 2021-01-18 06:45:50 +01:00
Adolfo Gómez García
7e4975be99 cleanup new tunnel 2021-01-18 06:04:59 +01:00
Adolfo Gómez García
a2df121e45 fixed a couple readmes 2021-01-18 05:51:34 +01:00
Adolfo Gómez García
f402dadb0a Advanced A LOT on new tunnel server & client. First test passed 2021-01-15 11:31:39 +01:00
Adolfo Gómez García
865601b3c8 Merge remote-tracking branch 'origin/v3.0' 2021-01-14 17:43:07 +01:00
Adolfo Gómez García
0da51dda92 fixed log of tunnel 2021-01-14 10:05:58 +01:00
Adolfo Gómez García
7c9c510ca0 minor updates to texts 2021-01-14 08:23:34 +01:00
Adolfo Gómez García
7ae9df21a5 added new tunnel server client 2021-01-14 08:17:49 +01:00
Adolfo Gómez García
2fd1dc5fc9 Advancing on forwarder 2021-01-14 08:11:02 +01:00
Adolfo Gómez García
a4986d3b4d Advancing on forwarder 2021-01-14 08:10:46 +01:00
Adolfo Gómez García
40abfb6014 Advancing on forwarder 2021-01-14 08:10:28 +01:00
Adolfo Gómez García
d6a8639b18 new tunnel server ready for testing phase 2021-01-14 06:01:06 +01:00
Adolfo Gómez García
971e5984d9 Advancing on new tunneler 2021-01-13 10:04:26 +01:00
Adolfo Gómez García
e486d6708d added local uds_tunnel work to openuds 2021-01-13 04:42:59 +01:00
Adolfo Gómez
f0bd3782d7 Merge branch 'master' of https://github.com/dkmstr/openuds 2021-01-11 03:04:38 +01:00
Adolfo Gómez García
7e9dde66ac Merge remote-tracking branch 'origin/v3.0' 2021-01-11 03:02:38 +01:00
Adolfo Gómez
fa05d9425e Fixed for python 3 on Windows 2021-01-11 02:50:30 +01:00
Adolfo Gómez
75221a4842 fixed python3 version for windows 2021-01-11 01:33:32 +01:00
Adolfo Gómez García
4cc11d783a Merge remote-tracking branch 'origin/v3.0' 2020-12-18 11:10:35 +01:00
Adolfo Gómez García
e5a38a65ed updated actor toke user on re-registration 2020-12-17 14:04:19 +01:00
Adolfo Gómez García
dcdea31061 fixing minor possible issues with staff members && reformating code, adapting to type checking, etc... 2020-12-17 13:56:15 +01:00
Adolfo Gómez García
6b3d222a12 Merge remote-tracking branch 'origin/v3.0' 2020-12-15 16:42:02 +01:00
Adolfo Gómez García
8719896f62 Merge remote-tracking branch 'origin/v3.0' 2020-12-15 16:41:54 +01:00
Adolfo Gómez García
57d8b01757 Fixed rdp_file url generation for mac audio 2020-12-04 13:37:07 +01:00
Adolfo Gómez García
66fb59a13b fixed tests for service on 3.5 actor 2020-12-01 11:36:01 +01:00
Adolfo Gómez García
78372e593a refactorization 2020-11-27 15:56:17 +01:00
Adolfo Gómez García
1d7c57eb2f Merge remote-tracking branch 'origin/v3.0' 2020-11-27 14:33:11 +01:00
Adolfo Gómez García
501565c088 Reformated & minor updates for workers 2020-11-27 11:12:06 +01:00
Adolfo Gómez García
f2d55d6141 Merge remote-tracking branch 'origin/v3.0' 2020-11-26 18:43:03 +01:00
Adolfo Gómez García
e9a4da5acc Merge remote-tracking branch 'origin/v3.0' 2020-11-26 11:52:21 +01:00
Adolfo Gómez García
522a5ebfb7 Merge remote-tracking branch 'origin/v3.0' 2020-11-25 18:40:11 +01:00
Adolfo Gómez García
6868e471c5 Merge remote-tracking branch 'origin/v3.0' 2020-11-20 14:40:18 +01:00
Adolfo Gómez García
9e4922ba79 adde future recording of guacamole 2020-11-19 12:14:52 +01:00
Adolfo Gómez García
7a377b0065 adapting UDS to new tunnel 2020-11-18 12:21:58 +01:00
Adolfo Gómez García
b830b0ee0a Merge remote-tracking branch 'origin/v3.0' 2020-11-17 17:09:15 +01:00
Adolfo Gómez
2251618c69
Merge pull request #58 from glyptodon/migrate-extension
Convert "guacamole-tunnel" web application into an equivalent Apache Guacamole extension.
2020-11-17 00:28:12 +01:00
Michael Jumper
a6876de0b1 Convert "guacamole-tunnel" web application into an equivalent Apache Guacamole extension. 2020-11-16 14:18:41 -08:00
Adolfo Gómez García
58a70e368e * Small RDP fix (typo)
* Added secure ticket type
* Reformated sevice view
2020-11-16 19:45:54 +01:00
Adolfo Gómez García
50f3b79ee3 Merge remote-tracking branch 'origin/v3.0' 2020-11-16 14:45:24 +01:00
Adolfo Gómez García
4183069cec Fixed help for mac ox on freerdp 2020-11-16 13:27:20 +01:00
Adolfo Gómez García
905b1e7589 refactoring code 2020-11-16 13:10:02 +01:00
Adolfo Gómez García
024bb5e748 Updated default wait-time && fixed mac access 2020-11-16 13:09:33 +01:00
Adolfo Gómez García
e4345dfefa fixed tunnel scripts for macosx 2020-11-15 22:48:17 +01:00
Adolfo Gómez García
6c54f8e75a Fixed cache bug intruduced on encoders module removal
Improbed type checking for REST (ongoing)
Optimized queries (using prefetch) for service pools listing
2020-11-13 11:23:22 +01:00
Adolfo Gómez García
45ca92b77e Removed encoders modules 2020-11-13 09:35:18 +01:00
Adolfo Gómez García
06b0f1396f reformated storage source 2020-11-13 08:43:55 +01:00
Adolfo Gómez García
c698300096 Merge remote-tracking branch 'origin/v3.0' 2020-11-13 08:30:45 +01:00
Adolfo Gómez García
482cc4b2ae Removing "encoders" uds module 2020-11-13 08:30:27 +01:00
Adolfo Gómez García
2f67eacfb6 * Removing "encoders" module (nonsense and sometimes confusing. Helped on python 2.7, but now... :)
* Revised reports to improve type checking
2020-11-12 13:55:09 +01:00
Adolfo Gómez García
b8e7dc07c3 Refactoring models (without DB modification) to better type checking 2020-11-12 12:13:35 +01:00
Adolfo Gómez García
52f524eb61 * Fixed comms to not "annoy" with warnings
* Added generateUuid to allow pass in an object
* renamed "is_meta" to more convenient "is_owned_by_meta
* Fixed 2.x actor rest api small bug (not used that part right now anyway, but for future)
2020-11-12 11:48:42 +01:00
Adolfo Gómez García
637519a162 Upgrading models for pylance typechecking 2020-11-12 08:35:45 +01:00
Adolfo Gómez García
65b47686db updating type checking 2020-11-11 14:36:31 +01:00
Adolfo Gómez García
1ab534c3aa * Adding more type checking (pylance type checking works fin with theese new "checks")
* Removed redundant fields not used
2020-11-11 13:32:02 +01:00
Adolfo Gómez García
8cd5437429 removing unused ManyToManyField (it has already a relation class) 2020-11-11 11:24:13 +01:00
Adolfo Gómez García
a475d45b7b * Added better type checking on Handler
* Fixed exception of ticket store exception
* Added initial nitification for unamanged
2020-11-11 09:03:02 +01:00
Adolfo Gómez García
4f3792ced5 added typing to calendar actions pairs 2020-11-11 09:01:43 +01:00
Adolfo Gómez García
3e061275b4 Added some more typing checks 2020-11-11 09:00:34 +01:00
Adolfo Gómez García
22415b98cd Commented out fix for passwords. Do not apply to 3.x mechanics 2020-11-11 08:48:36 +01:00
Adolfo Gómez
302b9a85d5
Merge pull request #57 from danitorregrosa/escape-conflicting-chars-rdp-credential-redirection
fix for proper escaping of conflicting chars in rdp credential redire…
2020-11-10 14:20:59 +01:00
danitorregrosa
08038b5b90 fix for proper escaping of conflicting chars in rdp credential redirection 2020-11-10 14:05:56 +01:00
Adolfo Gómez García
6d9a6baa2a Merge remote-tracking branch 'origin/v3.0' 2020-11-10 09:20:16 +01:00
Adolfo Gómez
fb69866f89 Merge remote-tracking branch 'origin/v3.0' 2020-11-09 09:19:31 +01:00
Adolfo Gómez García
74ad50d7d8 working on allowing services to detect user login on unmanaged services 2020-11-08 19:17:29 +01:00
Adolfo Gómez García
00dc4c5a7b Changed default encrypt to AES 2020-11-07 08:20:08 +01:00
Adolfo Gómez García
a495f36c43 .gitignore update 2020-11-07 08:19:32 +01:00
Adolfo Gómez García
f69a9dbc82 Merge remote-tracking branch 'origin/v3.0' 2020-11-06 01:08:09 +01:00
Adolfo Gómez García
65879f4bd3 fixed ignorables for mac client 2020-11-03 07:29:18 +01:00
Adolfo Gómez García
a094e1ebee fixed log name being bytes instead of string 2020-11-03 05:41:32 +01:00
admin
c35dc90264 added ignorable 2020-11-03 04:59:51 +01:00
Adolfo Gómez García
1be48b99d4 making some tests with nuitka 2020-11-02 08:45:20 +01:00
Adolfo Gómez García
cab09aea9c Fixing up mac os RDP transport support 2020-10-31 07:21:01 +01:00
Adolfo Gómez García
da23222f0f Working on supporting better clients on Mac 2020-10-30 09:44:55 +01:00
Adolfo Gómez García
5d604bb629 Merge remote-tracking branch 'origin/v3.0' 2020-10-29 09:36:45 +01:00
Adolfo Gómez García
13de581b80 Improbed session clear on user logout 2020-10-29 07:49:43 +01:00
Adolfo Gómez García
76f4df5aa1 Added admin access API restriction by IP 2020-10-29 06:23:09 +01:00
Adolfo Gómez García
8634ce50c6 Fixed so, if an invalid IP is configured on trusted source, it gets logged and ignored 2020-10-29 06:22:52 +01:00
Adolfo Gómez García
758f409372 Renamed module "openStack" to more convenient "openstack", and a couple of minor fixes related to it 2020-10-28 06:55:15 +01:00
Adolfo Gómez García
edd6714cd0 removed version dependency from requirements for cryptography 2020-10-28 01:37:42 +01:00
Adolfo Gómez
a7f9880816
Merge pull request #56 from dkmstr/dependabot/pip/server/cryptography-3.2
Bump cryptography from 2.9.2 to 3.2 in /server
2020-10-28 00:49:29 +01:00
dependabot[bot]
d9bbbb35eb
Bump cryptography from 2.9.2 to 3.2 in /server
Bumps [cryptography](https://github.com/pyca/cryptography) from 2.9.2 to 3.2.
- [Release notes](https://github.com/pyca/cryptography/releases)
- [Changelog](https://github.com/pyca/cryptography/blob/master/CHANGELOG.rst)
- [Commits](https://github.com/pyca/cryptography/compare/2.9.2...3.2)

Signed-off-by: dependabot[bot] <support@github.com>
2020-10-27 22:53:01 +00:00
Adolfo Gómez García
5bf8e74018 Merge remote-tracking branch 'origin/v3.0' 2020-10-27 11:10:01 +01:00
Adolfo Gómez García
f5b59889fc Merge remote-tracking branch 'origin/v3.0' 2020-10-27 07:57:48 +01:00
Adolfo Gómez García
6ced042153 upgraded debian build for actor and client 2020-10-23 08:34:10 +02:00
Adolfo Gómez García
e9f74d9ccc upgraded debian build for actor and client 2020-10-23 08:31:24 +02:00
Adolfo Gómez García
9815e21524 upgraded debian build 2020-10-23 08:28:02 +02:00
Adolfo Gómez García
666ae4e1d3 Added experimental support for L2 cache to Proxmox 2020-10-23 02:47:51 +02:00
Adolfo Gómez García
3e8a3efb75 Added L2 cache support for proxmox 2020-10-23 02:14:11 +02:00
Adolfo Gómez García
4094818ccc Merge remote-tracking branch 'origin/v3.0' 2020-10-22 11:14:04 +02:00
Adolfo Gómez García
43acedf7f6 small storage fix 2020-10-21 08:24:24 +02:00
Adolfo Gómez García
37f06617b8 Added dict-like storage management 2020-10-21 08:03:18 +02:00
Adolfo Gómez García
dd39bb4e64 Merge remote-tracking branch 'origin/v3.0' 2020-10-20 11:55:40 +02:00
Adolfo Gómez García
bafd3bc6b3 Added support for configurable admin pagesizes 2020-10-20 11:11:52 +02:00
Adolfo Gómez García
48e0577e9f Merge remote-tracking branch 'origin/v3.0' 2020-10-20 11:10:20 +02:00
Adolfo Gómez García
cb05113d88 Adding support for configurable page size of lists on admin 2020-10-20 09:19:10 +02:00
Adolfo Gómez García
afc4fd39ef Merge remote-tracking branch 'origin/v3.0' 2020-10-16 13:52:52 +02:00
Adolfo Gómez García
33502140cf Merge remote-tracking branch 'origin/v3.0' 2020-10-16 13:29:18 +02:00
Adolfo Gómez García
63280bf9cb Merge remote-tracking branch 'origin/v3.0' 2020-10-16 11:46:45 +02:00
Adolfo Gómez García
1d90f04245 Upgraded angualar version for user & admin 2020-10-15 04:40:32 +02:00
Adolfo Gómez García
a486e68e39 Removed old unused project files 2020-10-15 04:09:34 +02:00
Adolfo Gómez García
76e5aede37 Modified VERSION for future version release. Current stable is 3.0 2020-10-15 03:48:44 +02:00
1237 changed files with 89902 additions and 111710 deletions

7
.gitignore vendored
View File

@ -32,9 +32,6 @@
/client/administration/installer/UDSAdminInstaller/MSChart.exe
/client/administration/installer/UDSAdminInstaller/UDSAdminSetup.exe
# /guacamole-tunnel/
/guacamole-tunnel/target
# /linuxActor/
/linuxActor/udsactor_*
@ -67,8 +64,6 @@
# /server/
*_enterprise
/server/openuds.sublime-project
/server/openuds.sublime-workspace
# /server/src/
/server/src/taskmanager.pid
@ -91,7 +86,6 @@
# /server/src/uds/
/server/src/uds/*_enterprise.py
/server/src/uds/fixtures
/server/src/uds/tests
# /server/src/uds/auths/
/server/src/uds/auths/*-enterprise
@ -168,3 +162,4 @@
.vscode
.mypy_cache
.pytest_cache

29
LICENSE Normal file
View File

@ -0,0 +1,29 @@
BSD 3-Clause License
Copyright (c) 2022, Virtual Cable S.L.U.
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
2. 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.
3. Neither the name of the copyright holder 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.

View File

@ -10,7 +10,6 @@ OpenUDS (Universal Desktop Services) is a multiplatform connection broker for:
This is an Open Source Source project, initiated by Spanish Company Virtualcable and released Open Source with the help of several Spanish Universities.
Any help provided will be welcome.
Please fell free to contribute to this project.
**Note: Master version is always under heavy development and it is not recommended for use, it will probably have unfixed bugs.
For use, please use the latest stable branch.**
**Note: Master version is always under heavy development and it is not recommended for use, it will probably have unfixed bugs. Please use the latest stable branch.**

View File

@ -1 +1 @@
3.0.0
4.0.0

2
actor/.env Normal file
View File

@ -0,0 +1,2 @@
PYTHONPATH=./src:${PYTHONPATH}

View File

@ -1,4 +0,0 @@
Linux:
python3-prctl (recommended, but not required in fact)
python3-pyqt5

View File

@ -11,6 +11,9 @@ dpkg-buildpackage -b
cat udsactor-template.spec |
sed -e s/"version 0.0.0"/"version ${VERSION}"/g |
sed -e s/"release 1"/"release ${RELEASE}"/g > udsactor-$VERSION.spec
cat udsactor-unmanaged-template.spec |
sed -e s/"version 0.0.0"/"version ${VERSION}"/g |
sed -e s/"release 1"/"release ${RELEASE}"/g > udsactor-unmanaged-$VERSION.spec
# Now fix dependencies for opensuse
# Note that, although on opensuse the library is "libXss1" on newer,
@ -22,7 +25,7 @@ cat udsactor-template.spec |
# sed -e s/"libXScrnSaver"/"libXss1"/g > udsactor-opensuse-$VERSION.spec
#for pkg in udsactor-$VERSION.spec udsactor-opensuse-$VERSION.spec; do
for pkg in udsactor-$VERSION.spec; do
for pkg in udsactor-*$VERSION.spec; do
rm -rf rpm
for folder in SOURCES BUILD RPMS SPECS SRPMS; do

View File

@ -1,3 +1,21 @@
udsactor (4.0.0) stable; urgency=medium
* Upgraded to 4.0.0 release
-- Adolfo Gómez García <agomez@virtualcable.es> Fri, 1 Jul 2022 15:00:00 +0200
udsactor (3.6.0) stable; urgency=medium
* Upgraded to 3.6.0 release
-- Adolfo Gómez García <agomez@virtualcable.es> Fri, 1 Jul 2022 14:00:00 +0200
udsactor (3.5.0) stable; urgency=medium
* Upgraded to 3.5.0 release
-- Adolfo Gómez García <agomez@virtualcable.es> Fri, 23 Oct 2020 8:00:00 +0200
udsactor (3.0.0) stable; urgency=medium
* Upgraded to 3.0.0 release

View File

@ -10,7 +10,7 @@ Package: udsactor
Section: admin
Priority: optional
Architecture: all
Depends: policykit-1(>=0.100), python3-requests (>=0.8.2), python3-pyqt5 (>=4.9), python3-six(>=1.1), python3 (>=3.4), libxss1, xscreensaver, ${misc:Depends}
Depends: policykit-1(>=0.100), python3-requests (>=0.8.2), python3-pyqt5 (>=4.9), python3-six(>=1.1), python3 (>=3.6), libxss1, xscreensaver, ${misc:Depends}
Recommends: python3-prctl(>=1.1.1)
Description: Actor for Universal Desktop Services (UDS) Broker
This package provides the required components to allow managed machines to work on an environment managed by UDS Broker.
@ -19,7 +19,7 @@ Package: udsactor-unmanaged
Section: admin
Priority: optional
Architecture: all
Depends: policykit-1(>=0.100), python3-requests (>=0.8.2), python3-pyqt5 (>=4.9), python3-six(>=1.1), python3 (>=3.4), libxss1, xscreensaver, ${misc:Depends}
Depends: policykit-1(>=0.100), python3-requests (>=0.8.2), python3-pyqt5 (>=4.9), python3-six(>=1.1), python3 (>=3.6), libxss1, xscreensaver, ${misc:Depends}
Recommends: python3-prctl(>=1.1.1)
Description: Actor for Universal Desktop Services (UDS) Broker Static Unmanaged machines
This package provides the required components to allow unmanaged machines (static, independent machines) to work on an environment managed by UDS Broker.

View File

@ -1,3 +1,3 @@
udsactor-unmanaged_3.0.0_all.deb admin optional
udsactor_3.0.0_all.deb admin optional
udsactor_3.0.0_amd64.buildinfo admin optional
udsactor-unmanaged_3.6.0_all.deb admin optional
udsactor_3.6.0_all.deb admin optional
udsactor_3.6.0_amd64.buildinfo admin optional

View File

@ -3,4 +3,4 @@
FOLDER=/usr/share/UDSActor
cd $FOLDER
exec python3 actor_config.py $@
exec python3 actor_config.py -platform xcb $@

View File

@ -3,4 +3,4 @@
FOLDER=/usr/share/UDSActor
cd $FOLDER
exec python3 actor_config_unmanaged.py $@
exec python3 actor_config_unmanaged.py -platform xcb $@

View File

@ -3,4 +3,4 @@
FOLDER=/usr/share/UDSActor
cd $FOLDER
exec python3 actor_client.py $@
exec python3 -s actor_client.py -platform xcb $@

View File

@ -1,5 +1,5 @@
%define _topdir %(echo $PWD)/rpm
%define name udsactor
%define name udsactor-unmanaged
%define version 0.0.0
%define release 1
%define buildroot %{_topdir}/%{name}-%{version}-%{release}-root
@ -11,7 +11,7 @@ Release: %{release}
Summary: Actor for Universal Desktop Services (UDS) Broker
License: BSD3
Group: Admin
Requires: python-six python-requests PyQt4 libXScrnSaver
Requires: python3-six python3-requests python3-qt5 libXScrnSaver
Vendor: Virtual Cable S.L.U.
URL: http://www.udsenterprise.com
Provides: udsactor
@ -23,7 +23,7 @@ Provides: udsactor
%install
curdir=`pwd`
cd ../..
make DESTDIR=$RPM_BUILD_ROOT DISTRO=rh install-udsactor
make DESTDIR=$RPM_BUILD_ROOT DISTRO=rh install-udsactor-unmanaged
cd $curdir
%clean
@ -51,13 +51,13 @@ fi
rm -rf /usr/share/UDSActor > /dev/null 2>&1
%description
This package provides the required components to allow this machine to work on an environment managed by UDS Broker.
This package provides the required components to allow this unmanaged machine to work on an environment managed by UDS Broker.
%files
%defattr(-,root,root)
/etc/udsactor
/etc/xdg/autostart/UDSActorTool.desktop
/etc/init.d/udsactor
/etc/systemd/system/udsactor.service
/usr/bin/UDSActorTool-startup
/usr/bin/udsactor
/usr/bin/udsvapp

View File

@ -0,0 +1,33 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>Label</key>
<string>net.virtualcable.udsactor.server</string>
<key>KeepAlive</key>
<dict>
<key>SuccessfulExit</key>
<false/>
</dict>
<key>ProgramArguments</key>
<array>
<string>/Applications/UDSActor.app/Contents/MacOS/udsactor</string>
<string>start</string>
</array>
<key>RunAtLoad</key>
<true/>
<key>StandardErrorPath</key>
<string>/var/log/udsactor.log</string>
<key>StandardOutPath</key>
<string>/var/log/nxserver.log</string>
<key>WorkingDirectory</key>
<string>/Applications/UDSActor.app/Contents/Resources/</string>
</dict>
</plist>

1
actor/macos/notes.txt Normal file
View File

@ -0,0 +1 @@
service file (net.virtualcable.udsactor.server.plist) goes in /Library/LaunchDaemons

View File

@ -29,33 +29,32 @@
'''
@author: Adolfo Gómez, dkmaster at dkmon dot com
'''
# pylint: disable=invalid-name
import sys
import os
import PyQt5 # pylint: disable=unused-import
import PyQt5 # noqa
from PyQt5.QtCore import QTimer
from PyQt5.QtWidgets import QMainWindow
from udsactor.log import logger, INFO
from udsactor.client import UDSClientQApp
from udsactor.platform import operations
from udsactor import platform
if __name__ == "__main__":
logger.setLevel(INFO)
# Ensure idle operations is initialized on start
operations.initIdleDuration(0)
platform.operations.initIdleDuration(0)
if 'linux' in sys.platform:
if platform.is_linux:
os.environ['QT_X11_NO_MITSHM'] = '1'
UDSClientQApp.setQuitOnLastWindowClosed(False)
qApp = UDSClientQApp(sys.argv)
if 'linux' not in sys.platform:
# The "hidden window" is only needed to process events on Windows
if platform.is_windows or platform.is_mac:
# The "hidden window" is not needed on linux
# Not needed on Linux
mw = QMainWindow()
mw.showMinimized() # Start minimized, will be hidden (not destroyed) as soon as qApp.init is invoked
@ -67,9 +66,9 @@ if __name__ == "__main__":
# Note: Signals are only checked on python code execution, so we create a timer to force call back to python
timer = QTimer(qApp)
timer.start(1000)
timer.timeout.connect(lambda *a: None)
timer.timeout.connect(lambda *a: None) # type: ignore # timeout can be connected to a callable
qApp.exec_()
qApp.exec()
# On windows, if no window is created, this point will never be reached.
qApp.end()

View File

@ -1,7 +1,7 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
#
# Copyright (c) 2020 Virtual Cable S.L.
# Copyright (c) 2020-2022 Virtual Cable S.L.U.
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without modification,
@ -35,7 +35,7 @@ import os
import logging
import typing
import PyQt5 # pylint: disable=unused-import
import PyQt5 # Ensures PyQt is included in the package
from PyQt5.QtWidgets import QApplication, QDialog, QFileDialog, QMessageBox
import udsactor
@ -187,9 +187,9 @@ if __name__ == "__main__":
app = QApplication(sys.argv)
if udsactor.platform.operations.checkPermissions() is False:
QMessageBox.critical(None, 'UDS Actor', 'This Program must be executed as administrator', QMessageBox.Ok)
QMessageBox.critical(None, 'UDS Actor', 'This Program must be executed as administrator', QMessageBox.Ok) # type: ignore
sys.exit(1)
myapp = UDSConfigDialog()
myapp.show()
sys.exit(app.exec_())
sys.exit(app.exec())

View File

@ -1,7 +1,7 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
#
# Copyright (c) 2020 Virtual Cable S.L.
# Copyright (c) 2020-2022 Virtual Cable S.L.U.
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without modification,
@ -12,7 +12,7 @@
# * 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
# * Neither the name of Virtual Cable S.L.U. nor the names of its contributors
# may be used to endorse or promote products derived from this software
# without specific prior written permission.
#
@ -32,7 +32,7 @@
# pylint: disable=invalid-name
import sys
import os
import pickle
import pickle # nosec: B403
import logging
import typing
@ -40,6 +40,7 @@ import PyQt5 # pylint: disable=unused-import
from PyQt5.QtWidgets import QApplication, QDialog, QMessageBox
import udsactor
import udsactor.tools
from ui.setup_dialog_unmanaged_ui import Ui_UdsActorSetupDialog
@ -49,6 +50,7 @@ if typing.TYPE_CHECKING:
logger = logging.getLogger('actor')
class UDSConfigDialog(QDialog):
_host: str = ''
_config: udsactor.types.ActorConfigurationType
@ -60,91 +62,130 @@ class UDSConfigDialog(QDialog):
self.ui = Ui_UdsActorSetupDialog()
self.ui.setupUi(self)
self.ui.host.setText(self._config.host)
self.ui.validateCertificate.setCurrentIndex(1 if self._config.validateCertificate else 0)
self.ui.validateCertificate.setCurrentIndex(
1 if self._config.validateCertificate else 0
)
self.ui.logLevelComboBox.setCurrentIndex(self._config.log_level)
self.ui.serviceToken.setText(self._config.master_token)
self.ui.serviceToken.setText(self._config.master_token or '')
self.ui.restrictNet.setText(self._config.restrict_net or '')
self.ui.testButton.setEnabled(bool(self._config.master_token and self._config.host))
self.ui.testButton.setEnabled(
bool(self._config.master_token and self._config.host)
)
@property
def api(self) -> udsactor.rest.UDSServerApi:
return udsactor.rest.UDSServerApi(self.ui.host.text(), self.ui.validateCertificate.currentIndex() == 1)
return udsactor.rest.UDSServerApi(
self.ui.host.text(), self.ui.validateCertificate.currentIndex() == 1
)
def finish(self) -> None:
self.close()
def configChanged(self, text: str) -> None:
self.ui.testButton.setEnabled(self.ui.host.text() == self._config.host and self.ui.serviceToken.text() == self._config.master_token)
self.ui.testButton.setEnabled(
self.ui.host.text() == self._config.host
and self.ui.serviceToken.text() == self._config.master_token
and self.ui.restrictNet.text() == self._config.restrict_net
)
def testUDSServer(self) -> None:
if not self._config.master_token or not self._config.host:
self.ui.testButton.setEnabled(False)
return
try:
api = udsactor.rest.UDSServerApi(self._config.host, self._config.validateCertificate)
api = udsactor.rest.UDSServerApi(
self._config.host, self._config.validateCertificate
)
if not api.test(self._config.master_token, udsactor.types.UNMANAGED):
QMessageBox.information(
self,
'UDS Test',
'Service token seems to be invalid . Please, check token validity.',
QMessageBox.Ok
QMessageBox.Ok, # type: ignore
)
else:
QMessageBox.information(
self,
'UDS Test',
'Configuration for {} seems to be correct.'.format(self._config.host),
QMessageBox.Ok
'Configuration for {} seems to be correct.'.format(
self._config.host
),
QMessageBox.Ok, # type: ignore
)
except Exception:
QMessageBox.information(
self,
'UDS Test',
'Configured host {} seems to be inaccesible.'.format(self._config.host),
QMessageBox.Ok
QMessageBox.Ok, # type: ignore
)
def saveConfig(self) -> None:
# Ensure restrict_net is empty or a valid subnet
restrictNet = self.ui.restrictNet.text().strip()
if restrictNet:
try:
subnet = udsactor.tools.strToNoIPV4Network(restrictNet)
if not subnet:
raise Exception('Invalid subnet')
except Exception:
QMessageBox.information(
self,
'Invalid subnet',
'Invalid subnet {}. Please, check it.'.format(restrictNet),
QMessageBox.Ok, # type: ignore
)
return
# Store parameters on register for later use, notify user of registration
self._config = udsactor.types.ActorConfigurationType(
actorType=udsactor.types.UNMANAGED,
host=self.ui.host.text(),
validateCertificate=self.ui.validateCertificate.currentIndex() == 1,
master_token=self.ui.serviceToken.text(),
log_level=self.ui.logLevelComboBox.currentIndex()
master_token=self.ui.serviceToken.text().strip(),
restrict_net=restrictNet,
log_level=self.ui.logLevelComboBox.currentIndex(),
)
udsactor.platform.store.writeConfig(self._config)
# Enables test button
self.ui.testButton.setEnabled(True)
# Informs the user
QMessageBox.information(self, 'UDS Configuration', 'Configuration saved.', QMessageBox.Ok)
QMessageBox.information(
self,
'UDS Configuration',
'Configuration saved.',
QMessageBox.Ok, # type: ignore
)
if __name__ == "__main__":
# If to be run as "sudo" on linux, we will need this to avoid problems
# If run as "sudo" on linux, we will need this to avoid problems
if 'linux' in sys.platform:
os.environ['QT_X11_NO_MITSHM'] = '1'
app = QApplication(sys.argv)
if udsactor.platform.operations.checkPermissions() is False:
QMessageBox.critical(None, 'UDS Actor', 'This Program must be executed as administrator', QMessageBox.Ok)
QMessageBox.critical(None, 'UDS Actor', 'This Program must be executed as administrator', QMessageBox.Ok) # type: ignore
sys.exit(1)
if len(sys.argv) > 2:
if sys.argv[1] == 'export':
try:
with open(sys.argv[2], 'wb') as f:
pickle.dump(udsactor.platform.store.readConfig(), f, protocol=3)
with open(sys.argv[2], 'wb') as export_:
pickle.dump(
udsactor.platform.store.readConfig(), export_, protocol=3
)
except Exception as e:
print('Error exporting configuration file: {}'.format(e))
sys.exit(1)
sys.exit(0)
if sys.argv[1] == 'import':
elif sys.argv[1] == 'import':
try:
with open(sys.argv[2], 'rb') as f:
config = pickle.load(f)
with open(sys.argv[2], 'rb') as import_:
config = pickle.load(import_) # nosec: B301: the file is provided by user, so it's not a security issue
udsactor.platform.store.writeConfig(config)
except Exception as e:
print('Error importing configuration file: {}'.format(e))
@ -153,4 +194,4 @@ if __name__ == "__main__":
myapp = UDSConfigDialog()
myapp.show()
sys.exit(app.exec_())
sys.exit(app.exec())

View File

@ -1,7 +1,7 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
#
# Copyright (c) 2020 Virtual Cable S.L.
# Copyright (c) 2020-2022 Virtual Cable S.L.U.
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without modification,
@ -12,7 +12,7 @@
# * 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
# * Neither the name of Virtual Cable S.L.U. nor the names of its contributors
# may be used to endorse or promote products derived from this software
# without specific prior written permission.
#
@ -29,12 +29,8 @@
'''
@author: Adolfo Gómez, dkmaster at dkmon dot com
'''
import sys
from udsactor import platform
if sys.platform == 'win32':
from udsactor.windows import runner
else:
from udsactor.linux import runner
if __name__ == "__main__":
runner.run()
platform.runner.run()

View File

@ -10,8 +10,8 @@
<rect>
<x>0</x>
<y>0</y>
<width>595</width>
<height>220</height>
<width>601</width>
<height>243</height>
</rect>
</property>
<property name="sizePolicy">
@ -55,7 +55,7 @@
<property name="geometry">
<rect>
<x>10</x>
<y>180</y>
<y>210</y>
<width>181</width>
<height>23</height>
</rect>
@ -83,7 +83,7 @@
<property name="geometry">
<rect>
<x>410</x>
<y>180</y>
<y>210</y>
<width>171</width>
<height>23</height>
</rect>
@ -117,7 +117,7 @@
<property name="geometry">
<rect>
<x>210</x>
<y>180</y>
<y>210</y>
<width>181</width>
<height>23</height>
</rect>
@ -144,7 +144,7 @@
<x>10</x>
<y>10</y>
<width>571</width>
<height>161</height>
<height>191</height>
</rect>
</property>
<layout class="QFormLayout" name="formLayout">
@ -214,21 +214,21 @@
<item row="2" column="1">
<widget class="QLineEdit" name="serviceToken">
<property name="toolTip">
<string>UDS user with administration rights (Will not be stored on template)</string>
<string>UDS Service Token</string>
</property>
<property name="whatsThis">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Administrator user on UDS Server.&lt;/p&gt;&lt;p&gt;Note: This credential will not be stored on client. Will be used to obtain an unique token for this image.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Token of the service on UDS platform&lt;/p&gt;&lt;p&gt;This token can be obtainend from the service configuration on UDS.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
</widget>
</item>
<item row="3" column="0">
<item row="4" column="0">
<widget class="QLabel" name="label_loglevel">
<property name="text">
<string>Log Level</string>
</property>
</widget>
</item>
<item row="3" column="1">
<item row="4" column="1">
<widget class="QComboBox" name="logLevelComboBox">
<property name="currentIndex">
<number>1</number>
@ -258,6 +258,23 @@
</item>
</widget>
</item>
<item row="3" column="0">
<widget class="QLabel" name="label_restrictNet">
<property name="text">
<string>Restrict Net</string>
</property>
</widget>
</item>
<item row="3" column="1">
<widget class="QLineEdit" name="restrictNet">
<property name="toolTip">
<string>Restrict valid detection of network interfaces to this network.</string>
</property>
<property name="whatsThis">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Restrics valid detection of network interfaces.&lt;/p&gt;&lt;p&gt;Note: Use this field only in case of several network interfaces, so UDS knows which one is the interface where the user will be connected..&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
</widget>
</item>
</layout>
<zorder>label_host</zorder>
<zorder>host</zorder>
@ -267,6 +284,8 @@
<zorder>label_security</zorder>
<zorder>label_loglevel</zorder>
<zorder>logLevelComboBox</zorder>
<zorder>label_restrictNet</zorder>
<zorder>restrictNet</zorder>
</widget>
</widget>
<resources>
@ -353,6 +372,22 @@
</hint>
</hints>
</connection>
<connection>
<sender>restrictNet</sender>
<signal>textChanged(QString)</signal>
<receiver>UdsActorSetupDialog</receiver>
<slot>configChanged()</slot>
<hints>
<hint type="sourcelabel">
<x>341</x>
<y>139</y>
</hint>
<hint type="destinationlabel">
<x>295</x>
<y>121</y>
</hint>
</hints>
</connection>
</connections>
<slots>
<slot>finish()</slot>

View File

@ -35,4 +35,4 @@ from . import platform
__title__ = 'udsactor'
__author__ = 'Adolfo Gómez <dkmaster@dkmon.com>'
__license__ = "BSD 3-clause"
__copyright__ = "Copyright 2014-2020 VirtualCable S.L.U."
__copyright__ = "Copyright 2014-2022 VirtualCable S.L.U."

View File

@ -65,9 +65,9 @@ class UDSClientQApp(QApplication):
self._initialized = False
# This will be invoked on session close
self.commitDataRequest.connect(self.end) # Will be invoked on session close, to gracely close app
self.commitDataRequest.connect(self.end) # type: ignore # Will be invoked on session close, to gracely close app
# self.aboutToQuit.connect(self.end)
self.message.connect(self.showMessage)
self.message.connect(self.showMessage) # type: ignore # there are problems with Pylance and connects on PyQt5... :)
# Execute backgroup thread for actions
self._app = UDSActorClient(self)
@ -94,7 +94,7 @@ class UDSClientQApp(QApplication):
self._app.join()
def showMessage(self, message: str) -> None:
QMessageBox.information(None, 'Message', message)
QMessageBox.information(None, 'Message', message) # type: ignore
def setMainWindow(self, mw: 'QMainWindow'):
self._mainWindow = mw
@ -108,6 +108,7 @@ class UDSActorClient(threading.Thread): # pylint: disable=too-many-instance-att
_listener: client.HTTPServerThread
_loginInfo: typing.Optional['types.LoginResultInfoType']
_notified: bool
_notifiedDeadline: bool
_sessionStartTime: datetime.datetime
api: rest.UDSClientApi
@ -115,13 +116,14 @@ class UDSActorClient(threading.Thread): # pylint: disable=too-many-instance-att
super().__init__()
self.api = rest.UDSClientApi() # Self initialized
self._qApp = qApp
self._qApp = typing.cast(UDSClientQApp, qApp)
self._running = False
self._forceLogoff = False
self._extraLogoff = ''
self._listener = client.HTTPServerThread(self)
self._loginInfo = None
self._notified = False
self._notifiedDeadline = False
# Capture stop signals..
logger.debug('Setting signals...')
@ -139,8 +141,8 @@ class UDSActorClient(threading.Thread): # pylint: disable=too-many-instance-att
remainingTime = self._loginInfo.dead_line - (datetime.datetime.now() - self._sessionStartTime).total_seconds()
logger.debug('Remaining time: {}'.format(remainingTime))
if not self._notified and remainingTime < 300: # With five minutes, show a warning message
self._notified = True
if not self._notifiedDeadline and remainingTime < 300: # With five minutes, show a warning message
self._notifiedDeadline = True
self._showMessage('Your session will expire in less that 5 minutes. Please, save your work and disconnect.')
return
@ -183,7 +185,8 @@ class UDSActorClient(threading.Thread): # pylint: disable=too-many-instance-att
try:
# Notify loging and mark it
self._loginInfo = self.api.login(platform.operations.getCurrentUser(), platform.operations.getSessionType())
user, sessionType = platform.operations.getCurrentUser(), platform.operations.getSessionType()
self._loginInfo = self.api.login(user, sessionType)
if self._loginInfo.max_idle:
platform.operations.initIdleDuration(self._loginInfo.max_idle)
@ -193,10 +196,13 @@ class UDSActorClient(threading.Thread): # pylint: disable=too-many-instance-att
self.checkIdle()
self.checkDeadLine()
time.sleep(1.3) # Sleeps between loop iterations
time.sleep(1.22) # Sleeps between loop iterations
self.api.logout(user + self._extraLogoff, sessionType)
logger.info('Notified logout for %s (%s)', user, sessionType) # Log logout
# Clean up login info
self._loginInfo = None
self.api.logout(platform.operations.getCurrentUser() + self._extraLogoff)
except Exception as e:
logger.error('Error on client loop: %s', e)
@ -210,7 +216,7 @@ class UDSActorClient(threading.Thread): # pylint: disable=too-many-instance-att
platform.operations.loggoff()
def _showMessage(self, message: str) -> None:
self._qApp.message.emit(message)
self._qApp.message.emit(message) # type: ignore # there are problems with Pylance and connects on PyQt5... :)
def stop(self) -> None:
logger.debug('Stopping client Service')
@ -230,13 +236,13 @@ class UDSActorClient(threading.Thread): # pylint: disable=too-many-instance-att
On windows, an RDP session with minimized screen will render "black screen"
So only when user is using RDP connection will return an "actual" screenshot
'''
pixmap: 'QPixmap' = self._qApp.primaryScreen().grabWindow(0)
pixmap: 'QPixmap' = self._qApp.primaryScreen().grabWindow(0) # type: ignore
ba = QByteArray()
buffer = QBuffer(ba)
buffer.open(QIODevice.WriteOnly)
buffer.open(QIODevice.WriteOnly) # type: ignore
pixmap.save(buffer, 'PNG')
buffer.close()
scrBase64 = bytes(ba.toBase64()).decode()
scrBase64 = bytes(ba.toBase64()).decode() # type: ignore # there are problems with Pylance and connects on PyQt5... :)
logger.debug('Screenshot length: %s', len(scrBase64))
return scrBase64 # 'result' of JSON will contain base64 of screen

View File

@ -132,7 +132,7 @@ class HTTPServerThread(threading.Thread):
self._app = app
self.port = -1
self.id = secrets.token_urlsafe(16)
self.id = secrets.token_urlsafe(24)
@property
def url(self) -> str:

View File

@ -33,8 +33,8 @@ import json
import typing
import requests
from ..log import logger
from udsactor import tools, types
from udsactor.log import logger
# For avoid proxy on localhost connections
NO_PROXY = {
@ -42,55 +42,108 @@ NO_PROXY = {
'https': None,
}
class UDSActorClientPool:
_clientUrl: typing.List[str]
class UDSActorClientPool(metaclass=tools.Singleton):
_clients: typing.List[types.ClientInfo]
def __init__(self) -> None:
self._clientUrl = []
self._clients = []
def _post(self, method: str, data: typing.MutableMapping[str, str], timeout=2) -> typing.List[requests.Response]:
removables: typing.List[str] = []
result: typing.List[typing.Any] = []
for clientUrl in self._clientUrl:
def _post(
self,
session_id: typing.Optional[str],
method: str,
data: typing.MutableMapping[str, str],
timeout: int = 2,
) -> typing.List[
typing.Tuple[types.ClientInfo, typing.Optional[requests.Response]]
]:
result: typing.List[
typing.Tuple[types.ClientInfo, typing.Optional[requests.Response]]
] = []
for client in self._clients:
# Skip if session id is provided but does not match
if session_id and client.session_id != session_id:
continue
clientUrl = client.url
try:
result.append(requests.post(clientUrl + '/' + method, data=json.dumps(data), verify=False, timeout=timeout, proxies=NO_PROXY))
result.append(
(
client,
requests.post(
clientUrl + '/' + method,
data=json.dumps(data),
verify=False,
timeout=timeout,
proxies=NO_PROXY, # type: ignore
),
)
)
except Exception as e:
# If cannot request to a clientUrl, remove it from list
logger.info('Could not connect with client %s: %s. Removed from registry.', e, clientUrl)
removables.append(clientUrl)
# Remove failed connections
for clientUrl in removables:
self.unregister(clientUrl)
logger.info(
'Could not connect with client %s: %s. ',
e,
clientUrl,
)
result.append((client, None))
return result
def register(self, clientUrl: str) -> None:
@property
def clients(self) -> typing.List[types.ClientInfo]:
return self._clients
def register(self, client_url: str) -> None:
# Remove first if exists, to avoid duplicates
self.unregister(clientUrl)
self.unregister(client_url)
# And add it again
self._clientUrl.append(clientUrl)
self._clients.append(types.ClientInfo(client_url, ''))
def unregister(self, clientUrl: str) -> None:
self._clientUrl = list((i for i in self._clientUrl if i != clientUrl))
def set_session_id(self, client_url: str, session_id: typing.Optional[str]) -> None:
"""Set the session id for a client
def executeScript(self, script: str) -> None:
self._post('script', {'script': script}, timeout=30)
Args:
clientUrl (str): _description_
session_id (str): _description_
"""
for client in self._clients:
if client.url == client_url:
# remove existing client from list, create a new one and insert it
self._clients.remove(client)
self._clients.append(types.ClientInfo(client_url, session_id or ''))
break
def logout(self) -> None:
self._post('logout', {})
def unregister(self, client_url: str) -> None:
# remove client url from array if found
for i, client in enumerate(self._clients):
if client.url == client_url:
self._clients.pop(i)
return
def message(self, message: str) -> None:
self._post('message', {'message': message})
def executeScript(self, session_id: typing.Optional[str], script: str) -> None:
self._post(session_id, 'script', {'script': script}, timeout=30)
def ping(self) -> bool:
if not self._clientUrl:
return True # No clients, ping ok
self._post('ping', {}, timeout=1)
return bool(self._clientUrl) # There was clients, but they are now lost!!!
def logout(self, session_id: typing.Optional[str]) -> None:
self._post(session_id, 'logout', {})
def screenshot(self) -> typing.Optional[str]: # Screenshot are returned as base64
for r in self._post('screenshot', {}, timeout=3):
def message(self, session_id: typing.Optional[str], message: str) -> None:
self._post(session_id, 'message', {'message': message})
def lost_clients(
self,
session_id: typing.Optional[str] = None,
) -> typing.Iterable[types.ClientInfo]: # returns the list of "lost" clients
# Port ping to every client
for i in self._post(session_id, 'ping', {}, timeout=1):
if i[1] is None:
yield i[0]
def screenshot(
self, session_id: typing.Optional[str]
) -> typing.Optional[str]: # Screenshot are returned as base64
for client, r in self._post(session_id, 'screenshot', {}, timeout=3):
if not r:
continue # Missing client, so we ignore it
try:
return r.json()['result']
except Exception:

View File

@ -30,19 +30,23 @@
'''
import typing
from . import handler
from udsactor.http import handler, clients_pool
if typing.TYPE_CHECKING:
from ..service import CommonService
from udsactor.service import CommonService
class LocalProvider(handler.Handler):
def post_login(self) -> typing.Any:
result = self._service.login(self._params['username'], self._params['session_type'])
# if callback_url is provided, record it in the clients pool
if 'callback_url' in self._params and result.session_id:
# If no session id is returned, then no login is acounted for
clients_pool.UDSActorClientPool().set_session_id(self._params['callback_url'], result.session_id)
return result._asdict()
def post_logout(self) -> typing.Any:
self._service.logout(self._params['username'])
self._service.logout(self._params['username'], self._params['session_type'], self._params['session_id'])
return 'ok'
def post_ping(self) -> typing.Any:

View File

@ -38,6 +38,7 @@ from ..log import logger
if typing.TYPE_CHECKING:
from ..service import CommonService
class PublicProvider(handler.Handler):
def post_logout(self) -> typing.Any:
logger.debug('Sending LOGOFF to clients')
@ -51,7 +52,9 @@ class PublicProvider(handler.Handler):
logger.debug('Sending MESSAGE to clients')
if 'message' not in self._params:
raise Exception('Invalid message parameters')
self._service._clientsPool.message(self._params['message']) # pylint: disable=protected-access
self._service._clientsPool.message(
self._params['message']
) # pylint: disable=protected-access
return 'ok'
def post_script(self) -> typing.Any:
@ -60,7 +63,9 @@ class PublicProvider(handler.Handler):
raise Exception('Invalid script parameters')
if self._params.get('user', False):
logger.debug('Sending SCRIPT to client')
self._service._clientsPool.executeScript(self._params['script']) # pylint: disable=protected-access
self._service._clientsPool.executeScript(
self._params['script']
) # pylint: disable=protected-access
else:
# Execute script at server space, that is, here
# as a parallel thread
@ -72,14 +77,22 @@ class PublicProvider(handler.Handler):
logger.debug('Received Pre connection')
if 'user' not in self._params or 'protocol' not in self._params:
raise Exception('Invalid preConnect parameters')
return self._service.preConnect(self._params['user'], self._params['protocol'], self._params.get('ip', 'unknown'), self._params.get('hostname', 'unknown'))
return self._service.preConnect(
self._params['user'],
self._params['protocol'],
self._params.get('ip', 'unknown'),
self._params.get('hostname', 'unknown'),
self._params.get('udsuser', 'unknown'),
)
def get_information(self) -> typing.Any:
# Return something useful? :)
return 'UDS Actor Secure Server'
def get_screenshot(self) -> typing.Any:
return self._service._clientsPool.screenshot() # pylint: disable=protected-access
return (
self._service._clientsPool.screenshot()
) # pylint: disable=protected-access
def get_uuid(self) -> typing.Any:
if self._service.isManaged():

View File

@ -71,7 +71,7 @@ class HTTPServerHandler(http.server.BaseHTTPRequestHandler):
# Very simple path & params splitter
path = self.path.split('?')[0][1:].split('/')
logger.debug('Path: %s, params: %s', path, params)
logger.debug('Path: %s, ip: %s, params: %s', path, self.client_address, params)
handlerType: typing.Optional[typing.Type['Handler']] = None
@ -159,7 +159,7 @@ class HTTPServerThread(threading.Thread):
# self._server.socket = ssl.wrap_socket(self._server.socket, certfile=self.certFile, server_side=True)
context = ssl.SSLContext(ssl.PROTOCOL_TLS_SERVER)
context.options = ssl.CERT_NONE
# context.options = ssl.CERT_NONE
context.load_cert_chain(certfile=self._certFile, password=password)
self._server.socket = context.wrap_socket(self._server.socket, server_side=True)

View File

@ -1 +0,0 @@
VERSION = '3.0.0'

View File

@ -101,7 +101,7 @@ class Daemon:
def removePidFile(self) -> None:
try:
os.remove(self.pidfile)
except Exception:
except Exception: # nosec: Not interested in exception
# Not found/not permissions or whatever, ignore it
pass

View File

@ -1,6 +1,6 @@
# -*- coding: utf-8 -*-
#
# Copyright (c) 2014-2019 Virtual Cable S.L.
# Copyright (c) 2014-2022 Virtual Cable S.L.U.
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without modification,
@ -11,7 +11,7 @@
# * 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
# * Neither the name of Virtual Cable S.L.U. nor the names of its contributors
# may be used to endorse or promote products derived from this software
# without specific prior written permission.
#
@ -35,8 +35,9 @@ import logging
import typing
class LocalLogger: # pylint: disable=too-few-public-methods
linux = False
windows = True
linux = True
windows = False
serviceLogger = False
logger: typing.Optional[logging.Logger]
@ -58,7 +59,8 @@ class LocalLogger: # pylint: disable=too-few-public-methods
self.logger = logging.getLogger('udsactor')
os.chmod(fname, 0o0600)
return
except Exception:
except Exception: # nosec: B110: we don't care about exceptions here
# Ignore and try next
pass
# Logger can't be set

View File

@ -34,7 +34,7 @@ import platform
import socket
import fcntl # Only available on Linux. Expect complains if edited from windows
import os
import subprocess
import subprocess # nosec
import struct
import array
import typing
@ -53,7 +53,9 @@ def _getMacAddr(ifname: str) -> typing.Optional[str]:
ifnameBytes = ifname.encode('utf-8')
try:
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
info = bytearray(fcntl.ioctl(s.fileno(), 0x8927, struct.pack(str('256s'), ifnameBytes[:15])))
info = bytearray(
fcntl.ioctl(s.fileno(), 0x8927, struct.pack(str('256s'), ifnameBytes[:15]))
)
return str(''.join(['%02x:' % char for char in info[18:24]])[:-1]).upper()
except Exception:
return None
@ -67,11 +69,15 @@ def _getIpAddr(ifname: str) -> typing.Optional[str]:
ifnameBytes = ifname.encode('utf-8')
try:
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
return str(socket.inet_ntoa(fcntl.ioctl(
s.fileno(),
0x8915, # SIOCGIFADDR
struct.pack(str('256s'), ifnameBytes[:15])
)[20:24]))
return str(
socket.inet_ntoa(
fcntl.ioctl(
s.fileno(),
0x8915, # SIOCGIFADDR
struct.pack(str('256s'), ifnameBytes[:15]),
)[20:24]
)
)
except Exception:
return None
@ -91,22 +97,32 @@ def _getInterfaces() -> typing.List[str]:
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
names = array.array(str('B'), b'\0' * space)
outbytes = struct.unpack(str('iL'), fcntl.ioctl(
s.fileno(),
0x8912, # SIOCGIFCONF
struct.pack(str('iL'), space, names.buffer_info()[0])
))[0]
outbytes = struct.unpack(
'iL',
fcntl.ioctl(
s.fileno(),
0x8912, # SIOCGIFCONF
struct.pack('iL', space, names.buffer_info()[0]),
),
)[0]
namestr = names.tobytes()
# return namestr, outbytes
return [namestr[i:i + offset].split(b'\0', 1)[0].decode('utf-8') for i in range(0, outbytes, length)]
return [
namestr[i : i + offset].split(b'\0', 1)[0].decode('utf-8')
for i in range(0, outbytes, length)
]
def _getIpAndMac(ifname: str) -> typing.Tuple[typing.Optional[str], typing.Optional[str]]:
def _getIpAndMac(
ifname: str,
) -> typing.Tuple[typing.Optional[str], typing.Optional[str]]:
ip, mac = _getIpAddr(ifname), _getMacAddr(ifname)
return (ip, mac)
def checkPermissions() -> bool:
return os.getuid() == 0 # getuid only available on linux. Expect "complaioins" if edited from Windows
return os.getuid() == 0
def getComputerName() -> str:
'''
@ -114,15 +130,23 @@ def getComputerName() -> str:
'''
return socket.gethostname().split('.')[0]
def getNetworkInfo() -> typing.Iterator[types.InterfaceInfoType]:
for ifname in _getInterfaces():
ip, mac = _getIpAndMac(ifname)
if mac != '00:00:00:00:00:00' and mac and ip and ip.startswith('169.254') is False: # Skips local interfaces & interfaces with no dhcp IPs
if (
mac != '00:00:00:00:00:00'
and mac
and ip
and ip.startswith('169.254') is False
): # Skips local interfaces & interfaces with no dhcp IPs
yield types.InterfaceInfoType(name=ifname, mac=mac, ip=ip)
def getDomainName() -> str:
return ''
def getLinuxOs() -> str:
try:
with open('/etc/os-release', 'r') as f:
@ -133,18 +157,22 @@ def getLinuxOs() -> str:
except Exception:
return 'unknown'
def getVersion() -> str:
return 'Linux ' + getLinuxOs()
def reboot(flags: int = 0):
'''
Simple reboot using os command
'''
subprocess.call(['/sbin/shutdown', 'now', '-r'])
subprocess.call(['/sbin/shutdown', 'now', '-r']) # nosec: Fine, all under control
def loggoff() -> None:
'''
Right now restarts the machine...
'''
subprocess.call(['/usr/bin/pkill', '-u', os.environ['USER']])
subprocess.call(['/usr/bin/pkill', '-u', os.environ['USER']]) # nosec: Fine, all under control
# subprocess.call(['/sbin/shutdown', 'now', '-r'])
# subprocess.call(['/usr/bin/systemctl', 'reboot', '-i'])
@ -155,10 +183,12 @@ def renameComputer(newName: str) -> bool:
Returns True if reboot needed
'''
rename(newName)
return True # Always reboot right now. Not much slower but much more better
return True # Always reboot right now. Not much slower but much more convenient
def joinDomain(domain: str, ou: str, account: str, password: str, executeInOneStep: bool = False):
def joinDomain(
domain: str, ou: str, account: str, password: str, executeInOneStep: bool = False
):
pass
@ -166,7 +196,11 @@ def changeUserPassword(user: str, oldPassword: str, newPassword: str) -> None:
'''
Simple password change for user using command line
'''
os.system('echo "{1}\n{1}" | /usr/bin/passwd {0} 2> /dev/null'.format(user, newPassword))
subprocess.run( # nosec: Fine, all under control
'echo "{1}\n{1}" | /usr/bin/passwd {0} 2> /dev/null'.format(user, newPassword),
shell=True,
)
def initIdleDuration(atLeastSeconds: int) -> None:
@ -181,16 +215,22 @@ def getCurrentUser() -> str:
'''
Returns current logged in user
'''
return os.environ['USER']
return os.getlogin()
def getSessionType() -> str:
'''
Known values:
* Unknown -> No SESSIONNAME environment variable
* Console -> Local session
* RDP-Tcp#[0-9]+ -> RDP Session
Known values:
* Unknown -> No XDG_SESSION_TYPE environment variable
* xrdp --> xrdp session
* other types
'''
return 'xrdp' if 'XRDP_SESSION' in os.environ else os.environ.get('XDG_SESSION_TYPE', 'unknown')
return (
'xrdp'
if 'XRDP_SESSION' in os.environ
else os.environ.get('XDG_SESSION_TYPE', 'unknown')
)
def forceTimeSync() -> None:
return

View File

@ -1,6 +1,6 @@
# -*- coding: utf-8 -*-
#
# Copyright (c) 2014-2019 Virtual Cable S.L.
# Copyright (c) 2014-2022 Virtual Cable S.L.U.
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without modification,
@ -11,7 +11,7 @@
# * 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
# * Neither the name of Virtual Cable S.L.U. nor the names of its contributors
# may be used to endorse or promote products derived from this software
# without specific prior written permission.
#
@ -28,7 +28,7 @@
'''
@author: Alexey Shabalin, shaba at altlinux dot org
'''
import os
import subprocess # nosec
from .common import renamers
from ...log import logger
@ -46,8 +46,8 @@ def rename(newName: str) -> bool:
hostname.write(newName)
# Force system new name
os.system('/bin/hostname {}'.format(newName))
os.system('/usr/bin/hostnamectl set-hostname {}'.format(newName))
subprocess.run(['hostnamectl', 'set-hostname', newName]) # nosec: subprocess
subprocess.run(['/bin/hostname', newName]) # nosec: subprocess
# add name to "hosts"
with open('/etc/hosts', 'r') as hosts:

View File

@ -29,9 +29,6 @@
'''
@author: Adolfo Gómez, dkmaster at dkmon dot com
'''
import os
import sys
import pkgutil
import typing
from .. import operations

View File

@ -29,7 +29,7 @@
'''
@author: Adolfo Gómez, dkmaster at dkmon dot com
'''
import os
import subprocess # nosec
from .common import renamers
from ...log import logger
@ -45,8 +45,8 @@ def rename(newName: str) -> bool:
hostname.write(newName)
# Force system new name
os.system('/bin/hostname {}'.format(newName))
os.system('/usr/bin/hostnamectl set-hostname {}'.format(newName))
subprocess.run(['hostnamectl', 'set-hostname', newName]) # nosec: ok, we are root
subprocess.run(['/bin/hostname', newName]) # nosec: ok, we are root
# add name to "hosts"
with open('/etc/hosts', 'r') as hosts:

View File

@ -28,7 +28,7 @@
'''
@author: Adolfo Gómez, dkmaster at dkmon dot com
'''
import os
import subprocess # nosec
from .common import renamers
from ...log import logger
@ -46,8 +46,8 @@ def rename(newName: str) -> bool:
hostname.write(newName)
# Force system new name
os.system('/bin/hostname {}'.format(newName))
os.system('/usr/bin/hostnamectl set-hostname {}'.format(newName))
subprocess.run(['hostnamectl', 'set-hostname', newName]) # nosec: ok, we are root
subprocess.run(['/bin/hostname', newName]) # nosec: ok, we are root
# add name to "hosts"
with open('/etc/hosts', 'r') as hosts:

View File

@ -28,7 +28,7 @@
'''
@author: Adolfo Gómez, dkmaster at dkmon dot com
'''
import os
import subprocess # nosec
from .common import renamers
from ...log import logger
@ -46,8 +46,8 @@ def rename(newName: str) -> bool:
hostname.write(newName)
# Force system new name
os.system('/bin/hostname {}'.format(newName))
os.system('/usr/bin/hostnamectl set-hostname {}'.format(newName))
subprocess.run(['hostnamectl', 'set-hostname', newName]) # nosec: ok, we are root
subprocess.run(['/bin/hostname', newName]) # nosec: ok, we are root
# add name to "hosts"
with open('/etc/hosts', 'r') as hosts:

View File

@ -50,7 +50,7 @@ def run() -> None:
r = client.login(sys.argv[2], platform.operations.getSessionType())
print('{},{},{},{}\n'.format(r.ip, r.hostname, r.max_idle, r.dead_line or ''))
elif sys.argv[1] == 'logout':
client.logout(sys.argv[2])
client.logout(sys.argv[2], platform.operations.getSessionType())
except Exception as e:
logger.exception()
logger.error('Got exception while processing command: %s', e)

View File

@ -37,7 +37,7 @@ from ..log import logger
from ..service import CommonService
try:
from prctl import set_proctitle # @UnresolvedImport
from prctl import set_proctitle # type: ignore
except ImportError: # Platform may not include prctl, so in case it's not available, we let the "name" as is
def set_proctitle(_):
pass

View File

@ -32,12 +32,13 @@
import os
import configparser
import base64
import pickle
import pickle # nosec
from .. import types
CONFIGFILE = '/etc/udsactor/udsactor.cfg'
def readConfig() -> types.ActorConfigurationType:
try:
cfg = configparser.ConfigParser()
@ -45,10 +46,22 @@ def readConfig() -> types.ActorConfigurationType:
uds: configparser.SectionProxy = cfg['uds']
# Extract data:
base64Config = uds.get('config', None)
config = pickle.loads(base64.b64decode(base64Config.encode())) if base64Config else None
config = (
pickle.loads( # nosec: file is restricted
base64.b64decode(base64Config.encode())
)
if base64Config
else None
)
base64Data = uds.get('data', None)
data = pickle.loads(base64.b64decode(base64Data.encode())) if base64Data else None
data = (
pickle.loads( # nosec: file is restricted
base64.b64decode(base64Data.encode())
)
if base64Data
else None
)
return types.ActorConfigurationType(
actorType=uds.get('type', types.MANAGED),
@ -56,28 +69,33 @@ def readConfig() -> types.ActorConfigurationType:
validateCertificate=uds.getboolean('validate', fallback=False),
master_token=uds.get('master_token', None),
own_token=uds.get('own_token', None),
restrict_net=uds.get('restrict_net', None),
pre_command=uds.get('pre_command', None),
runonce_command=uds.get('runonce_command', None),
post_command=uds.get('post_command', None),
log_level=int(uds.get('log_level', '2')),
config=config,
data=data
data=data,
)
except Exception:
return types.ActorConfigurationType('', False)
def writeConfig(config: types.ActorConfigurationType) -> None:
cfg = configparser.ConfigParser()
cfg.add_section('uds')
uds: configparser.SectionProxy = cfg['uds']
uds['host'] = config.host
uds['validate'] = 'yes' if config.validateCertificate else 'no'
def writeIfValue(val, name):
if val:
uds[name] = val
writeIfValue(config.actorType, 'type')
writeIfValue(config.master_token, 'master_token')
writeIfValue(config.own_token, 'own_token')
writeIfValue(config.restrict_net, 'restrict_net')
writeIfValue(config.pre_command, 'pre_command')
writeIfValue(config.post_command, 'post_command')
writeIfValue(config.runonce_command, 'runonce_command')
@ -91,12 +109,19 @@ def writeConfig(config: types.ActorConfigurationType) -> None:
# Ensures exists destination folder
dirname = os.path.dirname(CONFIGFILE)
if not os.path.exists(dirname):
os.mkdir(dirname, mode=0o700) # Will create only if route to path already exists, for example, /etc (that must... :-))
os.mkdir(
dirname, mode=0o700
) # Will create only if route to path already exists, for example, /etc (that must... :-))
with open(CONFIGFILE, 'w') as f:
cfg.write(f)
os.chmod(CONFIGFILE, 0o0600) # Ensure only readable by root
def useOldJoinSystem() -> bool:
return False
def invokeScriptOnLogin() -> str:
return ''

View File

@ -31,7 +31,7 @@
# pylint: disable=invalid-name
import ctypes
import ctypes.util
import subprocess
import subprocess # nosec
xlib = None
xss = None
@ -39,17 +39,22 @@ display = None
xssInfo = None
initialized = False
class XScreenSaverInfo(ctypes.Structure): # pylint: disable=too-few-public-methods
_fields_ = [('window', ctypes.c_long),
('state', ctypes.c_int),
('kind', ctypes.c_int),
('til_or_since', ctypes.c_ulong),
('idle', ctypes.c_ulong),
('eventMask', ctypes.c_ulong)]
_fields_ = [
('window', ctypes.c_long),
('state', ctypes.c_int),
('kind', ctypes.c_int),
('til_or_since', ctypes.c_ulong),
('idle', ctypes.c_ulong),
('eventMask', ctypes.c_ulong),
]
class c_ptr(ctypes.c_void_p):
pass
def _ensureInitialized():
global xlib, xss, xssInfo, display, initialized # pylint: disable=global-statement
@ -73,13 +78,15 @@ def _ensureInitialized():
xss.XScreenSaverQueryExtension.argtypes = [
ctypes.c_void_p,
ctypes.POINTER(ctypes.c_int),
ctypes.POINTER(ctypes.c_int)
ctypes.POINTER(ctypes.c_int),
]
xss.XScreenSaverAllocInfo.restype = ctypes.POINTER(XScreenSaverInfo) # Result in a XScreenSaverInfo structure
xss.XScreenSaverAllocInfo.restype = ctypes.POINTER(
XScreenSaverInfo
) # Result in a XScreenSaverInfo structure
xss.XScreenSaverQueryInfo.argtypes = [
ctypes.c_void_p,
ctypes.c_void_p,
ctypes.POINTER(XScreenSaverInfo)
ctypes.POINTER(XScreenSaverInfo),
]
xlib.XOpenDisplay.argtypes = [ctypes.c_char_p]
xlib.XOpenDisplay.restype = c_ptr
@ -95,7 +102,9 @@ def _ensureInitialized():
event_base = ctypes.c_int()
error_base = ctypes.c_int()
available = xss.XScreenSaverQueryExtension(display, ctypes.byref(event_base), ctypes.byref(error_base))
available = xss.XScreenSaverQueryExtension(
display, ctypes.byref(event_base), ctypes.byref(error_base)
)
if available != 1:
raise Exception('ScreenSaver not available')
@ -107,9 +116,11 @@ def _ensureInitialized():
def initIdleDuration(atLeastSeconds: int) -> None:
_ensureInitialized()
if atLeastSeconds:
subprocess.call(['/usr/bin/xset', 's', '{}'.format(atLeastSeconds + 30)])
subprocess.call( # nosec, controlled params
['/usr/bin/xset', 's', '{}'.format(atLeastSeconds + 30)]
)
# And now reset it
subprocess.call(['/usr/bin/xset', 's', 'reset'])
subprocess.call(['/usr/bin/xset', 's', 'reset']) # nosec: fixed command
def getIdleDuration() -> float:
@ -122,7 +133,11 @@ def getIdleDuration() -> float:
xss.XScreenSaverQueryInfo(display, xlib.XDefaultRootWindow(display), xssInfo)
# States: 0 = off, 1 = On, 2 = Cycle, 3 = Disabled, ...?
if xssInfo.contents.state == 1: # state = 1 means "active", so idle is not a valid state
return 3600 * 100 * 1000 # If screen saver is active, return a high enough value
if (
xssInfo.contents.state == 1
): # state = 1 means "active", so idle is not a valid state
return (
3600 * 100 * 1000
) # If screen saver is active, return a high enough value
return xssInfo.contents.idle / 1000.0

View File

@ -35,6 +35,8 @@ import typing
if sys.platform == 'win32':
from .windows.log import LocalLogger
elif sys.platform == 'darwin':
from .macos.log import LocalLogger
else:
from .linux.log import LocalLogger
@ -55,7 +57,7 @@ class Logger:
self.logLevel = INFO
self.localLogger = LocalLogger()
self.remoteLogger = None
self.own_token = ''
self.own_token = '' # nosec: This is no password at all
def setLevel(self, level: typing.Union[str, int]) -> None:
'''

View File

@ -0,0 +1,31 @@
# -*- coding: utf-8 -*-
#
# Copyright (c) 2022 Virtual Cable S.L.U.
# 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.U. 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
'''

View File

@ -1,6 +1,6 @@
# -*- coding: utf-8 -*-
#
# Copyright (c) 2014 Virtual Cable S.L.
# Copyright (c) 2022 Virtual Cable S.L.U.
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without modification,
@ -11,7 +11,7 @@
# * 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
# * Neither the name of Virtual Cable S.L.U. nor the names of its contributors
# may be used to endorse or promote products derived from this software
# without specific prior written permission.
#
@ -25,29 +25,27 @@
# 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
Author: Adolfo Gómez, dkmaster at dkmon dot com
'''
from __future__ import unicode_literals
import logging
# pylint: disable=invalid-name
import os
import tempfile
import six
import logging
import typing
# Valid logging levels, from UDS Broker (uds.core.utils.log)
OTHER, DEBUG, INFO, WARN, ERROR, FATAL = (10000 * (x + 1) for x in six.moves.xrange(6)) # @UndefinedVariable
# Basically, same logger as in linux,
class LocalLogger:
linux = False
windows = False
serviceLogger = False
logger: typing.Optional[logging.Logger]
class LocalLogger(object):
def __init__(self):
# tempdir is different for "user application" and "service"
# service wil get c:\windows\temp, while user will get c:\users\XXX\temp
def __init__(self) -> None:
# Try to open logger at /var/log path
# If it fails (access denied normally), will try to open one at user's home folder, and if
# agaim it fails, open it at the tmpPath
for logDir in ('/var/log', os.path.expanduser('~'), tempfile.gettempdir()):
try:
fname = os.path.join(logDir, 'udsactor.log')
@ -60,21 +58,17 @@ class LocalLogger(object):
self.logger = logging.getLogger('udsactor')
os.chmod(fname, 0o0600)
return
except Exception:
except Exception: # nosec: B110: we don't care about exceptions here
# ignore and try next one
pass
# Logger can't be set
self.logger = None
def log(self, level, message):
def log(self, level: int, message: str) -> None:
# Debug messages are logged to a file
# our loglevels are 10000 (other), 20000 (debug), ....
# our loglevels are 0 (other), 10000 (debug), ....
# logging levels are 10 (debug), 20 (info)
# OTHER = logging.NOTSET
self.logger.log(int(level / 1000) - 10, message)
def isWindows(self):
return False
def isLinux(self):
return True
if self.logger:
self.logger.log(int(level / 1000), message)

View File

@ -0,0 +1,185 @@
# -*- coding: utf-8 -*-
#
# Copyright (c) 2022 Virtual Cable S.L.U.
# 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.U. 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
'''
# Note. most methods are not implemented, as they are not needed for this platform (macos)
# that only supports unmanaged machines
import socket
import os
import re
import subprocess # nosec
import typing
import psutil
from udsactor import types, tools
MACVER_RE = re.compile(
r"<key>ProductVersion</key>\s*<string>(.*)</string>", re.MULTILINE
)
MACVER_FILE = '/System/Library/CoreServices/SystemVersion.plist'
def checkPermissions() -> bool:
return os.getuid() == 0
def getComputerName() -> str:
'''
Returns computer name, with no domain
'''
return socket.gethostname().split('.')[0]
def getNetworkInfo() -> typing.Iterator[types.InterfaceInfoType]:
ifdata: typing.List['psutil._common.snicaddr']
for ifname, ifdata in psutil.net_if_addrs().items():
name, ip, mac = '', '', ''
# Get IP address, interface name and MAC address whenever possible
for row in ifdata:
if row.family == socket.AF_INET:
ip = row.address
name = ifname
elif row.family == socket.AF_LINK:
mac = row.address
# if all data is available, stop iterating
if ip and name and mac:
if (
mac != '00:00:00:00:00:00'
and mac
and ip
and ip.startswith('169.254') is False
): # Skips local interfaces & interfaces with no dhcp IPs
yield types.InterfaceInfoType(name=name, ip=ip, mac=mac)
break
def getDomainName() -> str:
return ''
def getMacOs() -> str:
try:
with open(MACVER_FILE, 'r') as f:
data = f.read()
m = MACVER_RE.search(data)
if m:
return m.group(1)
except Exception: # nosec: B110: ignore exception because we are not interested in it
pass
return 'unknown'
def getVersion() -> str:
return 'MacOS ' + getMacOs()
def reboot(flags: int = 0) -> None:
'''
Simple reboot using os command
'''
subprocess.call(['/sbin/shutdown', '-r', 'now']) # nosec: Command line is fixed
def loggoff() -> None:
'''
Right now restarts the machine...
'''
subprocess.run(
"/bin/launchctl bootout gui/$(id -u $USER)", shell=True
) # nosec: Command line is fixed
# Ignores output, as it may fail if user is not logged in
def renameComputer(newName: str) -> bool:
'''
Changes the computer name
Returns True if reboot needed
Note: For macOS, no configuration is supported, only "unmanaged" actor
'''
return False
def joinDomain(
domain: str, ou: str, account: str, password: str, executeInOneStep: bool = False
):
pass
def changeUserPassword(user: str, oldPassword: str, newPassword: str) -> None:
pass
def initIdleDuration(atLeastSeconds: int) -> None:
pass
# se we cache for 20 seconds the result, that is enough for our needs
# and we avoid calling a system command every time we need it
@tools.cache(20)
def getIdleDuration() -> float:
# Execute:
try:
return (
int(
next(
filter(
lambda x: b"HIDIdleTime" in x,
subprocess.check_output(
["/usr/sbin/ioreg", "-c", "IOHIDSystem"]
).split(b"\n"),
)
).split(b"=")[1]
)
/ 1000000000
) # nosec: Command line is fixed
except Exception: # nosec: B110: ignore exception because we are not interested in it
return 0
def getCurrentUser() -> str:
'''
Returns current logged in user
'''
return os.getlogin()
def getSessionType() -> str:
'''
Returns the session type. Currently, only "macos" (console) is supported
'''
return 'macos'
def forceTimeSync() -> None:
return

View File

@ -1,6 +1,6 @@
# -*- coding: utf-8 -*-
#
# Copyright (c) 2014 Virtual Cable S.L.
# Copyright (c) 2022 Virtual Cable S.L.U.
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without modification,
@ -25,48 +25,47 @@
# 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
Author: Adolfo Gómez, dkmaster at dkmon dot com
'''
from __future__ import unicode_literals
import sys
import six
import typing
if sys.platform == 'win32':
_fromEncoding = 'windows-1250'
else:
_fromEncoding = 'utf-8'
from .. import rest
from .. import platform
from ..log import logger
from .service import UDSActorSvc
def usage() -> typing.NoReturn:
sys.stderr.write('usage: udsactor start|login "username"|logout "username"\n')
sys.exit(2)
def toUnicode(msg):
try:
if not isinstance(msg, six.text_type):
if isinstance(msg, six.binary_type):
return msg.decode(_fromEncoding, 'ignore')
return six.text_type(msg)
else:
return msg
except Exception:
def run() -> None:
logger.setLevel(20000)
if len(sys.argv) == 3 and sys.argv[1] in ('login', 'logout'):
logger.debug('Running client udsactor')
try:
return six.text_type(msg)
except Exception:
return ''
client: rest.UDSClientApi = rest.UDSClientApi()
if sys.argv[1] == 'login':
r = client.login(sys.argv[2], platform.operations.getSessionType())
print('{},{},{},{}\n'.format(r.ip, r.hostname, r.max_idle, r.dead_line or ''))
elif sys.argv[1] == 'logout':
client.logout(sys.argv[2], platform.operations.getSessionType())
except Exception as e:
logger.exception()
logger.error('Got exception while processing command: %s', e)
sys.exit(0)
elif len(sys.argv) != 2:
usage()
def exceptionToMessage(e):
msg = ''
for arg in e.args:
if isinstance(arg, Exception):
msg = msg + exceptionToMessage(arg)
daemonSvr = UDSActorSvc()
if len(sys.argv) == 2:
# Daemon mode...
if sys.argv[1] in ('start', 'start-foreground'):
daemonSvr.run() # execute in foreground
else:
msg = msg + toUnicode(arg) + '. '
return msg
class Bunch(dict):
def __init__(self, **kw):
dict.__init__(self, kw)
self.__dict__ = self
usage()
sys.exit(0)
else:
usage()

View File

@ -0,0 +1,108 @@
# -*- coding: utf-8 -*-
#
# Copyright (c) 2022 Virtual Cable S.L.U.
# 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.U. 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
'''
import typing
import signal
from ..log import logger
from ..service import CommonService
class UDSActorSvc(CommonService):
def __init__(self) -> None:
CommonService.__init__(self)
# Captures signals so we can stop gracefully
signal.signal(signal.SIGINT, self.markForExit)
signal.signal(signal.SIGTERM, self.markForExit)
def markForExit(self, signum, frame) -> None: # pylint: disable=unused-argument
self._isAlive = False
def joinDomain( # pylint: disable=unused-argument, too-many-arguments
self,
name: str,
domain: str,
ou: str,
account: str,
password: str
) -> None:
pass # Not implemented for unmanaged machines
def rename(
self,
name: str,
userName: typing.Optional[str] = None,
oldPassword: typing.Optional[str] = None,
newPassword: typing.Optional[str] = None,
) -> None:
pass # Not implemented for unmanaged machines
def run(self) -> None:
logger.debug('Running Daemon: {}'.format(self._isAlive))
# Linux daemon will continue running unless something is requested to
# Unmanaged services does not initializes "on start", but rather when user logs in (because userservice does not exists "as such" before that)
if self.isManaged(): # Currently, managed is not implemented for UDS on M
logger.error('Managed machines not supported on MacOS')
# Wait a bit, this is mac os and will be run by launchd
# If the daemon shuts down too quickly, launchd may think it is a crash.
self.doWait(10000)
self.finish()
return # Stop daemon if initializes told to do so
if not self.initializeUnmanaged():
# Wait a bit, this is mac os and will be run by launchd
# If the daemon shuts down too quickly, launchd may think it is a crash.
self.doWait(10000)
self.finish()
return
# Start listening for petitions
self.startHttpServer()
# *********************
# * Main Service loop *
# *********************
# Counter used to check ip changes only once every 10 seconds, for
# example
counter = 0
while self._isAlive:
counter += 1
try:
if counter % 5 == 0:
self.loop()
except Exception as e:
logger.error('Got exception on main loop: %s', e)
# In milliseconds, will break
self.doWait(1000)
self.finish()

View File

@ -0,0 +1,106 @@
# -*- coding: utf-8 -*-
#
# Copyright (c) 2022 Virtual Cable S.L.U.
# 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.U. 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
'''
import os
import configparser
import base64
import pickle # nosec
from .. import types
CONFIGFILE = '/etc/udsactor/udsactor.cfg'
def readConfig() -> types.ActorConfigurationType:
try:
cfg = configparser.ConfigParser()
cfg.read(CONFIGFILE)
uds: configparser.SectionProxy = cfg['uds']
# Extract data:
base64Config = uds.get('config', None)
config = pickle.loads(base64.b64decode(base64Config.encode())) if base64Config else None # nosec: Read from root controled file, secure
base64Data = uds.get('data', None)
data = pickle.loads(base64.b64decode(base64Data.encode())) if base64Data else None # nosec: Read from root controled file, secure
return types.ActorConfigurationType(
actorType=uds.get('type', types.MANAGED),
host=uds.get('host', ''),
validateCertificate=uds.getboolean('validate', fallback=False),
master_token=uds.get('master_token', None),
own_token=uds.get('own_token', None),
restrict_net=uds.get('restrict_net', None),
pre_command=uds.get('pre_command', None),
runonce_command=uds.get('runonce_command', None),
post_command=uds.get('post_command', None),
log_level=int(uds.get('log_level', '2')),
config=config,
data=data
)
except Exception:
return types.ActorConfigurationType('', False)
def writeConfig(config: types.ActorConfigurationType) -> None:
cfg = configparser.ConfigParser()
cfg.add_section('uds')
uds: configparser.SectionProxy = cfg['uds']
uds['host'] = config.host
uds['validate'] = 'yes' if config.validateCertificate else 'no'
def writeIfValue(val, name):
if val:
uds[name] = val
writeIfValue(config.actorType, 'type')
writeIfValue(config.master_token, 'master_token')
writeIfValue(config.own_token, 'own_token')
writeIfValue(config.restrict_net, 'restrict_net')
writeIfValue(config.pre_command, 'pre_command')
writeIfValue(config.post_command, 'post_command')
writeIfValue(config.runonce_command, 'runonce_command')
uds['log_level'] = str(config.log_level)
if config.config: # Special case, encoded & dumped
uds['config'] = base64.b64encode(pickle.dumps(config.config)).decode()
if config.data: # Special case, encoded & dumped
uds['data'] = base64.b64encode(pickle.dumps(config.data)).decode()
# Ensures exists destination folder
dirname = os.path.dirname(CONFIGFILE)
if not os.path.exists(dirname):
os.mkdir(dirname, mode=0o700) # Will create only if route to path already exists, for example, /etc (that must... :-))
with open(CONFIGFILE, 'w') as f:
cfg.write(f)
os.chmod(CONFIGFILE, 0o0600) # Ensure only readable by root
def useOldJoinSystem() -> bool:
return False
def invokeScriptOnLogin() -> str:
return ''

View File

@ -1,6 +1,6 @@
# -*- coding: utf-8 -*-
#
# Copyright (c) 2014 Virtual Cable S.L.
# Copyright (c) 2014-2022 Virtual Cable S.L.U.
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without modification,
@ -11,7 +11,7 @@
# * 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
# * Neither the name of Virtual Cable S.L.U. nor the names of its contributors
# may be used to endorse or promote products derived from this software
# without specific prior written permission.
#
@ -31,7 +31,15 @@
import sys
name = sys.platform
is_windows = is_linux = is_mac = False
if sys.platform == 'win32':
from .windows import operations, store # pylint: disable=unused-import
from .windows import operations, store, runner
is_windows = True
elif sys.platform == 'darwin':
from .macos import operations, store, runner
is_mac = True
elif sys.platform == 'linux':
from .linux import operations, store, runner
is_linux = True
else:
from .linux import operations, store # pylint: disable=unused-import
raise Exception('Unsupported platform: {0}'.format(sys.platform))

View File

@ -36,42 +36,52 @@ import typing
import requests
from . import types
from .info import VERSION
from udsactor import types, tools
from udsactor.version import VERSION, BUILD
# Default public listen port
LISTEN_PORT = 43910
# Default timeout
TIMEOUT = 5 # 5 seconds is more than enought
TIMEOUT = 5 # 5 seconds is more than enought
# Constants
UNKNOWN = 'unknown'
class RESTError(Exception):
ERRCODE = 0
class RESTConnectionError(RESTError):
ERRCODE = -1
# Errors ""raised"" from broker
class RESTInvalidKeyError(RESTError):
ERRCODE = 1
class RESTUnmanagedHostError(RESTError):
ERRCODE = 2
class RESTUserServiceNotFoundError(RESTError):
ERRCODE = 3
class RESTOsManagerError(RESTError):
ERRCODE = 4
# For avoid proxy on localhost connections
NO_PROXY = {
'http': None,
'https': None,
}
UDS_BASE_URL = 'https://{}/uds/rest/'
#
# Basic UDS Api
#
@ -79,48 +89,51 @@ class UDSApi: # pylint: disable=too-few-public-methods
"""
Base for remote api accesses
"""
_host: str
_validateCert: bool
_url: str
_host: str = ''
_validateCert: bool = True
_url: str = ''
def __init__(self, host: str, validateCert: bool) -> None:
self._host = host
self._validateCert = validateCert
self._url = "https://{}/uds/rest/".format(self._host)
self._url = UDS_BASE_URL.format(self._host)
# Disable logging requests messages except for errors, ...
logging.getLogger("requests").setLevel(logging.CRITICAL)
logging.getLogger("urllib3").setLevel(logging.ERROR)
logging.getLogger('request').setLevel(logging.CRITICAL)
logging.getLogger('urllib3').setLevel(logging.ERROR)
try:
warnings.simplefilter("ignore") # Disables all warnings
except Exception:
warnings.simplefilter('ignore') # Disables all warnings
except Exception: # nosec: not interested in exceptions
pass
@property
def _headers(self) -> typing.MutableMapping[str, str]:
return {
'Content-Type': 'application/json',
'User-Agent': 'UDS Actor v{}'.format(VERSION)
'User-Agent': 'UDS Actor v{}/{}'.format(VERSION, BUILD),
}
def _apiURL(self, method: str) -> str:
def _api_url(self, method: str) -> str:
raise NotImplementedError
def _doPost(
self,
method: str, # i.e. 'initialize', 'ready', ....
payLoad: typing.MutableMapping[str, typing.Any],
headers: typing.Optional[typing.MutableMapping[str, str]] = None,
disableProxy: bool = False
) -> typing.Any:
self,
method: str, # i.e. 'initialize', 'ready', ....
payLoad: typing.MutableMapping[str, typing.Any],
headers: typing.Optional[typing.MutableMapping[str, str]] = None,
disableProxy: bool = False,
) -> typing.Any:
headers = headers or self._headers
try:
result = requests.post(
self._apiURL(method),
self._api_url(method),
data=json.dumps(payLoad),
headers=headers,
verify=self._validateCert,
timeout=TIMEOUT,
proxies=NO_PROXY if disableProxy else None # if not proxies wanted, enforce it
proxies=NO_PROXY # type: ignore
if disableProxy
else None, # if not proxies wanted, enforce it
)
if result.ok:
@ -139,16 +152,22 @@ class UDSApi: # pylint: disable=too-few-public-methods
raise RESTError(data)
#
# UDS Broker API access
#
class UDSServerApi(UDSApi):
def _apiURL(self, method: str) -> str:
def _api_url(self, method: str) -> str:
return self._url + 'actor/v3/' + method
def enumerateAuthenticators(self) -> typing.Iterable[types.AuthenticatorType]:
try:
result = requests.get(self._url + 'auth/auths', headers=self._headers, verify=self._validateCert, timeout=4)
result = requests.get(
self._url + 'auth/auths',
headers=self._headers,
verify=self._validateCert,
timeout=4,
)
if result.ok:
for v in sorted(result.json(), key=lambda x: x['priority']):
yield types.AuthenticatorType(
@ -157,24 +176,24 @@ class UDSServerApi(UDSApi):
auth=v['auth'],
type=v['type'],
priority=v['priority'],
isCustom=v['isCustom']
isCustom=v['isCustom'],
)
except Exception:
except Exception: # nosec: not interested in exceptions
pass
def register( #pylint: disable=too-many-arguments, too-many-locals
self,
auth: str,
username: str,
password: str,
hostname: str,
ip: str,
mac: str,
preCommand: str,
runOnceCommand: str,
postCommand: str,
logLevel: int
) -> str:
def register(
self,
auth: str,
username: str,
password: str,
hostname: str,
ip: str,
mac: str,
preCommand: str,
runOnceCommand: str,
postCommand: str,
logLevel: int,
) -> str:
"""
Raises an exception if could not register, or registers and returns the "authorization token"
"""
@ -186,7 +205,7 @@ class UDSServerApi(UDSApi):
'pre_command': preCommand,
'run_once_command': runOnceCommand,
'post_command': postCommand,
'log_level': logLevel
'log_level': logLevel,
}
# First, try to login to REST api
@ -194,13 +213,23 @@ class UDSServerApi(UDSApi):
# First, try to login
authInfo = {'auth': auth, 'username': username, 'password': password}
headers = self._headers
result = requests.post(self._url + 'auth/login', data=json.dumps(authInfo), headers=headers, verify=self._validateCert)
result = requests.post(
self._url + 'auth/login',
data=json.dumps(authInfo),
headers=headers,
verify=self._validateCert,
)
if not result.ok or result.json()['result'] == 'error':
raise Exception() # Invalid credentials
headers['X-Auth-Token'] = result.json()['token']
result = requests.post(self._apiURL('register'), data=json.dumps(data), headers=headers, verify=self._validateCert)
result = requests.post(
self._api_url('register'),
data=json.dumps(data),
headers=headers,
verify=self._validateCert,
)
if result.ok:
return result.json()['result']
except requests.ConnectionError as e:
@ -212,13 +241,19 @@ class UDSServerApi(UDSApi):
raise RESTError(result.content.decode())
def initialize(self, token: str, interfaces: typing.Iterable[types.InterfaceInfoType], actorType: typing.Optional[str]) -> types.InitializationResultType:
def initialize(
self,
token: str,
interfaces: typing.Iterable[types.InterfaceInfoType],
actor_type: typing.Optional[str],
) -> types.InitializationResultType:
# Generate id list from netork cards
payload = {
'type': actorType or types.MANAGED,
'type': actor_type or types.MANAGED,
'token': token,
'version': VERSION,
'id': [{'mac': i.mac, 'ip': i.ip} for i in interfaces]
'build': BUILD,
'id': [{'mac': i.mac, 'ip': i.ip} for i in interfaces],
}
r = self._doPost('initialize', payload)
os = r['os']
@ -232,95 +267,115 @@ class UDSServerApi(UDSApi):
password=os.get('password'),
new_password=os.get('new_password'),
ad=os.get('ad'),
ou=os.get('ou')
) if r['os'] else None
ou=os.get('ou'),
)
if r['os']
else None,
alias_token=r.get('alias_token'), # Possible alias for unmanaged
)
def ready(self, own_token: str, secret: str, ip: str, port: int) -> types.CertificateInfoType:
payload = {
'token': own_token,
'secret': secret,
'ip': ip,
'port': port
}
def ready(
self, own_token: str, secret: str, ip: str, port: int
) -> types.CertificateInfoType:
payload = {'token': own_token, 'secret': secret, 'ip': ip, 'port': port}
result = self._doPost('ready', payload)
return types.CertificateInfoType(
private_key=result['private_key'],
server_certificate=result['server_certificate'],
password=result['password']
password=result['password'],
)
def notifyIpChange(self, own_token: str, secret: str, ip: str, port: int) -> types.CertificateInfoType:
payload = {
'token': own_token,
'secret': secret,
'ip': ip,
'port': port
}
def notifyIpChange(
self, own_token: str, secret: str, ip: str, port: int
) -> types.CertificateInfoType:
payload = {'token': own_token, 'secret': secret, 'ip': ip, 'port': port}
result = self._doPost('ipchange', payload)
return types.CertificateInfoType(
private_key=result['private_key'],
server_certificate=result['server_certificate'],
password=result['password']
password=result['password'],
)
def notifyUnmanagedCallback(self, master_token: str, secret: str, interfaces: typing.Iterable[types.InterfaceInfoType], port: int) -> types.CertificateInfoType:
def notifyUnmanagedCallback(
self,
master_token: str,
secret: str,
interfaces: typing.Iterable[types.InterfaceInfoType],
port: int,
) -> types.CertificateInfoType:
payload = {
'id': [{'mac': i.mac, 'ip': i.ip} for i in interfaces],
'token': master_token,
'secret': secret,
'port': port
'port': port,
}
result = self._doPost('unmanaged', payload)
return types.CertificateInfoType(
private_key=result['private_key'],
server_certificate=result['server_certificate'],
password=result['password']
password=result['password'],
)
def login(self, own_token: str, username: str, sessionType: typing.Optional[str] = None) -> types.LoginResultInfoType:
if not own_token:
def login(
self,
actor_type: typing.Optional[str],
token: str,
username: str,
session_type: str,
interfaces: typing.Iterable[types.InterfaceInfoType],
secret: typing.Optional[str],
) -> types.LoginResultInfoType:
if not token:
return types.LoginResultInfoType(
ip='0.0.0.0',
hostname=UNKNOWN,
dead_line=None,
max_idle=None
ip='0.0.0.0', hostname=UNKNOWN, dead_line=None, max_idle=None, session_id=None
)
payload = {
'token': own_token,
'type': actor_type or types.MANAGED,
'id': [{'mac': i.mac, 'ip': i.ip} for i in interfaces],
'token': token,
'username': username,
'session_type': sessionType or UNKNOWN
'session_type': session_type,
'secret': secret or '',
}
result = self._doPost('login', payload)
return types.LoginResultInfoType(
ip=result['ip'],
hostname=result['hostname'],
dead_line=result['dead_line'],
max_idle=result['max_idle']
max_idle=result['max_idle'],
session_id=result.get('session_id', ''),
)
def logout(self, own_token: str, username: str) -> None:
if not own_token:
return
def logout(
self,
actor_type: typing.Optional[str],
token: str,
username: str,
session_id: str,
session_type: str,
interfaces: typing.Iterable[types.InterfaceInfoType],
secret: typing.Optional[str],
) -> typing.Optional[str]:
if not token:
return None
payload = {
'token': own_token,
'username': username
'type': actor_type or types.MANAGED,
'id': [{'mac': i.mac, 'ip': i.ip} for i in interfaces],
'token': token,
'username': username,
'session_type': session_type,
'session_id': session_id,
'secret': secret or '',
}
self._doPost('logout', payload)
return self._doPost('logout', payload) # Can be 'ok' or 'notified'
def log(self, own_token: str, level: int, message: str) -> None:
if not own_token:
return
payLoad = {
'token': own_token,
'level': level,
'message': message
}
payLoad = {'token': own_token, 'level': level, 'message': message}
self._doPost('log', payLoad) # Ignores result...
def test(self, master_token: str, actorType: typing.Optional[str]) -> bool:
@ -331,50 +386,62 @@ class UDSServerApi(UDSApi):
return self._doPost('test', payLoad) == 'ok'
class UDSClientApi(UDSApi):
class UDSClientApi(UDSApi, metaclass=tools.Singleton):
_session_id: str = ''
_callback_url: str = ''
def __init__(self) -> None:
super().__init__('127.0.0.1:{}'.format(LISTEN_PORT), False)
# Override base url
# Replace base url
self._url = "https://{}/ui/".format(self._host)
def _apiURL(self, method: str) -> str:
def _api_url(self, method: str) -> str:
return self._url + method
def post(
self,
method: str, # i.e. 'initialize', 'ready', ....
payLoad: typing.MutableMapping[str, typing.Any]
) -> typing.Any:
self,
method: str, # i.e. 'initialize', 'ready', ....
payLoad: typing.MutableMapping[str, typing.Any],
) -> typing.Any:
return self._doPost(method=method, payLoad=payLoad, disableProxy=True)
def register(self, callbackUrl: str) -> None:
payLoad = {
'callback_url': callbackUrl
}
def register(self, callback_url: str) -> None:
self._callback_url = callback_url
payLoad = {'callback_url': callback_url}
self.post('register', payLoad)
def unregister(self, callbackUrl: str) -> None:
payLoad = {
'callback_url': callbackUrl
}
def unregister(self, callback_url: str) -> None:
payLoad = {'callback_url': callback_url}
self.post('unregister', payLoad)
self._callback_url = ''
def login(self, username: str, sessionType: typing.Optional[str] = None) -> types.LoginResultInfoType:
def login(
self, username: str, sessionType: typing.Optional[str] = None
) -> types.LoginResultInfoType:
payLoad = {
'username': username,
'session_type': sessionType or UNKNOWN,
'callback_url': self._callback_url, # So we identify ourselves
}
result = self.post('login', payLoad)
return types.LoginResultInfoType(
res = types.LoginResultInfoType(
ip=result['ip'],
hostname=result['hostname'],
dead_line=result['dead_line'],
max_idle=result['max_idle']
max_idle=result['max_idle'],
session_id=result['session_id'],
)
# Store session id for future use
self._session_id = res.session_id or ''
return res
def logout(self, username: str) -> None:
def logout(self, username: str, sessionType: typing.Optional[str]) -> None:
payLoad = {
'username': username
'username': username,
'session_type': sessionType or UNKNOWN,
'callback_url': self._callback_url, # So we identify ourselves
'session_id': self._session_id, # We now know the session id, provided on login
}
self.post('logout', payLoad)

View File

@ -36,12 +36,13 @@ import secrets
import subprocess
import typing
from . import platform
from . import rest
from . import types
from udsactor import platform
from udsactor import rest
from udsactor import types
from udsactor import tools
from .log import logger, DEBUG, INFO, ERROR, FATAL
from .http import clients_pool, server, cert
from udsactor.log import logger, DEBUG, INFO, ERROR, FATAL
from udsactor.http import clients_pool, server, cert
# def setup() -> None:
# cfg = platform.store.readConfig()
@ -55,18 +56,16 @@ from .http import clients_pool, server, cert
# else:
# logger.setLevel(20000)
class CommonService: # pylint: disable=too-many-instance-attributes
_isAlive: bool = True
_rebootRequested: bool = False
_loggedIn: bool = False
_initialized: bool = False
_cfg: types.ActorConfigurationType
_api: rest.UDSServerApi
_interfaces: typing.List[types.InterfaceInfoType]
_secret: str
_certificate: types.CertificateInfoType
_clientsPool: clients_pool.UDSActorClientPool
_http: typing.Optional[server.HTTPServerThread]
@staticmethod
@ -75,7 +74,9 @@ class CommonService: # pylint: disable=too-many-instance-attributes
logger.debug('Executing command on {}: {}'.format(section, cmdLine))
res = subprocess.check_call(cmdLine, shell=True)
except Exception as e:
logger.error('Got exception executing: {} - {} - {}'.format(section, cmdLine, e))
logger.error(
'Got exception executing: {} - {} - {}'.format(section, cmdLine, e)
)
return False
logger.debug('Result of executing cmd for {} was {}'.format(section, res))
return True
@ -86,7 +87,9 @@ class CommonService: # pylint: disable=too-many-instance-attributes
self._api = rest.UDSServerApi(self._cfg.host, self._cfg.validateCertificate)
self._secret = secrets.token_urlsafe(33)
self._clientsPool = clients_pool.UDSActorClientPool()
self._certificate = cert.defaultCertificate # For being used on "unmanaged" hosts only
self._certificate = (
cert.defaultCertificate
) # For being used on "unmanaged" hosts only
self._http = None
# Initialzies loglevel and serviceLogger
@ -95,7 +98,7 @@ class CommonService: # pylint: disable=too-many-instance-attributes
# 0 = OTHER, 10000 = DEBUG, 20000 = WARN, 30000 = INFO, 40000 = ERROR, 50000 = FATAL
# So this comes:
logger.setLevel([DEBUG, INFO, ERROR, FATAL][self._cfg.log_level])
# If windows, enable service logger
# If windows, enable service logger FOR SERVICE only
logger.enableServiceLogger()
socket.setdefaulttimeout(20)
@ -112,16 +115,24 @@ class CommonService: # pylint: disable=too-many-instance-attributes
self._http.start()
def isManaged(self) -> bool:
return self._cfg.actorType != types.UNMANAGED # Only "unmanaged" hosts are unmanaged, the rest are "managed"
return (
self._cfg.actorType != types.UNMANAGED
) # Only "unmanaged" hosts are unmanaged, the rest are "managed"
def serviceInterfaceInfo(self, interfaces: typing.Optional[typing.List[types.InterfaceInfoType]] = None) -> typing.Optional[types.InterfaceInfoType]:
def serviceInterfaceInfo(
self, interfaces: typing.Optional[typing.List[types.InterfaceInfoType]] = None
) -> typing.Optional[types.InterfaceInfoType]:
"""
returns the inteface with unique_id mac or first interface or None if no interfaces...
"""
interfaces = interfaces or self._interfaces # Emty interfaces is like "no ip change" because cannot be notified
interfaces = (
interfaces or self._interfaces
) # Emty interfaces is like "no ip change" because cannot be notified
if self._cfg.config and interfaces:
try:
return next(x for x in interfaces if x.mac.lower() == self._cfg.config.unique_id)
return next(
x for x in interfaces if x.mac.lower() == self._cfg.config.unique_id
)
except StopIteration:
return interfaces[0]
@ -152,7 +163,12 @@ class CommonService: # pylint: disable=too-many-instance-attributes
while self._isAlive:
counter -= 1
try:
self._certificate = self._api.ready(self._cfg.own_token, self._secret, srvInterface.ip, rest.LISTEN_PORT)
self._certificate = self._api.ready(
self._cfg.own_token,
self._secret,
srvInterface.ip,
rest.LISTEN_PORT,
)
except rest.RESTConnectionError as e:
if not logged: # Only log connection problems ONCE
logged = True
@ -168,7 +184,9 @@ class CommonService: # pylint: disable=too-many-instance-attributes
# Success or any error that is not recoverable (retunerd by UDS). if Error, service will be cleaned in a while.
break
else:
logger.error('Could not locate IP address!!!. (Not registered with UDS)')
logger.error(
'Could not locate IP address!!!. (Not registered with UDS)'
)
# Do not continue if not alive...
if not self._isAlive:
@ -176,7 +194,9 @@ class CommonService: # pylint: disable=too-many-instance-attributes
# Cleans sensible data
if self._cfg.config:
self._cfg = self._cfg._replace(config=self._cfg.config._replace(os=None), data=None)
self._cfg = self._cfg._replace(
config=self._cfg.config._replace(os=None), data=None
)
platform.store.writeConfig(self._cfg)
logger.info('Service ready')
@ -195,10 +215,10 @@ class CommonService: # pylint: disable=too-many-instance-attributes
self._cfg = self._cfg._replace(runonce_command=None)
platform.store.writeConfig(self._cfg)
if self.execute(runOnce, "runOnce"):
# If runonce is present, will not do anythin more
# So we have to ensure that, when runonce command is finished, reboots the machine.
# That is, the COMMAND itself has to restart the machine!
return False # If the command fails, continue with the rest of the operations...
# If runonce is present, will not do anythin more
# So we have to ensure that, when runonce command is finished, reboots the machine.
# That is, the COMMAND itself has to restart the machine!
return False # If the command fails, continue with the rest of the operations...
# Retry configuration while not stop service, config in case of error 10 times, reboot vm
counter = 10
@ -208,9 +228,20 @@ class CommonService: # pylint: disable=too-many-instance-attributes
if self._cfg.config and self._cfg.config.os:
osData = self._cfg.config.os
if osData.action == 'rename':
self.rename(osData.name, osData.username, osData.password, osData.new_password)
self.rename(
osData.name,
osData.username,
osData.password,
osData.new_password,
)
elif osData.action == 'rename_ad':
self.joinDomain(osData.name, osData.ad or '', osData.ou or '', osData.username or '', osData.password or '')
self.joinDomain(
osData.name,
osData.ad or '',
osData.ou or '',
osData.username or '',
osData.password or '',
)
if self._rebootRequested:
try:
@ -234,7 +265,12 @@ class CommonService: # pylint: disable=too-many-instance-attributes
self.getInterfaces() # Ensure we have interfaces
if self._cfg.master_token:
try:
self._certificate = self._api.notifyUnmanagedCallback(self._cfg.master_token, self._secret, self._interfaces, rest.LISTEN_PORT)
self._certificate = self._api.notifyUnmanagedCallback(
self._cfg.master_token,
self._secret,
self._interfaces,
rest.LISTEN_PORT,
)
except Exception as e:
logger.error('Couuld not notify unmanaged callback: %s', e)
@ -245,13 +281,17 @@ class CommonService: # pylint: disable=too-many-instance-attributes
return
while self._isAlive:
self._interfaces = list(platform.operations.getNetworkInfo())
self._interfaces = tools.validNetworkCards(
self._cfg.restrict_net, platform.operations.getNetworkInfo()
)
if self._interfaces:
break
self.doWait(5000)
def initialize(self) -> bool:
if self._initialized or not self._cfg.host or not self._isAlive: # Not configured or not running
if (
self._initialized or not self._cfg.host or not self._isAlive
): # Not configured or not running
return False
self._initialized = True
@ -268,25 +308,37 @@ class CommonService: # pylint: disable=too-many-instance-attributes
try:
# If master token is present, initialize and get configuration data
if self._cfg.master_token:
initResult: types.InitializationResultType = self._api.initialize(self._cfg.master_token, self._interfaces, self._cfg.actorType)
initResult: types.InitializationResultType = self._api.initialize(
self._cfg.master_token, self._interfaces, self._cfg.actorType
)
if not initResult.own_token: # Not managed
logger.debug('This host is not managed by UDS Broker (ids: {})'.format(self._interfaces))
logger.debug(
'This host is not managed by UDS Broker (ids: {})'.format(
self._interfaces
)
)
return False
# Only removes token for managed machines
master_token = None if self.isManaged() else self._cfg.master_token
# Only removes master token for managed machines (will need it on next client execution)
# For unmanaged, if alias is present, replace master token with it
master_token = (
None
if self.isManaged()
else (initResult.alias_token or self._cfg.master_token)
)
# Replace master token with alias token if present
self._cfg = self._cfg._replace(
master_token=master_token,
own_token=initResult.own_token,
config=types.ActorDataConfigurationType(
unique_id=initResult.unique_id,
os=initResult.os
)
unique_id=initResult.unique_id, os=initResult.os
),
)
# On first successfull initialization request, master token will dissapear for managed hosts so it will be no more available (not needed anyway)
if self.isManaged():
platform.store.writeConfig(self._cfg)
# On first successfull initialization request, master token will dissapear for managed hosts
# so it will be no more available (not needed anyway). For unmanaged, the master token will
# be replaced with an alias token.
platform.store.writeConfig(self._cfg)
# Setup logger now
if self._cfg.own_token:
@ -294,29 +346,51 @@ class CommonService: # pylint: disable=too-many-instance-attributes
break # Initial configuration done..
except rest.RESTConnectionError as e:
logger.info('Trying to inititialize connection with broker (last error: {})'.format(e))
logger.info(
'Trying to inititialize connection with broker (last error: {})'.format(
e
)
)
self.doWait(5000) # Wait a bit and retry
except rest.RESTError as e: # Invalid key?
logger.error('Error validating with broker. (Invalid token?): {}'.format(e))
except rest.RESTError as e: # Invalid key?
logger.error(
'Error validating with broker. (Invalid token?): {}'.format(e)
)
return False
except Exception:
logger.exception()
self.doWait(5000) # Wait a bit and retry...
return self.configureMachine()
def uninitialize(self):
self._initialized = False
self._cfg = self._cfg._replace(own_token=None) # Ensures assigned token is cleared
self._cfg = self._cfg._replace(
own_token=None
) # Ensures assigned token is cleared
def finish(self) -> None:
if self._http:
self._http.stop()
# If logged in, notify UDS of logout (daemon stoped = no control = logout)
if self._loggedIn and self._cfg.own_token:
self._loggedIn = False
try:
self._api.logout(self._cfg.own_token, '')
except Exception as e:
logger.error('Error notifying final logout to UDS: %s', e)
# For every connected client...
if self._cfg.own_token:
for client in clients_pool.UDSActorClientPool().clients:
if client.session_id:
try:
self._api.logout(
self._cfg.actorType,
self._cfg.own_token,
'',
client.session_id
or 'stop', # If no session id, pass "stop"
'',
self._interfaces,
self._secret,
)
except Exception as e:
logger.error('Error notifying final logout to UDS: %s', e)
self.notifyStop()
@ -325,19 +399,33 @@ class CommonService: # pylint: disable=too-many-instance-attributes
return # Unamanaged hosts does not changes ips. (The full initialize-login-logout process is done in a row, so at login the IP is correct)
try:
if not self._cfg.own_token or not self._cfg.config or not self._cfg.config.unique_id:
if (
not self._cfg.own_token
or not self._cfg.config
or not self._cfg.config.unique_id
):
# Not enouth data do check
return
currentInterfaces = list(platform.operations.getNetworkInfo())
currentInterfaces = tools.validNetworkCards(
self._cfg.restrict_net, platform.operations.getNetworkInfo()
)
old = self.serviceInterfaceInfo()
new = self.serviceInterfaceInfo(currentInterfaces)
if not new or not old:
raise Exception('No ip currently available for {}'.format(self._cfg.config.unique_id))
raise Exception(
'No ip currently available for {}'.format(
self._cfg.config.unique_id
)
)
if old.ip != new.ip:
self._certificate = self._api.notifyIpChange(self._cfg.own_token, self._secret, new.ip, rest.LISTEN_PORT)
self._certificate = self._api.notifyIpChange(
self._cfg.own_token, self._secret, new.ip, rest.LISTEN_PORT
)
# Now store new addresses & interfaces...
self._interfaces = currentInterfaces
logger.info('Ip changed from {} to {}. Notified to UDS'.format(old.ip, new.ip))
logger.info(
'Ip changed from {} to {}. Notified to UDS'.format(old.ip, new.ip)
)
# Stop the running HTTP Thread and start a new one, with new generated cert
self.startHttpServer()
except Exception as e:
@ -345,29 +433,34 @@ class CommonService: # pylint: disable=too-many-instance-attributes
logger.warn('Checking ips failed: {}'.format(e))
def rename(
self,
name: str,
userName: typing.Optional[str] = None,
oldPassword: typing.Optional[str] = None,
newPassword: typing.Optional[str] = None
) -> None:
self,
name: str,
userName: typing.Optional[str] = None,
oldPassword: typing.Optional[str] = None,
newPassword: typing.Optional[str] = None,
) -> None:
'''
Invoked when broker requests a rename action
default does nothing
'''
hostName = platform.operations.getComputerName()
if hostName.lower() == name.lower():
logger.info('Computer name is already {}'.format(hostName))
return
# Check for password change request for an user
if userName and newPassword:
logger.info('Setting password for configured user')
try:
platform.operations.changeUserPassword(userName, oldPassword or '', newPassword)
platform.operations.changeUserPassword(
userName, oldPassword or '', newPassword
)
except Exception as e:
raise Exception('Could not change password for user {} (maybe invalid current password is configured at broker): {} '.format(userName, str(e)))
# Logs error, but continue renaming computer
logger.error(
'Could not change password for user {}: {}'.format(userName, e)
)
if hostName.lower() == name.lower():
logger.info('Computer name is already {}'.format(hostName))
return
if platform.operations.renameComputer(name):
self.reboot()
@ -379,8 +472,9 @@ class CommonService: # pylint: disable=too-many-instance-attributes
self.checkIpsChanged()
# Now check if every registered client is already there (if logged in OFC)
if self._loggedIn and not self._clientsPool.ping():
self.logout('client_unavailable')
for lost_client in clients_pool.UDSActorClientPool().lost_clients():
logger.info('Lost client: {}'.format(lost_client))
self.logout('client_unavailable', '', lost_client.session_id or '') # '' means "all clients"
except Exception as e:
logger.error('Exception on main service loop: %s', e)
@ -388,13 +482,8 @@ class CommonService: # pylint: disable=too-many-instance-attributes
# Methods that can be overriden by linux & windows Actor
# ******************************************************
def joinDomain( # pylint: disable=unused-argument, too-many-arguments
self,
name: str,
domain: str,
ou: str,
account: str,
password: str
) -> None:
self, name: str, domain: str, ou: str, account: str, password: str
) -> None:
'''
Invoked when broker requests a "domain" action
default does nothing
@ -402,30 +491,86 @@ class CommonService: # pylint: disable=too-many-instance-attributes
logger.debug('Base join invoked: {} on {}, {}'.format(name, domain, ou))
# Client notifications
def login(self, username: str, sessionType: typing.Optional[str] = None) -> types.LoginResultInfoType:
result = types.LoginResultInfoType(ip='', hostname='', dead_line=None, max_idle=None)
self._loggedIn = True
def login(
self, username: str, sessionType: typing.Optional[str] = None
) -> types.LoginResultInfoType:
result = types.LoginResultInfoType(
ip='', hostname='', dead_line=None, max_idle=None, session_id=None
)
master_token = None
secret = None
# If unmanaged, do initialization now, because we don't know before this
# Also, even if not initialized, get a "login" notification token
if not self.isManaged():
self.initialize()
self._initialized = (
self.initialize()
) # Maybe it's a local login by an unmanaged host.... On real login, will execute initilize again
# Unamanaged, need the master token
master_token = self._cfg.master_token
secret = self._secret
if self._cfg.own_token:
result = self._api.login(self._cfg.own_token, username, sessionType)
# Own token will not be set if UDS did not assigned the initialized VM to an user
# In that case, take master token (if machine is Unamanaged version)
token = self._cfg.own_token or master_token
if token:
result = self._api.login(
self._cfg.actorType,
token,
username,
sessionType or '',
self._interfaces,
secret,
)
if (
result.session_id
): # If logged in, process it. client_pool will take account of login response to client and session
script = platform.store.invokeScriptOnLogin()
if script:
logger.info('Executing script on login: {}'.format(script))
script += f'{username} {sessionType or "unknown"} {self._cfg.actorType}'
self.execute(script, 'Logon')
return result
def logout(self, username: str) -> None:
self._loggedIn = False
if self._cfg.own_token:
self._api.logout(self._cfg.own_token, username)
def logout(
self,
username: str,
session_type: typing.Optional[str],
session_id: typing.Optional[str],
) -> None:
master_token = self._cfg.master_token
self.onLogout(username)
# Own token will not be set if UDS did not assigned the initialized VM to an user
# In that case, take master token (if machine is Unamanaged version)
token = self._cfg.own_token or master_token
if token:
# If logout is not processed (that is, not ok result), the logout has not been processed
if (
self._api.logout(
self._cfg.actorType,
token,
username,
session_id or '',
session_type or '',
self._interfaces,
self._secret,
)
!= 'ok' # Can return also "notified", that means the logout has not been processed by UDS
):
logger.info(
'Logout from %s ignored as required by uds broker', username
)
return
self.onLogout(username, session_id or '')
if not self.isManaged():
self.uninitialize()
# ****************************************
# Methods that CAN BE overriden by actors
# ****************************************
# ******************************************************
# Methods that CAN BE overriden by specific OS Actor
# ******************************************************
def doWait(self, miliseconds: int) -> None:
'''
Invoked to wait a bit
@ -444,15 +589,27 @@ class CommonService: # pylint: disable=too-many-instance-attributes
'''
logger.info('Service stopped')
def preConnect(self, userName: str, protocol: str, ip: str, hostname: str) -> str: # pylint: disable=unused-argument
def preConnect(
self, userName: str, protocol: str, ip: str, hostname: str, udsUserName: str
) -> str:
'''
Invoked when received a PRE Connection request via REST
Base preconnect executes the preconnect command
'''
if self._cfg.pre_command:
self.execute(self._cfg.pre_command + ' {} {} {} {}'.format(userName.replace('"', '%22'), protocol, ip, hostname), 'preConnect')
self.execute(
self._cfg.pre_command
+ ' {} {} {} {} {}'.format(
userName.replace('"', '%22'),
protocol,
ip,
hostname,
udsUserName.replace('"', '%22'),
),
'preConnect',
)
return 'ok'
def onLogout(self, userName: str) -> None:
def onLogout(self, userName: str, session_id: str) -> None:
logger.debug('On logout invoked for {}'.format(userName))

View File

@ -28,20 +28,113 @@
'''
@author: Adolfo Gómez, dkmaster at dkmon dot com
'''
# pylint: disable=invalid-name
import threading
import ipaddress
import time
import typing
import functools
from udsactor.log import logger
if typing.TYPE_CHECKING:
from udsactor.types import InterfaceInfoType
# Simple cache for n seconds (default = 30) decorator
def cache(seconds: int = 30) -> typing.Callable:
'''
Simple cache for n seconds (default = 30) decorator
'''
def decorator(func) -> typing.Callable:
@functools.wraps(func)
def wrapper(*args, **kwargs) -> typing.Any:
if not hasattr(wrapper, 'cache'):
wrapper.cache = {} # type: ignore
cache = wrapper.cache # type: ignore
# Compose a key for the cache
key = '{}:{}'.format(args, kwargs)
if key in cache:
if time.time() - cache[key][0] < seconds:
return cache[key][1]
# Call the function
result = func(*args, **kwargs)
cache[key] = (time.time(), result)
return result
return wrapper
return decorator
# Simple sub-script exectution thread
class ScriptExecutorThread(threading.Thread):
def __init__(self, script: str) -> None:
super(ScriptExecutorThread, self).__init__()
self.script = script
def run(self) -> None:
from udsactor.log import logger
try:
logger.debug('Executing script: {}'.format(self.script))
exec(self.script, globals(), None) # pylint: disable=exec-used
exec(
self.script, globals(), None
) # nosec: exec is fine, it's a "trusted" script
except Exception as e:
logger.error('Error executing script: {}'.format(e))
logger.exception()
class Singleton(type):
'''
Metaclass for singleton pattern
Usage:
class MyClass(metaclass=Singleton):
...
'''
_instance: typing.Optional[typing.Any]
# We use __init__ so we customise the created class from this metaclass
def __init__(self, *args, **kwargs) -> None:
self._instance = None
super().__init__(*args, **kwargs)
def __call__(self, *args, **kwargs) -> typing.Any:
if self._instance is None:
self._instance = super().__call__(*args, **kwargs)
return self._instance
# Convert "X.X.X.X/X" to ipaddress.IPv4Network
def strToNoIPV4Network(
net: typing.Optional[str],
) -> typing.Optional[ipaddress.IPv4Network]:
if not net: # Empty or None
return None
try:
return ipaddress.IPv4Interface(net).network
except Exception:
return None
def validNetworkCards(
net: typing.Optional[str], cards: typing.Iterable['InterfaceInfoType']
) -> typing.List['InterfaceInfoType']:
try:
subnet = strToNoIPV4Network(net)
except Exception as e:
subnet = None
if subnet is None:
return list(cards)
def isValid(ip: str, subnet: ipaddress.IPv4Network) -> bool:
if not ip:
return False
try:
return ipaddress.IPv4Address(ip) in subnet
except Exception:
return False
return [c for c in cards if isValid(c.ip, subnet)]

View File

@ -35,6 +35,7 @@ class ActorConfigurationType(typing.NamedTuple):
actorType: typing.Optional[str] = None
master_token: typing.Optional[str] = None
own_token: typing.Optional[str] = None
restrict_net: typing.Optional[str] = None
pre_command: typing.Optional[str] = None
runonce_command: typing.Optional[str] = None
@ -50,12 +51,22 @@ class InitializationResultType(typing.NamedTuple):
own_token: typing.Optional[str] = None
unique_id: typing.Optional[str] = None
os: typing.Optional[ActorOsConfigurationType] = None
alias_token: typing.Optional[str] = None
class LoginResultInfoType(typing.NamedTuple):
ip: str
hostname: str
dead_line: typing.Optional[int]
max_idle: typing.Optional[int] # Not provided by broker
max_idle: typing.Optional[int]
session_id: typing.Optional[str]
@property
def logged_in(self) -> bool:
return bool(self.session_id)
class ClientInfo(typing.NamedTuple):
url: str
session_id: str
class CertificateInfoType(typing.NamedTuple):
private_key: str

View File

@ -0,0 +1,2 @@
VERSION = '4.0.0'
BUILD = '20220901'

View File

@ -1,6 +1,6 @@
# -*- coding: utf-8 -*-
#
# Copyright (c) 2014-2019 Virtual Cable S.L.
# Copyright (c) 2014-2022 Virtual Cable S.L.U.
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without modification,
@ -11,7 +11,7 @@
# * 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
# * Neither the name of Virtual Cable S.L.U. nor the names of its contributors
# may be used to endorse or promote products derived from this software
# without specific prior written permission.
#

View File

@ -1,6 +1,6 @@
# -*- coding: utf-8 -*-
#
# Copyright (c) 2014 Virtual Cable S.L.
# Copyright (c) 2014-2022 Virtual Cable S.L.U.
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without modification,
@ -11,7 +11,7 @@
# * 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
# * Neither the name of Virtual Cable S.L.U. nor the names of its contributors
# may be used to endorse or promote products derived from this software
# without specific prior written permission.
#
@ -34,7 +34,7 @@ import os
import tempfile
import typing
import servicemanager # pylint: disable=import-error
import servicemanager
# Valid logging levels, from UDS Broker (uds.core.utils.log).
from .. import loglevel
@ -42,6 +42,7 @@ from .. import loglevel
class LocalLogger: # pylint: disable=too-few-public-methods
linux = False
windows = True
serviceLogger = False
logger: typing.Optional[logging.Logger]

View File

@ -1,6 +1,6 @@
# -*- coding: utf-8 -*-
#
# Copyright (c) 2014-2019 Virtual Cable S.L.
# Copyright (c) 2014-2022 Virtual Cable S.L.U.
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without modification,
@ -11,7 +11,7 @@
# * 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
# * Neither the name of Virtual Cable S.L.U. nor the names of its contributors
# may be used to endorse or promote products derived from this software
# without specific prior written permission.
#
@ -45,32 +45,46 @@ import win32con
from .. import types
from ..log import logger
def checkPermissions() -> bool:
return shell.IsUserAnAdmin()
def getErrorMessage(resultCode: int = 0) -> str:
# sys_fs_enc = sys.getfilesystemencoding() or 'mbcs'
msg = win32api.FormatMessage(resultCode)
return msg
def getComputerName() -> str:
return win32api.GetComputerNameEx(win32con.ComputerNamePhysicalDnsHostname)
def getNetworkInfo() -> typing.Iterator[types.InterfaceInfoType]:
obj = win32com.client.Dispatch("WbemScripting.SWbemLocator")
wmobj = obj.ConnectServer("localhost", "root\\cimv2")
adapters = wmobj.ExecQuery("Select * from Win32_NetworkAdapterConfiguration where IpEnabled=True")
adapters = wmobj.ExecQuery(
"Select * from Win32_NetworkAdapterConfiguration where IpEnabled=True"
)
try:
for obj in adapters:
for ip in obj.IPAddress:
if ':' in ip: # Is IPV6, skip this
continue
if ip is None or ip == '' or ip.startswith('169.254') or ip.startswith('0.'): # If single link ip, or no ip
if (
ip is None
or ip == ''
or ip.startswith('169.254')
or ip.startswith('0.')
): # If single link ip, or no ip
continue
yield types.InterfaceInfoType(name=obj.Caption, mac=obj.MACAddress, ip=ip)
yield types.InterfaceInfoType(
name=obj.Caption, mac=obj.MACAddress, ip=ip
)
except Exception:
return
def getDomainName() -> str:
'''
Will return the domain name if we belong a domain, else None
@ -87,9 +101,19 @@ def getDomainName() -> str:
return domain
def getWindowsVersion() -> typing.Tuple[int, int, int, int, str]:
return win32api.GetVersionEx()
def getVersion() -> str:
verinfo = getWindowsVersion()
# Remove platform id i
return 'Windows-{}.{} Build {} ({})'.format(
verinfo[0], verinfo[1], verinfo[2], verinfo[4]
)
EWX_LOGOFF = 0x00000000
EWX_SHUTDOWN = 0x00000001
EWX_REBOOT = 0x00000002
@ -97,31 +121,53 @@ EWX_FORCE = 0x00000004
EWX_POWEROFF = 0x00000008
EWX_FORCEIFHUNG = 0x00000010
def reboot(flags: int = EWX_FORCEIFHUNG | EWX_REBOOT) -> None:
hproc = win32api.GetCurrentProcess()
htok = win32security.OpenProcessToken(hproc, win32security.TOKEN_ADJUST_PRIVILEGES | win32security.TOKEN_QUERY)
privs = ((win32security.LookupPrivilegeValue(None, win32security.SE_SHUTDOWN_NAME), win32security.SE_PRIVILEGE_ENABLED),)
htok = win32security.OpenProcessToken(
hproc, win32security.TOKEN_ADJUST_PRIVILEGES | win32security.TOKEN_QUERY
)
privs = (
(
win32security.LookupPrivilegeValue(None, win32security.SE_SHUTDOWN_NAME),
win32security.SE_PRIVILEGE_ENABLED,
),
)
win32security.AdjustTokenPrivileges(htok, 0, privs)
win32api.ExitWindowsEx(flags, 0)
def loggoff() -> None:
win32api.ExitWindowsEx(EWX_LOGOFF)
def renameComputer(newName: str) -> bool:
'''
Changes the computer name
Returns True if reboot needed
'''
# Needs admin privileges to work
if ctypes.windll.kernel32.SetComputerNameExW(DWORD(win32con.ComputerNamePhysicalDnsHostname), LPCWSTR(newName)) == 0: # @UndefinedVariable
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)
error = getErrorMessage()
computerName = win32api.GetComputerNameEx(win32con.ComputerNamePhysicalDnsHostname)
raise Exception('Error renaming computer from {} to {}: {}'.format(computerName, newName, error))
computerName = win32api.GetComputerNameEx(
win32con.ComputerNamePhysicalDnsHostname
)
raise Exception(
'Error renaming computer from {} to {}: {}'.format(
computerName, newName, error
)
)
return True
NETSETUP_JOIN_DOMAIN = 0x00000001
NETSETUP_ACCT_CREATE = 0x00000002
NETSETUP_ACCT_DELETE = 0x00000004
@ -132,7 +178,10 @@ NETSETUP_MACHINE_PWD_PASSED = 0x00000080
NETSETUP_JOIN_WITH_NEW_NAME = 0x00000400
NETSETUP_DEFER_SPN_SET = 0x1000000
def joinDomain(domain: str, ou: str, account: str, password: str, executeInOneStep: bool = False) -> None:
def joinDomain(
domain: str, ou: str, account: str, password: str, executeInOneStep: bool = False
) -> None:
'''
Joins machine to a windows domain
:param domain: Domain to join to
@ -149,7 +198,9 @@ def joinDomain(domain: str, ou: str, account: str, password: str, executeInOneSt
account = domain + '\\' + account
# Do log
flags: typing.Any = NETSETUP_ACCT_CREATE | NETSETUP_DOMAIN_JOIN_IF_JOINED | NETSETUP_JOIN_DOMAIN
flags: typing.Any = (
NETSETUP_ACCT_CREATE | NETSETUP_DOMAIN_JOIN_IF_JOINED | NETSETUP_JOIN_DOMAIN
)
if executeInOneStep:
flags |= NETSETUP_JOIN_WITH_NEW_NAME
@ -163,18 +214,31 @@ def joinDomain(domain: str, ou: str, account: str, password: str, executeInOneSt
lpAccount = LPCWSTR(account)
lpPassword = LPCWSTR(password)
res = ctypes.windll.netapi32.NetJoinDomain(None, lpDomain, lpOu, lpAccount, lpPassword, flags)
res = ctypes.windll.netapi32.NetJoinDomain(
None, lpDomain, lpOu, lpAccount, lpPassword, flags
)
# Machine found in another ou, use it and warn this on log
if res == 2224:
flags = DWORD(NETSETUP_DOMAIN_JOIN_IF_JOINED | NETSETUP_JOIN_DOMAIN)
res = ctypes.windll.netapi32.NetJoinDomain(None, lpDomain, None, lpAccount, lpPassword, flags)
res = ctypes.windll.netapi32.NetJoinDomain(
None, lpDomain, None, lpAccount, lpPassword, flags
)
if res:
# Log the error
error = getErrorMessage(res)
if res == 1355:
error = "DC Is not reachable"
logger.error('Error joining domain: {}, {}'.format(error, res))
raise Exception('Error joining domain {}, with credentials {}/*****{}: {}, {}'.format(domain, account, ', under OU {}'.format(ou) if ou is not None else '', res, error))
raise Exception(
'Error joining domain {}, with credentials {}/*****{}: {}, {}'.format(
domain,
account,
', under OU {}'.format(ou) if ou is not None else '',
res,
error,
)
)
def changeUserPassword(user: str, oldPassword: str, newPassword: str) -> None:
# lpUser = LPCWSTR(user)
@ -188,7 +252,10 @@ def changeUserPassword(user: str, oldPassword: str, newPassword: str) -> None:
if res:
# Log the error, and raise exception to parent
error = getErrorMessage(res)
raise Exception('Error changing password for user {}: {} {}'.format(user, res, error))
raise Exception(
'Error changing password for user {}: {} {}'.format(user, res, error)
)
class LASTINPUTINFO(ctypes.Structure): # pylint: disable=too-few-public-methods
_fields_ = [
@ -196,16 +263,20 @@ class LASTINPUTINFO(ctypes.Structure): # pylint: disable=too-few-public-methods
('dwTime', ctypes.c_uint),
]
def initIdleDuration(atLeastSeconds: int): # pylint: disable=unused-argument
'''
In windows, there is no need to set screensaver
'''
return
def getIdleDuration() -> float:
try:
lastInputInfo = LASTINPUTINFO()
lastInputInfo.cbSize = ctypes.sizeof(lastInputInfo) # pylint: disable=attribute-defined-outside-init
lastInputInfo.cbSize = ctypes.sizeof(
lastInputInfo
) # pylint: disable=attribute-defined-outside-init
if ctypes.windll.user32.GetLastInputInfo(ctypes.byref(lastInputInfo)) == 0:
return 0
current = ctypes.c_uint(ctypes.windll.kernel32.GetTickCount()).value
@ -217,22 +288,27 @@ def getIdleDuration() -> float:
logger.error('Getting idle duration: {}'.format(e))
return 0
def getCurrentUser() -> str:
'''
Returns current logged in username
'''
return os.environ['USERNAME']
def getSessionType() -> str:
'''
Known values:
* Unknown -> No SESSIONNAME environment variable
* Console -> Local session
* RDP-Tcp#[0-9]+ -> RDP Session
Known values:
* Unknown -> No SESSIONNAME environment variable
* Console -> Local session
* RDP-Tcp#[0-9]+ -> RDP Session
'''
return os.environ.get('SESSIONNAME', 'unknown')
def writeToPipe(pipeName: str, bytesPayload: bytes, waitForResponse: bool) -> typing.Optional[bytes]:
def writeToPipe(
pipeName: str, bytesPayload: bytes, waitForResponse: bool
) -> typing.Optional[bytes]:
# (str, bytes, bool) -> Optional[bytes]
try:
with open(pipeName, 'r+b', 0) as f:
@ -244,8 +320,11 @@ def writeToPipe(pipeName: str, bytesPayload: bytes, waitForResponse: bool) -> ty
except Exception:
return None
def forceTimeSync() -> None:
try:
subprocess.call([r'c:\WINDOWS\System32\w32tm.exe', ' /resync']) # , '/rediscover'])
subprocess.call(
[r'c:\WINDOWS\System32\w32tm.exe', ' /resync']
) # , '/rediscover'])
except Exception as e:
logger.error('Error invoking time sync command: %s', e)

View File

@ -1,6 +1,6 @@
# -*- coding: utf-8 -*-
#
# Copyright (c) 2019 Virtual Cable S.L.
# Copyright (c) 2019-2022 Virtual Cable S.L.U.
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without modification,
@ -11,7 +11,7 @@
# * 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
# * Neither the name of Virtual Cable S.L.U. nor the names of its contributors
# may be used to endorse or promote products derived from this software
# without specific prior written permission.
#
@ -41,6 +41,8 @@ from .service import UDSActorSvc
def setupRecoverService():
svc_name = UDSActorSvc._svc_name_ # pylint: disable=protected-access
hs = None
hscm = None
try:
hscm = win32service.OpenSCManager(None, None, win32service.SC_MANAGER_ALL_ACCESS)
@ -57,9 +59,11 @@ def setupRecoverService():
}
win32service.ChangeServiceConfig2(hs, win32service.SERVICE_CONFIG_FAILURE_ACTIONS, service_failure_actions)
finally:
win32service.CloseServiceHandle(hs)
if hs:
win32service.CloseServiceHandle(hs)
finally:
win32service.CloseServiceHandle(hscm)
if hscm:
win32service.CloseServiceHandle(hscm)
def run() -> None:

View File

@ -39,6 +39,7 @@ import win32net
import win32event
import pythoncom
import servicemanager
import winreg as wreg
from . import operations
from . import store
@ -138,7 +139,7 @@ class UDSActorSvc(win32serviceutil.ServiceFramework, CommonService):
logger.info('Using multiple step join because configuration requests to do so')
self.multiStepJoin(name, domain, ou, account, password)
def preConnect(self, userName: str, protocol: str, ip: str, hostname: str) -> str:
def preConnect(self, userName: str, protocol: str, ip: str, hostname: str, udsUserName: str) -> str:
logger.debug('Pre connect invoked')
if protocol == 'rdp': # If connection is not using rdp, skip adding user
@ -167,7 +168,7 @@ class UDSActorSvc(win32serviceutil.ServiceFramework, CommonService):
self._user = None
logger.debug('User {} already in group'.format(userName))
return super().preConnect(userName, protocol, ip, hostname)
return super().preConnect(userName, protocol, ip, hostname, udsUserName)
def ovLogon(self, username: str, password: str) -> str:
"""
@ -182,7 +183,7 @@ class UDSActorSvc(win32serviceutil.ServiceFramework, CommonService):
operations.writeToPipe("\\\\.\\pipe\\VDSMDPipe", packet, True)
return 'done'
def onLogout(self, userName) -> None:
def onLogout(self, userName: str, session_id: str) -> None:
logger.debug('Windows onLogout invoked: {}, {}'.format(userName, self._user))
try:
p = win32security.GetBinarySid(REMOTE_USERS_SID)
@ -197,6 +198,18 @@ class UDSActorSvc(win32serviceutil.ServiceFramework, CommonService):
except Exception as e:
logger.error('Exception removing user from Remote Desktop Users: {}'.format(e))
def isInstallationRunning(self):
'''
Detect if windows is installing anything, so we can delay the execution of Service
'''
try:
key = wreg.OpenKey(wreg.HKEY_LOCAL_MACHINE, 'SOFTWARE\Microsoft\Windows\CurrentVersion\Setup\State')
data, _ = wreg.QueryValueEx(key, 'ImageState')
logger.debug('State: %s', data)
return data != 'IMAGE_STATE_COMPLETE' # If ImageState is different of ImageStateComplete, there is something running on installation
except Exception: # If not found, means that no installation is running
return False
def SvcDoRun(self) -> None: # pylint: disable=too-many-statements, too-many-branches
'''
Main service loop
@ -209,6 +222,17 @@ class UDSActorSvc(win32serviceutil.ServiceFramework, CommonService):
pythoncom.CoInitialize() # pylint: disable=no-member
# Check if some install is running on windows before proceeding
while self._isAlive:
if self.isInstallationRunning():
win32event.WaitForSingleObject(self._hWaitStop, 1000) # Wait a bit, and check again
continue
break
if not self._isAlive: # Has been stopped while waiting windows installations
self.finish()
return
# Unmanaged services does not initializes "on start", but rather when user logs in (because userservice does not exists "as such" before that)
if self.isManaged():
if not self.initialize():

View File

@ -76,9 +76,9 @@ def writeConfig(config: types.ActorConfigurationType) -> None:
except Exception:
key = wreg.CreateKeyEx(BASEKEY, PATH, 0, wreg.KEY_ALL_ACCESS)
fixRegistryPermissions(key.handle)
fixRegistryPermissions(key.handle) # type: ignore
wreg.SetValueEx(key, "", 0, wreg.REG_BINARY, pickle.dumps(config))
wreg.SetValueEx(key, "", 0, wreg.REG_BINARY, pickle.dumps(config)) # type: ignore
wreg.CloseKey(key)
@ -94,3 +94,16 @@ def useOldJoinSystem() -> bool:
data = ''
return data == 'old'
def invokeScriptOnLogin() -> str:
try:
key = wreg.OpenKey(BASEKEY, PATH, 0, wreg.KEY_QUERY_VALUE)
try:
data, _ = wreg.QueryValueEx(key, 'logonScript')
except Exception:
data = ''
wreg.CloseKey(key)
except Exception:
data = ''
return data

View File

@ -2,9 +2,10 @@
# Form implementation generated from reading ui file 'setup-dialog.ui'
#
# Created by: PyQt5 UI code generator 5.13.2
# Created by: PyQt5 UI code generator 5.15.2
#
# WARNING! All changes made in this file will be lost!
# WARNING: Any manual changes made to this file will be lost when pyuic5 is
# run again. Do not edit this file unless you know what you are doing.
from PyQt5 import QtCore, QtGui, QtWidgets

View File

@ -2,9 +2,10 @@
# Form implementation generated from reading ui file 'setup-dialog-unmanaged.ui'
#
# Created by: PyQt5 UI code generator 5.13.2
# Created by: PyQt5 UI code generator 5.15.2
#
# WARNING! All changes made in this file will be lost!
# WARNING: Any manual changes made to this file will be lost when pyuic5 is
# run again. Do not edit this file unless you know what you are doing.
from PyQt5 import QtCore, QtGui, QtWidgets
@ -14,7 +15,7 @@ class Ui_UdsActorSetupDialog(object):
def setupUi(self, UdsActorSetupDialog):
UdsActorSetupDialog.setObjectName("UdsActorSetupDialog")
UdsActorSetupDialog.setWindowModality(QtCore.Qt.WindowModal)
UdsActorSetupDialog.resize(595, 220)
UdsActorSetupDialog.resize(601, 243)
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Preferred)
sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0)
@ -34,12 +35,12 @@ class Ui_UdsActorSetupDialog(object):
UdsActorSetupDialog.setModal(True)
self.saveButton = QtWidgets.QPushButton(UdsActorSetupDialog)
self.saveButton.setEnabled(True)
self.saveButton.setGeometry(QtCore.QRect(10, 180, 181, 23))
self.saveButton.setGeometry(QtCore.QRect(10, 210, 181, 23))
self.saveButton.setMinimumSize(QtCore.QSize(181, 0))
self.saveButton.setContextMenuPolicy(QtCore.Qt.DefaultContextMenu)
self.saveButton.setObjectName("saveButton")
self.closeButton = QtWidgets.QPushButton(UdsActorSetupDialog)
self.closeButton.setGeometry(QtCore.QRect(410, 180, 171, 23))
self.closeButton.setGeometry(QtCore.QRect(410, 210, 171, 23))
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Fixed)
sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0)
@ -49,11 +50,11 @@ class Ui_UdsActorSetupDialog(object):
self.closeButton.setObjectName("closeButton")
self.testButton = QtWidgets.QPushButton(UdsActorSetupDialog)
self.testButton.setEnabled(False)
self.testButton.setGeometry(QtCore.QRect(210, 180, 181, 23))
self.testButton.setGeometry(QtCore.QRect(210, 210, 181, 23))
self.testButton.setMinimumSize(QtCore.QSize(181, 0))
self.testButton.setObjectName("testButton")
self.layoutWidget = QtWidgets.QWidget(UdsActorSetupDialog)
self.layoutWidget.setGeometry(QtCore.QRect(10, 10, 571, 161))
self.layoutWidget.setGeometry(QtCore.QRect(10, 10, 571, 191))
self.layoutWidget.setObjectName("layoutWidget")
self.formLayout = QtWidgets.QFormLayout(self.layoutWidget)
self.formLayout.setSizeConstraint(QtWidgets.QLayout.SetDefaultConstraint)
@ -84,7 +85,7 @@ class Ui_UdsActorSetupDialog(object):
self.formLayout.setWidget(2, QtWidgets.QFormLayout.FieldRole, self.serviceToken)
self.label_loglevel = QtWidgets.QLabel(self.layoutWidget)
self.label_loglevel.setObjectName("label_loglevel")
self.formLayout.setWidget(3, QtWidgets.QFormLayout.LabelRole, self.label_loglevel)
self.formLayout.setWidget(4, QtWidgets.QFormLayout.LabelRole, self.label_loglevel)
self.logLevelComboBox = QtWidgets.QComboBox(self.layoutWidget)
self.logLevelComboBox.setFrame(True)
self.logLevelComboBox.setObjectName("logLevelComboBox")
@ -96,7 +97,13 @@ class Ui_UdsActorSetupDialog(object):
self.logLevelComboBox.setItemText(2, "ERROR")
self.logLevelComboBox.addItem("")
self.logLevelComboBox.setItemText(3, "FATAL")
self.formLayout.setWidget(3, QtWidgets.QFormLayout.FieldRole, self.logLevelComboBox)
self.formLayout.setWidget(4, QtWidgets.QFormLayout.FieldRole, self.logLevelComboBox)
self.label_restrictNet = QtWidgets.QLabel(self.layoutWidget)
self.label_restrictNet.setObjectName("label_restrictNet")
self.formLayout.setWidget(3, QtWidgets.QFormLayout.LabelRole, self.label_restrictNet)
self.restrictNet = QtWidgets.QLineEdit(self.layoutWidget)
self.restrictNet.setObjectName("restrictNet")
self.formLayout.setWidget(3, QtWidgets.QFormLayout.FieldRole, self.restrictNet)
self.label_host.raise_()
self.host.raise_()
self.label_serviceToken.raise_()
@ -105,6 +112,8 @@ class Ui_UdsActorSetupDialog(object):
self.label_security.raise_()
self.label_loglevel.raise_()
self.logLevelComboBox.raise_()
self.label_restrictNet.raise_()
self.restrictNet.raise_()
self.retranslateUi(UdsActorSetupDialog)
self.logLevelComboBox.setCurrentIndex(1)
@ -113,6 +122,7 @@ class Ui_UdsActorSetupDialog(object):
self.saveButton.clicked.connect(UdsActorSetupDialog.saveConfig)
self.host.textChanged['QString'].connect(UdsActorSetupDialog.configChanged)
self.serviceToken.textChanged['QString'].connect(UdsActorSetupDialog.configChanged)
self.restrictNet.textChanged['QString'].connect(UdsActorSetupDialog.configChanged)
QtCore.QMetaObject.connectSlotsByName(UdsActorSetupDialog)
def retranslateUi(self, UdsActorSetupDialog):
@ -136,7 +146,10 @@ class Ui_UdsActorSetupDialog(object):
self.host.setToolTip(_translate("UdsActorSetupDialog", "Uds Broker Server Addres. Use IP or FQDN"))
self.host.setWhatsThis(_translate("UdsActorSetupDialog", "Enter here the UDS Broker Addres using either its IP address or its FQDN address"))
self.label_serviceToken.setText(_translate("UdsActorSetupDialog", "Service Token"))
self.serviceToken.setToolTip(_translate("UdsActorSetupDialog", "UDS user with administration rights (Will not be stored on template)"))
self.serviceToken.setToolTip(_translate("UdsActorSetupDialog", "UDS Service Token"))
self.serviceToken.setWhatsThis(_translate("UdsActorSetupDialog", "<html><head/><body><p>Administrator user on UDS Server.</p><p>Note: This credential will not be stored on client. Will be used to obtain an unique token for this image.</p></body></html>"))
self.label_loglevel.setText(_translate("UdsActorSetupDialog", "Log Level"))
self.label_restrictNet.setText(_translate("UdsActorSetupDialog", "Restrict Net"))
self.restrictNet.setToolTip(_translate("UdsActorSetupDialog", "UDS user with administration rights (Will not be stored on template)"))
self.restrictNet.setWhatsThis(_translate("UdsActorSetupDialog", "<html><head/><body><p>Administrator user on UDS Server.</p><p>Note: This credential will not be stored on client. Will be used to obtain an unique token for this image.</p></body></html>"))
from ui import uds_rc

View File

@ -2,7 +2,7 @@
# Resource object code
#
# Created by: The Resource Compiler for PyQt5 (Qt v5.13.2)
# Created by: The Resource Compiler for PyQt5 (Qt v5.15.2)
#
# WARNING! All changes made in this file will be lost!

2
client-py3/full/.env Normal file
View File

@ -0,0 +1,2 @@
PYTHONPATH=./src:${PYTHONPATH}

View File

@ -2,3 +2,7 @@
/udsclient-[0-9]*.spec
/debian/udsclient
/targz
/UDSClientDir
/UDSClient*.AppImage
/appimage*
/UDSClient.desktop

View File

@ -14,6 +14,8 @@ APPSDIR := $(DESTDIR)/usr/share/applications
PYC := $(shell find $(SOURCEDIR) -name '*.py[co]')
CACHES := $(shell find $(SOURCEDIR) -name '__pycache__')
clean:
rm -rf $(PYC) $(CACHES) $(DESTDIR)
install:
@ -46,8 +48,60 @@ endif
ifeq ($(DISTRO),rh)
endif
# chmod 0755 $(BINDIR)/udsclient
uninstall:
rm -rf $(LIBDIR)
# rm -f $(BINDIR)/udsclient
# rm -rf $(CFGDIR)
build-appimage:
ifeq ($(DISTRO),x86_64)
cat udsclient-appimage-x86_64.recipe | sed -e s/"version: 0.0.0"/"version: $(VERSION)"/g > appimage.recipe
endif
ifeq ($(DISTRO),armhf)
cat udsclient-appimage-x86_64.recipe | sed -e s/"version: 0.0.0"/"version: $(VERSION)"/g | sed -e s/amd64/armhf/g | sed -e s/x86_64/armhf/g > appimage.recipe
endif
ifeq ($(DISTRO),i686)
cat udsclient-appimage-x86_64.recipe | sed -e s/"version: 0.0.0"/"version: $(VERSION)"/g | sed -e s/amd64/i386/g | sed -e s/x86_64/i686/g > appimage.recipe
endif
# Ensure all working folders are "clean"
-rm -rf appimage appimage-builder-cache /tmp/UDSClientDir
appimage-builder --recipe appimage.recipe
# Now create dist and move appimage
rm -rf $(DESTDIR)
mkdir -p $(DESTDIR)
cp UDSClient-$(VERSION)-$(DISTRO).AppImage $(DESTDIR)
# Generate the .desktop fixed for new path
cat desktop/UDSClient.desktop | sed -e s/".usr.lib.UDSClient.UDSClient.py"/"\/usr\/bin\/UDSClient-$(VERSION)-$(DISTRO).AppImage"/g > $(DESTDIR)/UDSClient.desktop
# And also, generater installer
cat installer-appimage-template.sh | sed -e s/"0.0.0"/"$(VERSION)"/g | sed -e s/x86_64/$(DISTRO)/g > $(DESTDIR)/installer.sh
chmod 755 $(DESTDIR)/installer.sh
tar czvf ../udsclient3-$(DISTRO)-$(VERSION).tar.gz -C $(DESTDIR) .
# cleanup
-rm -rf appimage appimage-builder-cache /tmp/UDSClientDir
build-igel:
rm -rf $(DESTDIR)
mkdir -p $(DESTDIR)
# Calculate the size of the custom partition (15 megas more than the appimage size)
@$(eval APPIMAGE_SIZE=$(shell du -sm UDSClient-$(VERSION)-x86_64.AppImage | cut -f1))
@$(eval APPIMAGE_SIZE=$(shell expr $(APPIMAGE_SIZE) + 15))
cat igel/UDSClient-Profile-template.xml | sed -e s/"_SIZE_"/"$(APPIMAGE_SIZE)M"/g > $(DESTDIR)/UDSClient-Profile.xml
cat igel/UDSClient-template.inf | sed -e s/"_SIZE_"/"$(APPIMAGE_SIZE)M"/g > $(DESTDIR)/UDSClient.inf
cp UDSClient-$(VERSION)-x86_64.AppImage $(DESTDIR)/UDSClient
cp igel/UDSClient.desktop $(DESTDIR)/UDSClient.desktop
cp igel/init.sh $(DESTDIR)/init.sh
tar cjvf $(DESTDIR)/UDSClient.tar.bz2 -C $(DESTDIR) UDSClient UDSClient.desktop init.sh
zip -j ../udsclient3-$(VERSION)-igel.zip $(DESTDIR)/UDSClient-Profile.xml $(DESTDIR)/UDSClient.inf $(DESTDIR)/UDSClient.tar.bz2
cd ..
rm -rf $(DESTDIR)
build-thinpro:
rm -rf $(DESTDIR)
mkdir -p $(DESTDIR)
cp -r thinpro/* $(DESTDIR)
cp UDSClient-$(VERSION)-x86_64.AppImage $(DESTDIR)/UDSClient
tar czvf ../udsclient3-$(VERSION)-thinpro.tar.gz -C $(DESTDIR) .
rm -rf $(DESTDIR)

View File

@ -12,6 +12,9 @@ cat udsclient-template.spec |
sed -e s/"version 0.0.0"/"version ${VERSION}"/g |
sed -e s/"release 1"/"release ${RELEASE}"/g > udsclient-$VERSION.spec
cat appimage-udsclient.recipe |
sed -e s/"version: 0.0.0"/"version: ${VERSION}"/g > appimage.recipe
# Now fix dependencies for opensuse
# Note: Right now, opensuse & rh seems to have same dependencies, only 1 package needed
# cat udsclient-template.spec |
@ -32,6 +35,19 @@ done
#rm udsclient-$VERSION
# Make .tar.gz with source
make DESTDIR=targz DISTRO=targz VERSION=${VERSION} install
# And make FULL CLIENT .tar.gz for x86 and raspberry
make DESTDIR=appimage DISTRO=x86_64 VERSION=${VERSION} build-appimage
make DESTDIR=appimage DISTRO=armhf VERSION=${VERSION} build-appimage
make DESTDIR=appimage DISTRO=i686 VERSION=${VERSION} build-appimage
# Now create igel version
# we need first to create the Appimage for x86_64
make DESTDIR=igelimage DISTRO=x86_64 VERSION=${VERSION} build-igel
# Create the thinpro version
make DESTDIR=thinproimage DISTRO=x86_64 VERSION=${VERSION} build-thinpro
rpm --addsign ../*rpm

View File

@ -1,3 +1,21 @@
udsclient3 (4.0.0) stable; urgency=medium
* Upgraded to 4.0.0 release
-- Adolfo Gómez García <agomez@virtualcable.es> Fri, 1 Jul 2022 15:12:10 +0200
udsclient3 (4.0.0) stable; urgency=medium
* Upgraded to 3.6.0 release
-- Adolfo Gómez García <agomez@virtualcable.es> Fri, 1 Jul 2022 14:12:10 +0200
udsclient3 (3.5.0) stable; urgency=medium
* Upgraded to 3.5.0 release
-- Adolfo Gómez García <agomez@virtualcable.es> Fri, 23 Oct 2020 08:12:10 +0200
udsclient3 (3.0.0) stable; urgency=medium
* Upgraded to 3.0.0 release

View File

@ -1 +1 @@
9
10

View File

@ -10,6 +10,6 @@ Package: udsclient3
Section: admin
Priority: optional
Architecture: all
Depends: python3-paramiko (>=2.0.0), python3-crypto, python3-pyqt5 (>=5.0), python3-six(>=1.1), python3 (>=3.6), freerdp2-x11 | freerdp-x11, desktop-file-utils, ${misc:Depends}
Depends: python3-paramiko (>=2.0.0), python3-certifi, python3-cryptography, python3-psutil, python3-pyqt5 (>=5.0), python3 (>=3.6), freerdp2-x11 | freerdp-x11 | freerdp-nightly, desktop-file-utils, ${misc:Depends}
Description: Client connector for Universal Desktop Services (UDS) Broker
This package provides the required components to allow this machine to connect to services provided by UDS Broker.

View File

@ -1,26 +1,38 @@
Format-Specification: http://svn.debian.org/wsvn/dep/web/deps/dep5.mdwn?op=file&rev=135
Name: udsclient3
Maintainer: Adolfo Gómez García
Source: http://www.udsenterprise.com/
Source: http://github.com/dkmstr/openuds/client-py3
Copyright: 2014 Virtual Cable S.L.U.
License: BSD-3-clause
Files: *
Copyright: (c) 2014-2022, Virtual Cable S.L.U.
License: 3-BSD
License: 3-BSD
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 pg_query 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.
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 +1,2 @@
udsclient3_3.0.0_all.deb admin optional
udsclient3_3.0.0_amd64.buildinfo admin optional
udsclient3_4.0.0_all.deb admin optional
udsclient3_4.0.0_amd64.buildinfo admin optional

View File

@ -2,7 +2,7 @@
Name=UDSClient
Comment=UDS Helper
Keywords=uds;client;vdi;
Exec=/usr/lib/UDSClient/UDSClient.py %u
Exec=/usr/lib/UDSClient/UDSClient.py %u -platform xcb
Icon=help-browser
StartupNotify=true
Terminal=false

View File

@ -0,0 +1,69 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<profile>
<profile_id>1126</profile_id>
<profilename>UDSClient</profilename>
<firmware>
<model>IGEL OS 11</model>
<version>11.05.120.01</version>
</firmware>
<description></description>
<overwritesessions>false</overwritesessions>
<is_master_profile>false</is_master_profile>
<is_igel_os>true</is_igel_os>
<settings>
<pclass name="custom_partition.enabled">
<pvalue instancenr="-1" variableExpression="" variableSubstitutionActive="false">true</pvalue>
<variableSubstitutionActive>false</variableSubstitutionActive>
</pclass>
<pclass name="system.security.apparmor">
<pvalue instancenr="-1" variableExpression="" variableSubstitutionActive="false">false</pvalue>
<variableSubstitutionActive>false</variableSubstitutionActive>
</pclass>
<pclass name="custom_partition.mountpoint">
<pvalue instancenr="-1" variableExpression="" variableSubstitutionActive="false">/UDSClient</pvalue>
<variableSubstitutionActive>false</variableSubstitutionActive>
</pclass>
<pclass name="custom_partition.size">
<pvalue instancenr="-1" variableExpression="" variableSubstitutionActive="false">_SIZE_</pvalue>
<variableSubstitutionActive>false</variableSubstitutionActive>
</pclass>
</settings>
<instancesettings>
<instance classprefix="custom_partition.source%" serialnumber="-719cadfe:17ca470644a:-7fff127.0.1.1">
<ivalue classname="custom_partition.source%.autoupdate" variableExpression="" variableSubstitutionActive="false">false</ivalue>
<ivalue classname="custom_partition.source%.crypt_password" variableExpression="" variableSubstitutionActive="false">000d4317311f2c0031133c4d3e4c3d</ivalue>
<ivalue classname="custom_partition.source%.final_action" variableExpression="" variableSubstitutionActive="false"></ivalue>
<ivalue classname="custom_partition.source%.init_action" variableExpression="" variableSubstitutionActive="false">/UDSClient/init.sh</ivalue>
<ivalue classname="custom_partition.source%.password" variableExpression="" variableSubstitutionActive="false"></ivalue>
<ivalue classname="custom_partition.source%.url" variableExpression="" variableSubstitutionActive="false">https://[UMS_SERVER]:8443/ums_filetransfer/UDSClient-igel.inf</ivalue>
<ivalue classname="custom_partition.source%.username" variableExpression="" variableSubstitutionActive="false">[UMS_USERNAME]</ivalue>
</instance>
<instance classprefix="sessions.chromium%" serialnumber="-6b5264e9:17ca6f65505:-8000127.0.1.1">
<ivalue classname="sessions.chromium%.app.browser_startup_page" variableExpression="" variableSubstitutionActive="false">1</ivalue>
<ivalue classname="sessions.chromium%.app.homepage" variableExpression="" variableSubstitutionActive="false">https://demo.udsenterprise.com</ivalue>
<ivalue classname="sessions.chromium%.applaunch" variableExpression="" variableSubstitutionActive="false">true</ivalue>
<ivalue classname="sessions.chromium%.applaunch_path" variableExpression="" variableSubstitutionActive="false"></ivalue>
<ivalue classname="sessions.chromium%.applaunch_system" variableExpression="" variableSubstitutionActive="false">false</ivalue>
<ivalue classname="sessions.chromium%.autostart" variableExpression="" variableSubstitutionActive="false">false</ivalue>
<ivalue classname="sessions.chromium%.autostartnotify" variableExpression="" variableSubstitutionActive="false">false</ivalue>
<ivalue classname="sessions.chromium%.desktop" variableExpression="" variableSubstitutionActive="false">true</ivalue>
<ivalue classname="sessions.chromium%.desktop_path" variableExpression="" variableSubstitutionActive="false"></ivalue>
<ivalue classname="sessions.chromium%.hotkey" variableExpression="" variableSubstitutionActive="false"></ivalue>
<ivalue classname="sessions.chromium%.hotkeymodifier" variableExpression="" variableSubstitutionActive="false">None</ivalue>
<ivalue classname="sessions.chromium%.icon" variableExpression="" variableSubstitutionActive="false">chromium</ivalue>
<ivalue classname="sessions.chromium%.menu_path" variableExpression="" variableSubstitutionActive="false"></ivalue>
<ivalue classname="sessions.chromium%.name" variableExpression="UDS" variableSubstitutionActive="true">###LOC_DEFAULT###</ivalue>
<ivalue classname="sessions.chromium%.position" variableExpression="" variableSubstitutionActive="false">0</ivalue>
<ivalue classname="sessions.chromium%.pulldown" variableExpression="" variableSubstitutionActive="false">false</ivalue>
<ivalue classname="sessions.chromium%.pwprotected" variableExpression="" variableSubstitutionActive="false">none</ivalue>
<ivalue classname="sessions.chromium%.quick_start" variableExpression="" variableSubstitutionActive="false">false</ivalue>
<ivalue classname="sessions.chromium%.scardautostart" variableExpression="" variableSubstitutionActive="false">false</ivalue>
<ivalue classname="sessions.chromium%.snotify" variableExpression="" variableSubstitutionActive="false">true</ivalue>
<ivalue classname="sessions.chromium%.startmenu" variableExpression="" variableSubstitutionActive="false">true</ivalue>
<ivalue classname="sessions.chromium%.startmenu_system" variableExpression="" variableSubstitutionActive="false">false</ivalue>
<ivalue classname="sessions.chromium%.usehotkey" variableExpression="" variableSubstitutionActive="false">false</ivalue>
<ivalue classname="sessions.chromium%.waittime2autostart" variableExpression="" variableSubstitutionActive="false">0</ivalue>
<ivalue classname="sessions.chromium%.waittime2restart" variableExpression="" variableSubstitutionActive="false">0</ivalue>
</instance>
</instancesettings>
</profile>

View File

@ -0,0 +1,7 @@
[INFO]
[PART]
file="UDSClient.tar.bz2"
version="1.1_igel1"
size="_SIZE_"
name="UDSClient"
minfw="11.05.120"

View File

@ -2,7 +2,7 @@
Name=UDSClient
Comment=UDS Helper
Keywords=uds;client;vdi;
Exec=/bin/udsclient %u
Exec=/UDSClient/UDSClient %u
Icon=help-browser
StartupNotify=true
Terminal=false

View File

@ -0,0 +1,2 @@
#!/bin/sh
cp /UDSClient/UDSClient.desktop /usr/share/applications.mime

View File

@ -0,0 +1,15 @@
#!/bin/sh
# Check for root
if ! [ $(id -u) = 0 ]; then
echo "This script must be run as root"
exit 1
fi
echo "Installing UDSClient Portable..."
cp UDSClient-0.0.0-x86_64.AppImage /usr/bin
cp UDSClient.desktop /usr/share/applications
update-desktop-database
echo "Installation process done."

View File

@ -8,6 +8,8 @@ echo "Installation process done."
echo "Remember that the following packages must be installed on system:"
echo "* Python3 paramiko"
echo "* Python3 PyQt5"
echo "* Python3 six"
echo "* Python3 requests"
echo "* Python3 cryptography"
echo "Theese packages (as their names), are dependent on your platform, so you must locate and install them"
echo "Also, ensure that a /media folder exists on your machine, that will be redirected on RDP connections"

View File

@ -0,0 +1,4 @@
# UDS handlers.json
cp "/lib/UDSClient/firefox/handlers.json" "$FIREFOX_PROFILE_HANDLERS"
ffset "network.protocol-handler.external.uds" "true"
ffset "network.protocol-handler.external.udss" "true"

View File

@ -0,0 +1,98 @@
{
"defaultHandlersVersion": {
"en-US": 4
},
"mimeTypes": {
"application/pdf": {
"action": 3,
"extensions": [
"pdf"
]
},
"application/x-ica": {
"action": 2,
"extensions": [
"ica"
],
"handlers": [
{
"name": "wfica",
"path": "/usr/share/hptc-firefox-mgr/handlers/citrix"
}
]
},
"application/x-rdp": {
"action": 2,
"extensions": [
"rdp"
],
"handlers": [
{
"name": "HP xfreerdp",
"path": "/usr/share/hptc-firefox-mgr/handlers/rdp"
}
]
},
"text/lic": {
"action": 2,
"extensions": [
"lic"
],
"handlers": [
{
"name": "Copy license to ThinPro",
"path": "/usr/share/hptc-firefox-mgr/handlers/copy_lic"
}
]
},
"text/xml": {
"action": 3,
"extensions": [
"xml"
]
},
"image/svg+xml": {
"action": 3,
"extensions": [
"svg"
]
},
"image/webp": {
"action": 3,
"extensions": [
"webp"
]
}
},
"schemes": {
"vmware-view": {
"action": 2,
"handlers": [
{
"name": "VMWare Horizon View",
"path": "/usr/share/hptc-firefox-mgr/handlers/vmware"
}
]
},
"uds": {
"action": 2,
"handlers": [
{
"name": "UDS Client for ThinPro (SSL)",
"path": "/usr/share/hptc-firefox-mgr/handlers/uds"
}
]
},
"udss": {
"action": 2,
"handlers": [
{
"name": "UDS Client for ThinPro",
"path": "/usr/share/hptc-firefox-mgr/handlers/uds"
}
]
}
}
}

View File

@ -0,0 +1,5 @@
#!/bin/sh
export LD_PRELOAD=""
/bin/udsclient $*
exit 0

View File

@ -0,0 +1,2 @@
# UDS handlers.json
restore "/lib/UDSClient/firefox/handlers.json" "$FIREFOX_PROFILE_HANDLERS"

View File

@ -0,0 +1,50 @@
{
"defaultHandlersVersion":{
"en-US":4
},
"mimeTypes":{
"application/pdf":{
"action":3,
"extensions":["pdf"]
},
"application/x-ica":{
"action":2,
"handlers":[{
"name":"wfica",
"path":"/usr/bin/hptc-firefox-run-wfica.sh"
}],
"extensions":["ica"]
},
"application/x-rdp":{
"action":2,
"handlers":[{
"name":"HP xfreerdp",
"path":"/usr/bin/hptc-run-rdp-file-freerdp.sh"
}],
"extensions":["rdp"]
}
},
"schemes":{
"vmware-view":{
"action":2,
"handlers":[{
"name":"VMWare Horizon View",
"path":"/usr/bin/vmware-view"
}]
},
"udss":{
"action":2,
"handlers":[{
"name":"UDS Client",
"path":"/bin/udsclient"
}]
},
"uds":{
"action":2,
"handlers":[{
"name":"UDS Client",
"path":"/bin/udsclient"
}]
}
}
}

View File

@ -0,0 +1,37 @@
// This file can be used to configure global preferences for Firefox
// Example: Homepage
//pref("browser.startup.homepage", "http://www.weebls-stuff.com/wab/");
pref("plugin.default.state", 2);
pref("xpinstall.signatures.required", false, locked);
pref("extensions.autoDisableScopes", 0, locked);
pref("extensions.pocket.enabled", false, locked);
pref("extensions.screenshots.disabled", true, locked);
pref("datareporting.policy.dataSubmissionEnabled", false, locked);
pref("datareporting.policy.dataSubmissionEnabled.v2", false, locked);
pref("app.update.auto", false, locked);
pref("app.update.enabled", false, locked);
pref("browser.download.manager.closeWhenDone", true, locked);
pref("browser.helperApps.neverAsk.openFile", "application/x-rdp, application/x-java-jnlp-file", locked);
pref("browser.EULA.3.accepted", true, locked);
pref("browser.rights.3.shown", true, locked);
pref("browser.safebrowsing.enabled", false, locked);
pref("browser.search.update", false, locked);
pref("browser.sessionstore.enabled", false, locked);
pref("browser.sessionhistory.cache_subframes", false, locked);
pref("datareporting.healthreport.service.enabled", false, locked);
pref("datareporting.healthreport.uploadEnabled", false, locked);
pref("devtools.toolbox.host", "none", locked);
pref("extensions.autoDisableScopes", 14, locked);
pref("extensions.blocklist.enabled", false, locked);
pref("extensions.update.enabled", false, locked);
pref("intl.charsetmenu.browser.cache", "UTF-8", locked);
pref("network.protocol-handler.external.mailto", false, locked);
pref("network.protocol-handler.external.news", false, locked);
pref("network.protocol-handler.external.snews", false, locked);
pref("network.protocol-handler.external.nntp", false, locked);
pref("network.protocol-handler.external-default", false, locked);
pref("network.protocol-handler.external.vmware-view", true, locked);
pref("network.protocol-handler.external.uds", true, locked);
pref("network.protocol-handler.external.udss", true, locked);

View File

@ -0,0 +1,38 @@
#!/bin/sh
# Common part
# unlocks so we can write on TC
fsunlock
cp UDSClient /bin/udsclient
chmod 755 /bin/udsclient
# RDP Script for UDSClient. Launchs udsclient using the "Template_UDS" profile
cp udsrdp /usr/bin
INSTALLED=0
# Installation for 7.1.x version
grep -q "7.1" /etc/issue
if [ $? -eq 0 ]; then
echo "Installing for thinpro version 7.1"
# Allow UDS apps without asking
cp firefox7.1/syspref.js /etc/firefox
# Copy handlers.json for firefox
mkdir -p /lib/UDSClient/firefox/ > /dev/null 2>&1
cp firefox7.1/handlers.json /lib/UDSClient/firefox/
# and runner
cp firefox7.1/45-uds /etc/hptc-firefox-mgr/prestart
else
echo "Installing for thinpro version 7.2 or later"
# Copy handlers for firefox
mkdir -p /lib/UDSClient/firefox/ > /dev/null 2>&1
# Copy handlers.json for firefox
cp firefox/handlers.json /lib/UDSClient/firefox/
cp firefox/45-uds /etc/hptc-firefox-mgr/prestart
# copy uds handler for firefox
cp firefox/uds /usr/share/hptc-firefox-mgr/handlers/uds
chmod 755 /usr/share/hptc-firefox-mgr/handlers/uds
fi
# Common part
fslock

View File

@ -0,0 +1,390 @@
#!/bin/bash
function clearParams {
mclient set $REGKEY/address ""
mclient set $REGKEY/username ""
mclient set $REGKEY/password ""
mclient set $REGKEY/domain ""
mclient set $REGKEY/authorizations/user/execution 0
mclient commit
}
function getRegKey {
# Get Template_UDS
for key in `mclient get root/ConnectionType/freerdp/connections | sed "s/dir //g"`; do
val=`mclient get $key/label | sed "s/value //g"`
if [ "$val" == "Template_UDS" ]; then
REGKEY=$key
fi
done
}
function createUDSConnectionTemplate {
TMPFILE=$(mktemp /tmp/udsexport.XXXXXX)
cat > $TMPFILE << EOF
<Profile>
<ProfileSettings>
<Name>UDS Template Profile</Name>
<RegistryRoot>root/ConnectionType/freerdp/connections/{ff064bd9-047a-45ec-b70f-04ab218186ff}</RegistryRoot>
<Target>
<Hardware>t420</Hardware>
<ImageId>T7X62022</ImageId>
<Version>6.2.0</Version>
<Config>standard</Config>
</Target>
</ProfileSettings>
<ProfileRegistry>
<NodeDir name="{ff064bd9-047a-45ec-b70f-04ab218186ff}">
<NodeDir name="rdWebFeed">
<NodeKey name="keepResourcesWindowOpened">
<NodeParam name="value">0</NodeParam>
<NodeParam name="type">bool</NodeParam>
</NodeKey>
<NodeKey name="autoStartSingleResource">
<NodeParam name="value">0</NodeParam>
<NodeParam name="type">bool</NodeParam>
</NodeKey>
<NodeKey name="autoDisconnectTimeout">
<NodeParam name="value">0</NodeParam>
<NodeParam name="type">number</NodeParam>
</NodeKey>
</NodeDir>
<NodeDir name="loginfields">
<NodeKey name="username">
<NodeParam name="value">3</NodeParam>
<NodeParam name="type">number</NodeParam>
</NodeKey>
<NodeKey name="rememberme">
<NodeParam name="value">2</NodeParam>
<NodeParam name="type">number</NodeParam>
</NodeKey>
<NodeKey name="password">
<NodeParam name="value">3</NodeParam>
<NodeParam name="type">number</NodeParam>
</NodeKey>
<NodeKey name="domain">
<NodeParam name="value">3</NodeParam>
<NodeParam name="type">number</NodeParam>
</NodeKey>
</NodeDir>
<NodeDir name="authorizations">
<NodeDir name="user">
<NodeKey name="execution">
<NodeParam name="value">0</NodeParam>
<NodeParam name="type">string</NodeParam>
</NodeKey>
<NodeKey name="edit">
<NodeParam name="value">0</NodeParam>
<NodeParam name="type">string</NodeParam>
</NodeKey>
</NodeDir>
</NodeDir>
<NodeKey name="address">
<NodeParam name="value"/>
<NodeParam name="type">string</NodeParam>
</NodeKey>
<NodeKey name="username">
<NodeParam name="value"/>
<NodeParam name="type">string</NodeParam>
</NodeKey>
<NodeKey name="password">
<NodeParam name="value">NLCR.1</NodeParam>
<NodeParam name="type">rc4</NodeParam>
</NodeKey>
<NodeKey name="domain">
<NodeParam name="value"/>
<NodeParam name="type">string</NodeParam>
</NodeKey>
<NodeKey name="label">
<NodeParam name="value">Template_UDS</NodeParam>
<NodeParam name="type">string</NodeParam>
</NodeKey>
<NodeKey name="credentialsType">
<NodeParam name="value">password</NodeParam>
<NodeParam name="type">string</NodeParam>
</NodeKey>
<NodeKey name="gatewayEnabled">
<NodeParam name="value">0</NodeParam>
<NodeParam name="type">bool</NodeParam>
</NodeKey>
<NodeKey name="gatewayPort">
<NodeParam name="value">443</NodeParam>
<NodeParam name="type">number</NodeParam>
</NodeKey>
<NodeKey name="gatewayUsesSameCredentials">
<NodeParam name="value">1</NodeParam>
<NodeParam name="type">bool</NodeParam>
</NodeKey>
<NodeKey name="gatewayCredentialsType">
<NodeParam name="value">password</NodeParam>
<NodeParam name="type">string</NodeParam>
</NodeKey>
<NodeKey name="remoteDesktopService">
<NodeParam name="value">Remote Computer</NodeParam>
<NodeParam name="type">string</NodeParam>
</NodeKey>
<NodeKey name="windowMode">
<NodeParam name="value">Remote Application</NodeParam>
<NodeParam name="type">string</NodeParam>
</NodeKey>
<NodeKey name="seamlessWindow">
<NodeParam name="value">0</NodeParam>
<NodeParam name="type">bool</NodeParam>
</NodeKey>
<NodeKey name="windowType">
<NodeParam name="value">full</NodeParam>
<NodeParam name="type">string</NodeParam>
</NodeKey>
<NodeKey name="windowSizePercentage">
<NodeParam name="value">70</NodeParam>
<NodeParam name="type">number</NodeParam>
</NodeKey>
<NodeKey name="windowSizeWidth">
<NodeParam name="value">1024</NodeParam>
<NodeParam name="type">number</NodeParam>
</NodeKey>
<NodeKey name="windowSizeHeight">
<NodeParam name="value">768</NodeParam>
<NodeParam name="type">number</NodeParam>
</NodeKey>
<NodeKey name="mouseMotionEvents">
<NodeParam name="value">1</NodeParam>
<NodeParam name="type">bool</NodeParam>
</NodeKey>
<NodeKey name="compression">
<NodeParam name="value">1</NodeParam>
<NodeParam name="type">bool</NodeParam>
</NodeKey>
<NodeKey name="rdpEncryption">
<NodeParam name="value">1</NodeParam>
<NodeParam name="type">bool</NodeParam>
</NodeKey>
<NodeKey name="offScreenBitmaps">
<NodeParam name="value">1</NodeParam>
<NodeParam name="type">bool</NodeParam>
</NodeKey>
<NodeKey name="attachToConsole">
<NodeParam name="value">0</NodeParam>
<NodeParam name="type">bool</NodeParam>
</NodeKey>
<NodeKey name="clipboardExtension">
<NodeParam name="value">1</NodeParam>
<NodeParam name="type">bool</NodeParam>
</NodeKey>
<NodeKey name="rdp6Buffering">
<NodeParam name="value">1</NodeParam>
<NodeParam name="type">bool</NodeParam>
</NodeKey>
<NodeKey name="rdpProgressiveCodec">
<NodeParam name="value">1</NodeParam>
<NodeParam name="type">bool</NodeParam>
</NodeKey>
<NodeKey name="securityLevel">
<NodeParam name="value">0</NodeParam>
<NodeParam name="type">number</NodeParam>
</NodeKey>
<NodeKey name="tlsVersion">
<NodeParam name="value">auto</NodeParam>
<NodeParam name="type">string</NodeParam>
</NodeKey>
<NodeKey name="sound">
<NodeParam name="value">1</NodeParam>
<NodeParam name="type">number</NodeParam>
</NodeKey>
<NodeKey name="printerMapping">
<NodeParam name="value">1</NodeParam>
<NodeParam name="type">number</NodeParam>
</NodeKey>
<NodeKey name="portMapping">
<NodeParam name="value">1</NodeParam>
<NodeParam name="type">number</NodeParam>
</NodeKey>
<NodeKey name="usbStorageRedirection">
<NodeParam name="value">1</NodeParam>
<NodeParam name="type">number</NodeParam>
</NodeKey>
<NodeKey name="localPartitionRedirection">
<NodeParam name="value">1</NodeParam>
<NodeParam name="type">number</NodeParam>
</NodeKey>
<NodeKey name="scRedirection">
<NodeParam name="value">1</NodeParam>
<NodeParam name="type">number</NodeParam>
</NodeKey>
<NodeKey name="usbMiscRedirection">
<NodeParam name="value">2</NodeParam>
<NodeParam name="type">number</NodeParam>
</NodeKey>
<NodeKey name="perfFlagNoWallpaper">
<NodeParam name="value">0</NodeParam>
<NodeParam name="type">number</NodeParam>
</NodeKey>
<NodeKey name="perfFlagFontSmoothing">
<NodeParam name="value">1</NodeParam>
<NodeParam name="type">number</NodeParam>
</NodeKey>
<NodeKey name="perfFlagDesktopComposition">
<NodeParam name="value">1</NodeParam>
<NodeParam name="type">number</NodeParam>
</NodeKey>
<NodeKey name="perfFlagNoWindowDrag">
<NodeParam name="value">0</NodeParam>
<NodeParam name="type">number</NodeParam>
</NodeKey>
<NodeKey name="perfFlagNoMenuAnimations">
<NodeParam name="value">0</NodeParam>
<NodeParam name="type">number</NodeParam>
</NodeKey>
<NodeKey name="perfFlagNoTheming">
<NodeParam name="value">0</NodeParam>
<NodeParam name="type">number</NodeParam>
</NodeKey>
<NodeKey name="timeoutsEnabled">
<NodeParam name="value">1</NodeParam>
<NodeParam name="type">bool</NodeParam>
</NodeKey>
<NodeKey name="timeoutWarning">
<NodeParam name="value">6000</NodeParam>
<NodeParam name="type">number</NodeParam>
</NodeKey>
<NodeKey name="timeoutWarningDialog">
<NodeParam name="value">0</NodeParam>
<NodeParam name="type">bool</NodeParam>
</NodeKey>
<NodeKey name="timeoutRecovery">
<NodeParam name="value">30000</NodeParam>
<NodeParam name="type">number</NodeParam>
</NodeKey>
<NodeKey name="timeoutError">
<NodeParam name="value">0</NodeParam>
<NodeParam name="type">number</NodeParam>
</NodeKey>
<NodeKey name="showRDPDashboard">
<NodeParam name="value">0</NodeParam>
<NodeParam name="type">bool</NodeParam>
</NodeKey>
<NodeKey name="showConnectionGraph">
<NodeParam name="value">0</NodeParam>
<NodeParam name="type">bool</NodeParam>
</NodeKey>
<NodeKey name="x11Synchronous">
<NodeParam name="value">0</NodeParam>
<NodeParam name="type">bool</NodeParam>
</NodeKey>
<NodeKey name="x11Logging">
<NodeParam name="value">0</NodeParam>
<NodeParam name="type">bool</NodeParam>
</NodeKey>
<NodeKey name="x11LogAutoflush">
<NodeParam name="value">0</NodeParam>
<NodeParam name="type">bool</NodeParam>
</NodeKey>
<NodeKey name="x11Capture">
<NodeParam name="value">0</NodeParam>
<NodeParam name="type">bool</NodeParam>
</NodeKey>
<NodeKey name="SingleSignOn">
<NodeParam name="value">1</NodeParam>
<NodeParam name="type">bool</NodeParam>
</NodeKey>
<NodeKey name="autostart">
<NodeParam name="value">0</NodeParam>
<NodeParam name="type">number</NodeParam>
</NodeKey>
<NodeKey name="waitForNetwork">
<NodeParam name="value">1</NodeParam>
<NodeParam name="type">bool</NodeParam>
</NodeKey>
<NodeKey name="hasDesktopIcon">
<NodeParam name="value">0</NodeParam>
<NodeParam name="type">bool</NodeParam>
</NodeKey>
<NodeKey name="autoReconnect">
<NodeParam name="value">0</NodeParam>
<NodeParam name="type">bool</NodeParam>
</NodeKey>
</NodeDir>
</ProfileRegistry>
<ProfileFiles/>
</Profile>
EOF
mclient import $TMPFILE
rm $TMPFILE
}
ADDRESS=
USERNAME=
PASSWORD=
DOMAIN=
REGKEY=
CLEAR=0
# Try to locate registry key for UDS Template
getRegKey
if [ "$REGKEY" == "" ]; then
# Not found, create on based on our template
createUDSConnectionTemplate
getRegKey
fi
for param in $@; do
if [ "/u:" == "${param:0:3}" ]; then
USERNAME=${param:3}
CLEAR=1
fi
if [ "/p:" == "${param:0:3}" ]; then
PASSWORD=${param:3}
CLEAR=1
fi
if [ "/d:" == "${param:0:3}" ]; then
DOMAIN=${param:3}
CLEAR=1
fi
if [ "/v:" == "${param:0:3}" ]; then
ADDRESS=${param:3}
CLEAR=1
fi
done
if [ "$CLEAR" -eq 1 ]; then
clearParams
fi
ID=`basename $REGKEY`
RESPAWN=0
if [ "" != "$ADDRESS" ]; then
mclient set $REGKEY/address "${ADDRESS}"
RESPAWN=1
fi
if [ "" != "$USERNAME" ]; then
mclient set $REGKEY/username "${USERNAME}"
RESPAWN=1
fi
if [ "" != "$PASSWORD" ]; then
mclient set $REGKEY/password "${PASSWORD}"
RESPAWN=1
fi
if [ "" != "$DOMAIN" ]; then
mclient set $REGKEY/domain "${DOMAIN}"
RESPAWN=1
fi
if [ "$RESPAWN" -eq 1 ]; then
mclient set $REGKEY/authorizations/user/execution 1
mclient commit
exec $0 # Restart without command line
fi
process-connection $ID
clearParams

View File

@ -0,0 +1,62 @@
version: 1
script:
# Remove any previous build
- rm -rf /tmp/UDSClientDir | true
# Make usr and icons dirs
- mkdir -p /tmp/UDSClientDir/usr/src
# Copy the python application code into the UDSClientDir
- cp ../src/UDS*.py /tmp/UDSClientDir/usr/src
- cp -r ../src/uds /tmp/UDSClientDir/usr/src
# Remove __pycache__ and .mypy if exists
- rm /tmp/UDSClientDir/usr/src/.mypy_cache -rf 2>&1 > /dev/null
- rm /tmp/UDSClientDir/usr/src/uds/.mypy_cache -rf 2>&1 > /dev/null
- rm /tmp/UDSClientDir/usr/src/__pycache__ -rf 2>&1 > /dev/null
- rm /tmp/UDSClientDir/usr/src/uds/__pycache__ -rf 2>&1 > /dev/null
AppDir:
# On /tmp, that is an ext4 filesystem. On btrfs squashfs complains with "Unrecognised xattr prefix btrfs.compression"
path: /tmp/UDSClientDir
app_info:
id: com.udsenterprise.UDSClient3
name: UDSClient
icon: utilities-terminal
version: 0.0.0
# Set the python executable as entry point
exec: usr/bin/python3
# Set the application main script path as argument. Use '$@' to forward CLI parameters
exec_args: "$APPDIR/usr/src/UDSClient.py $@"
apt:
arch: amd64
sources:
- sourceline: 'deb [arch=amd64] http://ftp.de.debian.org/debian/ bullseye main contrib non-free'
key_url: 'http://keyserver.ubuntu.com/pks/lookup?op=get&search=0x648ACFD622F3D138'
include:
- python3
- python3-pkg-resources
- python3-pyqt5
- python3-paramiko
- python3-cryptography
- python3-certifi
- python3-psutil
- freerdp2-x11
- freerdp2-wayland
- x2goclient
- openssh-sftp-server
exclude: []
runtime:
env:
# Set python home
# See https://docs.python.org/3/using/cmdline.html#envvar-PYTHONHOME
PYTHONHOME: '${APPDIR}/usr'
# Path to the site-packages dir or other modules dirs
# See https://docs.python.org/3/using/cmdline.html#envvar-PYTHONPATH
PYTHONPATH: '${APPDIR}/usr/lib/python3.9/site-packages'
AppImage:
update-information: None
sign-key: None
arch: x86_64

View File

@ -11,7 +11,7 @@ Release: %{release}
Summary: Client for Universal Desktop Services (UDS) Broker
License: BSD3
Group: Applications/Productivity
Requires: python3-six python3-requests python3-paramiko python3-qt5 (python3-crypto or python3-pycrypto)
Requires: python3-paramiko python3-qt5 python3-cryptography python3-certifi python3-psutil
Vendor: Virtual Cable S.L.U.
URL: http://www.udsenterprise.com
Provides: udsclient

View File

@ -1,4 +1,6 @@
/build
/dist
UDSClient.dmg
UDSClient.pkg
/UDSClient*.pkg
/UDSClient*.dist
/UDSClient*.build
/.eggs

View File

@ -1,7 +1,7 @@
#!/usr/bin/env python3
#!/usr/bin/env -S python3 -s
# -*- coding: utf-8 -*-
#
# Copyright (c) 2014-2017 Virtual Cable S.L.
# Copyright (c) 2014-2021 Virtual Cable S.L.U.
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without modification,
@ -12,7 +12,7 @@
# * 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
# * Neither the name of Virtual Cable S.L.U. nor the names of its contributors
# may be used to endorse or promote products derived from this software
# without specific prior written permission.
#
@ -31,41 +31,45 @@
@author: Adolfo Gómez, dkmaster at dkmon dot com
'''
import sys
import os
import platform
import time
import webbrowser
import json
import base64, bz2
import threading
import typing
from PyQt5 import QtCore, QtGui, QtWidgets # @UnresolvedImport
import six
from PyQt5 import QtCore, QtWidgets, QtGui
from PyQt5.QtCore import QSettings
from uds.rest import RestApi, RetryException, InvalidVersion, UDSException
# Just to ensure there are available on runtime
from uds.forward import forward as ssh_forward # type: ignore
from uds.tunnel import forward as tunnel_forwards # type: ignore
from uds.rest import RestRequest
from uds.forward import forward # pylint: disable=unused-import
from uds.log import logger
from uds import tools
from uds import VERSION
from UDSWindow import Ui_MainWindow
# Server before this version uses "unsigned" scripts
OLD_METHOD_VERSION = '2.4.0'
class RetryException(Exception):
pass
class UDSClient(QtWidgets.QMainWindow):
ticket = None
scrambler = None
ticket: str = ''
scrambler: str = ''
withError = False
animTimer = None
anim = 0
animInverted = False
serverVersion = 'X.Y.Z' # Will be overwriten on getVersion
req = None
animTimer: typing.Optional[QtCore.QTimer] = None
anim: int = 0
animInverted: bool = False
api: RestApi
def __init__(self):
def __init__(self, api: RestApi, ticket: str, scrambler: str):
QtWidgets.QMainWindow.__init__(self)
self.setWindowFlags(QtCore.Qt.FramelessWindowHint | QtCore.Qt.WindowStaysOnTopHint)
self.api = api
self.ticket = ticket
self.scrambler = scrambler
self.setWindowFlags(QtCore.Qt.FramelessWindowHint | QtCore.Qt.WindowStaysOnTopHint) # type: ignore
self.ui = Ui_MainWindow()
self.ui.setupUi(self)
@ -75,41 +79,36 @@ class UDSClient(QtWidgets.QMainWindow):
self.ui.info.setText('Initializing...')
screen = QtWidgets.QDesktopWidget().screenGeometry()
screen_geometry = QtGui.QGuiApplication.primaryScreen().geometry()
mysize = self.geometry()
hpos = (screen.width() - mysize.width()) // 2
vpos = (screen.height() - mysize.height() - mysize.height()) // 2
hpos = (screen_geometry.width() - mysize.width()) // 2
vpos = (screen_geometry.height() - mysize.height() - mysize.height()) // 2
self.move(hpos, vpos)
self.animTimer = QtCore.QTimer()
self.animTimer.timeout.connect(self.updateAnim)
self.animTimer.timeout.connect(self.updateAnim) # type: ignore
# QtCore.QObject.connect(self.animTimer, QtCore.SIGNAL('timeout()'), self.updateAnim)
self.activateWindow()
self.startAnim()
def closeWindow(self):
self.close()
def processError(self, data):
if 'error' in data:
# QtWidgets.QMessageBox.critical(self, 'Request error {}'.format(data.get('retryable', '0')), data['error'], QtWidgets.QMessageBox.Ok)
if data.get('retryable', '0') == '1':
raise RetryException(data['error'])
raise Exception(data['error'])
# QtWidgets.QMessageBox.critical(self, 'Request error', rest.data['error'], QtWidgets.QMessageBox.Ok)
# self.closeWindow()
# return
def showError(self, error):
logger.error('got error: %s', error)
self.stopAnim()
self.ui.info.setText('UDS Plugin Error') # In fact, main window is hidden, so this is not visible... :)
self.ui.info.setText(
'UDS Plugin Error'
) # In fact, main window is hidden, so this is not visible... :)
self.closeWindow()
QtWidgets.QMessageBox.critical(None, 'UDS Plugin Error', '{}'.format(error), QtWidgets.QMessageBox.Ok)
QtWidgets.QMessageBox.critical(
None, # type: ignore
'UDS Plugin Error',
'{}'.format(error),
QtWidgets.QMessageBox.Ok,
)
self.withError = True
def cancelPushed(self):
@ -125,165 +124,227 @@ class UDSClient(QtWidgets.QMainWindow):
self.ui.progressBar.setValue(self.anim)
def startAnim(self):
self.ui.progressBar.invertedAppearance = False
self.ui.progressBar.invertedAppearance = False # type: ignore
self.anim = 0
self.animInverted = False
self.ui.progressBar.setInvertedAppearance(self.animInverted)
self.animTimer.start(40)
if self.animTimer:
self.animTimer.start(40)
def stopAnim(self):
self.ui.progressBar.invertedAppearance = False
self.animTimer.stop()
self.ui.progressBar.invertedAppearance = False # type: ignore
if self.animTimer:
self.animTimer.stop()
def getVersion(self):
self.req = RestRequest('', self, self.version)
self.req.get()
def version(self, data):
try:
self.processError(data)
self.ui.info.setText('Processing...')
if data['result']['requiredVersion'] > VERSION:
QtWidgets.QMessageBox.critical(self, 'Upgrade required', 'A newer connector version is required.\nA browser will be opened to download it.', QtWidgets.QMessageBox.Ok)
webbrowser.open(data['result']['downloadUrl'])
self.closeWindow()
return
self.serverVersion = data['result']['requiredVersion']
self.getTransportData()
except RetryException as e:
self.ui.info.setText(str(e))
QtCore.QTimer.singleShot(1000, self.getVersion)
self.api.getVersion()
except InvalidVersion as e:
QtWidgets.QMessageBox.critical(
self,
'Upgrade required',
'A newer connector version is required.\nA browser will be opened to download it.',
QtWidgets.QMessageBox.Ok,
)
webbrowser.open(e.downloadUrl)
self.closeWindow()
return
except Exception as e:
self.showError(e)
self.getTransportData()
def getTransportData(self):
try:
self.req = RestRequest('/{}/{}'.format(self.ticket, self.scrambler), self, self.transportDataReceived, params={'hostname': tools.getHostName(), 'version': VERSION})
self.req.get()
except Exception as e:
logger.exception('Got exception on getTransportData')
raise e
def transportDataReceived(self, data):
logger.debug('Transport data received')
try:
self.processError(data)
params = None
if self.serverVersion <= OLD_METHOD_VERSION:
script = bz2.decompress(base64.b64decode(data['result']))
# This fixes uds 2.2 "write" string on binary streams on some transport
script = script.replace(b'stdin.write("', b'stdin.write(b"')
script = script.replace(b'version)', b'version.decode("utf-8"))')
else:
res = data['result']
# We have three elements on result:
# * Script
# * Signature
# * Script data
# We test that the Script has correct signature, and them execute it with the parameters
#script, signature, params = res['script'].decode('base64').decode('bz2'), res['signature'], json.loads(res['params'].decode('base64').decode('bz2'))
script, signature, params = bz2.decompress(base64.b64decode(res['script'])), res['signature'], json.loads(bz2.decompress(base64.b64decode(res['params'])))
if tools.verifySignature(script, signature) is False:
logger.error('Signature is invalid')
raise Exception('Invalid UDS code signature. Please, report to administrator')
script, params = self.api.getScriptAndParams(self.ticket, self.scrambler)
self.stopAnim()
if 'darwin' in sys.platform:
self.showMinimized()
QtCore.QTimer.singleShot(3000, self.endScript)
self.hide()
# QtCore.QTimer.singleShot(3000, self.endScript)
# self.hide()
self.closeWindow()
six.exec_(script.decode("utf-8"), globals(), {'parent': self, 'sp': params})
exec(script, globals(), {'parent': self, 'sp': params})
# Execute the waiting tasks...
threading.Thread(target=endScript).start()
except RetryException as e:
self.ui.info.setText(six.text_type(e) + ', retrying access...')
self.ui.info.setText(str(e) + ', retrying access...')
# Retry operation in ten seconds
QtCore.QTimer.singleShot(10000, self.getTransportData)
except Exception as e:
#logger.exception('Got exception executing script:')
self.showError(e)
def endScript(self):
# After running script, wait for stuff
try:
tools.waitForTasks()
except Exception:
pass
try:
tools.unlinkFiles()
except Exception:
pass
try:
tools.execBeforeExit()
except Exception:
pass
self.closeWindow()
def start(self):
'''
"""
Starts proccess by requesting version info
'''
"""
self.ui.info.setText('Initializing...')
QtCore.QTimer.singleShot(100, self.getVersion)
def done(data):
QtWidgets.QMessageBox.critical(None, 'Notice', six.text_type(data.data), QtWidgets.QMessageBox.Ok)
sys.exit(0)
def endScript():
# Wait a bit before start processing ending sequence
time.sleep(3)
try:
# Remove early stage files...
tools.unlinkFiles(early=True)
except Exception as e:
logger.debug('Unlinking files on early stage: %s', e)
# After running script, wait for stuff
try:
logger.debug('Wating for tasks to finish...')
tools.waitForTasks()
except Exception as e:
logger.debug('Watiting for tasks to finish: %s', e)
try:
logger.debug('Unlinking files')
tools.unlinkFiles(early=False)
except Exception as e:
logger.debug('Unlinking files on later stage: %s', e)
# Removing
try:
logger.debug('Executing threads before exit')
tools.execBeforeExit()
except Exception as e:
logger.debug('execBeforeExit: %s', e)
logger.debug('endScript done')
# Ask user to approve endpoint
def approveHost(hostName, parentWindow=None):
def approveHost(hostName: str):
settings = QtCore.QSettings()
settings.beginGroup('endpoints')
#approved = settings.value(hostName, False).toBool()
# approved = settings.value(hostName, False).toBool()
approved = bool(settings.value(hostName, False))
errorString = '<p>The server <b>{}</b> must be approved:</p>'.format(hostName)
errorString += '<p>Only approve UDS servers that you trust to avoid security issues.</p>'
errorString += (
'<p>Only approve UDS servers that you trust to avoid security issues.</p>'
)
if approved or QtWidgets.QMessageBox.warning(parentWindow, 'ACCESS Warning', errorString, QtWidgets.QMessageBox.Yes | QtWidgets.QMessageBox.No) == QtWidgets.QMessageBox.Yes:
settings.setValue(hostName, True)
approved = True
if not approved:
if (
QtWidgets.QMessageBox.warning(
None, # type: ignore
'ACCESS Warning',
errorString,
QtWidgets.QMessageBox.Yes | QtWidgets.QMessageBox.No, # type: ignore
)
== QtWidgets.QMessageBox.Yes
):
settings.setValue(hostName, True)
approved = True
settings.endGroup()
return approved
if __name__ == "__main__":
logger.debug('Initializing connector')
# Initialize app
def sslError(hostname: str, serial):
settings = QSettings()
settings.beginGroup('ssl')
approved = settings.value(serial, False)
if (
approved
or QtWidgets.QMessageBox.warning(
None, # type: ignore
'SSL Warning',
f'Could not check SSL certificate for {hostname}.\nDo you trust this host?',
QtWidgets.QMessageBox.Yes | QtWidgets.QMessageBox.No, # type: ignore
)
== QtWidgets.QMessageBox.Yes
):
approved = True
settings.setValue(serial, True)
settings.endGroup()
return approved
# Used only if command line says so
def minimal(api: RestApi, ticket: str, scrambler: str):
try:
logger.info('Minimal Execution')
logger.debug('Getting version')
try:
api.getVersion()
except InvalidVersion as e:
QtWidgets.QMessageBox.critical(
None, # type: ignore
'Upgrade required',
'A newer connector version is required.\nA browser will be opened to download it.',
QtWidgets.QMessageBox.Ok,
)
webbrowser.open(e.downloadUrl)
return 0
logger.debug('Transport data')
script, params = api.getScriptAndParams(ticket, scrambler)
# Execute UDS transport script
exec(script, globals(), {'parent': None, 'sp': params})
# Execute the waiting task...
threading.Thread(target=endScript).start()
except RetryException as e:
QtWidgets.QMessageBox.warning(
None, # type: ignore
'Service not ready',
'{}'.format('.\n'.join(str(e).split('.')))
+ '\n\nPlease, retry again in a while.',
QtWidgets.QMessageBox.Ok,
)
except Exception as e:
# logger.exception('Got exception on getTransportData')
QtWidgets.QMessageBox.critical(
None, # type: ignore
'Error',
'{}'.format(str(e)) + '\n\nPlease, retry again in a while.',
QtWidgets.QMessageBox.Ok,
)
return 0
def main(args: typing.List[str]):
app = QtWidgets.QApplication(sys.argv)
logger.debug('Initializing connector for %s(%s)', sys.platform, platform.machine())
logger.debug('Arguments: %s', args)
# Set several info for settings
QtCore.QCoreApplication.setOrganizationName('Virtual Cable S.L.U.')
QtCore.QCoreApplication.setApplicationName('UDS Connector')
if 'darwin' not in sys.platform:
logger.debug('Mac OS *NOT* Detected')
app.setStyle('plastique')
if six.PY3 is False:
logger.debug('Fixing threaded execution of commands')
import threading
threading._DummyThread._Thread__stop = lambda x: 42 # type: ignore # pylint: disable=protected-access
app.setStyle('plastique') # type: ignore
else:
logger.debug('Platform is Mac OS, adding homebrew possible paths')
os.environ['PATH'] += ''.join(
os.pathsep + i
for i in (
'/usr/local/bin',
'/opt/homebrew/bin',
)
)
logger.debug('Now path is %s', os.environ['PATH'])
# First parameter must be url
useMinimal = False
try:
uri = sys.argv[1]
uri = args[1]
if uri == '--minimal':
useMinimal = True
uri = args[2] # And get URI
if uri == '--test':
sys.exit(0)
@ -293,17 +354,28 @@ if __name__ == "__main__":
raise Exception()
ssl = uri[3] == 's'
host, UDSClient.ticket, UDSClient.scrambler = uri.split('//')[1].split('/') # type: ignore
logger.debug('ssl:%s, host:%s, ticket:%s, scrambler:%s', ssl, host, UDSClient.ticket, UDSClient.scrambler)
host, ticket, scrambler = uri.split('//')[1].split('/') # type: ignore
logger.debug(
'ssl:%s, host:%s, ticket:%s, scrambler:%s',
ssl,
host,
ticket,
scrambler,
)
except Exception:
logger.debug('Detected execution without valid URI, exiting')
QtWidgets.QMessageBox.critical(None, 'Notice', 'UDS Client Version {}'.format(VERSION), QtWidgets.QMessageBox.Ok)
QtWidgets.QMessageBox.critical(
None, # type: ignore
'Notice',
'UDS Client Version {}'.format(VERSION),
QtWidgets.QMessageBox.Ok,
)
sys.exit(1)
# Setup REST api endpoint
RestRequest.restApiUrl = '{}://{}/rest/client'.format(['http', 'https'][ssl], host)
logger.debug('Setting request URL to %s', RestRequest.restApiUrl)
# RestRequest.restApiUrl = 'https://172.27.0.1/rest/client'
api = RestApi(
'{}://{}/uds/rest/client'.format(['http', 'https'][ssl], host), sslError
)
try:
logger.debug('Starting execution')
@ -312,18 +384,23 @@ if __name__ == "__main__":
if approveHost(host) is False:
raise Exception('Host {} was not approved'.format(host))
win = UDSClient()
win = UDSClient(api, ticket, scrambler)
win.show()
win.start()
exitVal = app.exec_()
exitVal = app.exec()
logger.debug('Execution finished correctly')
except Exception as e:
logger.exception('Got an exception executing client:')
exitVal = 128
QtWidgets.QMessageBox.critical(None, 'Error', six.text_type(e), QtWidgets.QMessageBox.Ok)
QtWidgets.QMessageBox.critical(
None, 'Error', str(e), QtWidgets.QMessageBox.Ok # type: ignore
)
logger.debug('Exiting')
sys.exit(exitVal)
if __name__ == "__main__":
main(sys.argv)

View File

@ -0,0 +1,75 @@
import sys
import os.path
import subprocess
import typing
from uds.log import logger
import UDSClient
from UDSLauncherMac import Ui_MacLauncher
from PyQt5 import QtCore, QtWidgets, QtGui
SCRIPT_NAME = 'UDSClientLauncher'
class UdsApplication(QtWidgets.QApplication):
path: str
tunnels: typing.List[subprocess.Popen]
def __init__(self, argv: typing.List[str]) -> None:
super().__init__(argv)
self.path = os.path.join(os.path.dirname(sys.argv[0]).replace('Resources', 'MacOS'), SCRIPT_NAME)
self.tunnels = []
self.lastWindowClosed.connect(self.closeTunnels) # type: ignore
def cleanTunnels(self) -> None:
def isRunning(p: subprocess.Popen):
try:
if p.poll() is None:
return True
except Exception as e:
logger.debug('Got error polling subprocess: %s', e)
return False
for k in [i for i, tunnel in enumerate(self.tunnels) if not isRunning(tunnel)]:
try:
del self.tunnels[k]
except Exception as e:
logger.debug('Error closing tunnel: %s', e)
def closeTunnels(self) -> None:
logger.debug('Closing remaining tunnels')
for tunnel in self.tunnels:
logger.debug('Checking %s - "%s"', tunnel, tunnel.poll())
if tunnel.poll() is None: # Running
logger.info('Found running tunnel %s, closing it', tunnel.pid)
tunnel.kill()
def event(self, evnt: QtCore.QEvent) -> bool:
if evnt.type() == QtCore.QEvent.FileOpen: # type: ignore
fe = typing.cast(QtGui.QFileOpenEvent, evnt)
logger.debug('Got url: %s', fe.url().url())
fe.accept()
logger.debug('Spawning %s', self.path)
# First, remove all finished tunnel processed from check queue
self.cleanTunnels()
# And now add a new one
self.tunnels.append(subprocess.Popen([self.path, fe.url().url()]))
return super().event(evnt)
def main(args: typing.List[str]):
if len(args) > 1:
UDSClient.main(args)
else:
app = UdsApplication(sys.argv)
window = QtWidgets.QMainWindow()
Ui_MacLauncher().setupUi(window)
window.showMinimized()
sys.exit(app.exec())
if __name__ == "__main__":
main(args=sys.argv)

View File

@ -0,0 +1,75 @@
# -*- coding: utf-8 -*-
# Form implementation generated from reading ui file 'UDSLauncherMac.ui'
#
# Created by: PyQt5 UI code generator 5.15.2
#
# WARNING: Any manual changes made to this file will be lost when pyuic5 is
# run again. Do not edit this file unless you know what you are doing.
from PyQt5 import QtCore, QtGui, QtWidgets
class Ui_MacLauncher(object):
def setupUi(self, MacLauncher):
MacLauncher.setObjectName("MacLauncher")
MacLauncher.setWindowModality(QtCore.Qt.NonModal)
MacLauncher.resize(235, 120)
MacLauncher.setCursor(QtGui.QCursor(QtCore.Qt.ArrowCursor))
icon = QtGui.QIcon()
icon.addPixmap(QtGui.QPixmap(":/images/logo-uds-small"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
MacLauncher.setWindowIcon(icon)
MacLauncher.setWindowOpacity(1.0)
self.centralwidget = QtWidgets.QWidget(MacLauncher)
self.centralwidget.setAutoFillBackground(True)
self.centralwidget.setObjectName("centralwidget")
self.verticalLayout_2 = QtWidgets.QVBoxLayout(self.centralwidget)
self.verticalLayout_2.setContentsMargins(4, 4, 4, 4)
self.verticalLayout_2.setSpacing(4)
self.verticalLayout_2.setObjectName("verticalLayout_2")
self.frame = QtWidgets.QFrame(self.centralwidget)
self.frame.setFrameShape(QtWidgets.QFrame.StyledPanel)
self.frame.setFrameShadow(QtWidgets.QFrame.Raised)
self.frame.setObjectName("frame")
self.verticalLayout = QtWidgets.QVBoxLayout(self.frame)
self.verticalLayout.setObjectName("verticalLayout")
self.topLabel = QtWidgets.QLabel(self.frame)
self.topLabel.setTextFormat(QtCore.Qt.RichText)
self.topLabel.setObjectName("topLabel")
self.verticalLayout.addWidget(self.topLabel)
self.image = QtWidgets.QLabel(self.frame)
self.image.setMinimumSize(QtCore.QSize(0, 32))
self.image.setAutoFillBackground(True)
self.image.setText("")
self.image.setPixmap(QtGui.QPixmap(":/images/logo-uds-small"))
self.image.setScaledContents(False)
self.image.setAlignment(QtCore.Qt.AlignCenter)
self.image.setObjectName("image")
self.verticalLayout.addWidget(self.image)
self.label_2 = QtWidgets.QLabel(self.frame)
self.label_2.setTextFormat(QtCore.Qt.RichText)
self.label_2.setObjectName("label_2")
self.verticalLayout.addWidget(self.label_2)
self.verticalLayout_2.addWidget(self.frame)
MacLauncher.setCentralWidget(self.centralwidget)
self.retranslateUi(MacLauncher)
QtCore.QMetaObject.connectSlotsByName(MacLauncher)
def retranslateUi(self, MacLauncher):
_translate = QtCore.QCoreApplication.translate
MacLauncher.setWindowTitle(_translate("MacLauncher", "UDS Launcher"))
self.topLabel.setText(_translate("MacLauncher", "<html><head/><body><p align=\"center\"><span style=\" font-size:12pt; font-weight:600;\">UDS Launcher</span></p></body></html>"))
self.label_2.setText(_translate("MacLauncher", "<html><head/><body><p align=\"center\"><span style=\" font-size:6pt;\">Closing this window will end all UDS tunnels</span></p></body></html>"))
import UDSResources_rc
if __name__ == "__main__":
import sys
app = QtWidgets.QApplication(sys.argv)
MacLauncher = QtWidgets.QMainWindow()
ui = Ui_MacLauncher()
ui.setupUi(MacLauncher)
MacLauncher.show()
sys.exit(app.exec())

View File

@ -0,0 +1,113 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>MacLauncher</class>
<widget class="QMainWindow" name="MacLauncher">
<property name="windowModality">
<enum>Qt::NonModal</enum>
</property>
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>235</width>
<height>120</height>
</rect>
</property>
<property name="cursor">
<cursorShape>ArrowCursor</cursorShape>
</property>
<property name="windowTitle">
<string>UDS Launcher</string>
</property>
<property name="windowIcon">
<iconset resource="UDSResources.qrc">
<normaloff>:/images/logo-uds-small</normaloff>:/images/logo-uds-small</iconset>
</property>
<property name="windowOpacity">
<double>1.000000000000000</double>
</property>
<widget class="QWidget" name="centralwidget">
<property name="autoFillBackground">
<bool>true</bool>
</property>
<layout class="QVBoxLayout" name="verticalLayout_2">
<property name="spacing">
<number>4</number>
</property>
<property name="leftMargin">
<number>4</number>
</property>
<property name="topMargin">
<number>4</number>
</property>
<property name="rightMargin">
<number>4</number>
</property>
<property name="bottomMargin">
<number>4</number>
</property>
<item>
<widget class="QFrame" name="frame">
<property name="frameShape">
<enum>QFrame::StyledPanel</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Raised</enum>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QLabel" name="topLabel">
<property name="text">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p align=&quot;center&quot;&gt;&lt;span style=&quot; font-size:12pt; font-weight:600;&quot;&gt;UDS Launcher&lt;/span&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="textFormat">
<enum>Qt::RichText</enum>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="image">
<property name="minimumSize">
<size>
<width>0</width>
<height>32</height>
</size>
</property>
<property name="autoFillBackground">
<bool>true</bool>
</property>
<property name="text">
<string notr="true"/>
</property>
<property name="pixmap">
<pixmap resource="UDSResources.qrc">:/images/logo-uds-small</pixmap>
</property>
<property name="scaledContents">
<bool>false</bool>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="label_2">
<property name="text">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p align=&quot;center&quot;&gt;&lt;span style=&quot; font-size:6pt;&quot;&gt;Closing this window will end all UDS tunnels&lt;/span&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="textFormat">
<enum>Qt::RichText</enum>
</property>
</widget>
</item>
</layout>
</widget>
</item>
</layout>
</widget>
</widget>
<resources>
<include location="UDSResources.qrc"/>
</resources>
<connections/>
</ui>

View File

@ -2,7 +2,7 @@
# Resource object code
#
# Created by: The Resource Compiler for PyQt5 (Qt v5.13.2)
# Created by: The Resource Compiler for PyQt5 (Qt v5.15.2)
#
# WARNING! All changes made in this file will be lost!

View File

@ -2,9 +2,10 @@
# Form implementation generated from reading ui file 'UDSWindow.ui'
#
# Created by: PyQt5 UI code generator 5.13.2
# Created by: PyQt5 UI code generator 5.15.2
#
# WARNING! All changes made in this file will be lost!
# WARNING: Any manual changes made to this file will be lost when pyuic5 is
# run again. Do not edit this file unless you know what you are doing.
from PyQt5 import QtCore, QtGui, QtWidgets
@ -89,4 +90,4 @@ if __name__ == "__main__":
ui = Ui_MainWindow()
ui.setupUi(MainWindow)
MainWindow.show()
sys.exit(app.exec_())
sys.exit(app.exec())

View File

@ -1,6 +1,6 @@
# -*- coding: utf-8 -*-
#
# Copyright (c) 2014-2017 Virtual Cable S.L.
# Copyright (c) 2014-2021 Virtual Cable S.L.
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without modification,
@ -29,13 +29,11 @@
'''
@author: Adolfo Gómez, dkmaster at dkmon dot com
'''
from __future__ import unicode_literals
VERSION = '3.0.0'
VERSION = '3.6.0'
__title__ = 'udclient'
__version__ = VERSION
__build__ = 0x010760
__author__ = 'Adolfo Gómez'
__build__ = 0x010712
__author__ = 'Adolfo Gómez <dkmaster@dkmon.com>'
__license__ = "BSD 3-clause"
__copyright__ = "Copyright 2014-2017 VirtualCable S.L.U."
__copyright__ = "Copyright 2014-2022 VirtualCable S.L.U."

View File

@ -9,6 +9,7 @@ import random
import time
import select
import socketserver
import typing
import paramiko
@ -24,7 +25,11 @@ class CheckfingerPrints(paramiko.MissingHostKeyPolicy):
if self.fingerPrints:
remotefingerPrints = hexlify(key.get_fingerprint()).decode().lower()
if remotefingerPrints not in self.fingerPrints.split(','):
logger.error("Server {!r} has invalid fingerPrints. ({} vs {})".format(hostname, remotefingerPrints, self.fingerPrints))
logger.error(
"Server {!r} has invalid fingerPrints. ({} vs {})".format(
hostname, remotefingerPrints, self.fingerPrints
)
)
raise paramiko.SSHException(
"Server {!r} has invalid fingerPrints".format(hostname)
)
@ -36,26 +41,49 @@ class ForwardServer(socketserver.ThreadingTCPServer):
class Handler(socketserver.BaseRequestHandler):
event: threading.Event
thread: 'ForwardThread'
ssh_transport: paramiko.Transport
chain_host: str
chain_port: int
def handle(self):
self.thread.currentConnections += 1
try:
chan = self.ssh_transport.open_channel('direct-tcpip',
(self.chain_host, self.chain_port),
self.request.getpeername())
chan = self.ssh_transport.open_channel(
'direct-tcpip',
(self.chain_host, self.chain_port),
self.request.getpeername(),
)
except Exception as e:
logger.exception('Incoming request to %s:%d failed: %s', self.chain_host, self.chain_port, repr(e))
logger.exception(
'Incoming request to %s:%d failed: %s',
self.chain_host,
self.chain_port,
repr(e),
)
return
if chan is None:
logger.error('Incoming request to %s:%d was rejected by the SSH server.', self.chain_host, self.chain_port)
logger.error(
'Incoming request to %s:%d was rejected by the SSH server.',
self.chain_host,
self.chain_port,
)
return
logger.debug('Connected! Tunnel open %r -> %r -> %r', self.request.getpeername(), chan.getpeername(), (self.chain_host, self.chain_port))
logger.debug(
'Connected! Tunnel open %r -> %r -> %r',
self.request.getpeername(),
chan.getpeername(),
(self.chain_host, self.chain_port),
)
# self.ssh_transport.set_keepalive(10) # Keep alive every 10 seconds...
try:
while self.event.is_set() is False:
r, _w, _x = select.select([self.request, chan], [], [], 1) # pylint: disable=unused-variable
r, _w, _x = select.select(
[self.request, chan], [], [], 1
) # pylint: disable=unused-variable
if self.request in r:
data = self.request.recv(1024)
@ -74,7 +102,10 @@ class Handler(socketserver.BaseRequestHandler):
peername = self.request.getpeername()
chan.close()
self.request.close()
logger.debug('Tunnel closed from %r', peername,)
logger.debug(
'Tunnel closed from %r',
peername,
)
except Exception:
pass
@ -86,8 +117,21 @@ class Handler(socketserver.BaseRequestHandler):
class ForwardThread(threading.Thread):
status = 0 # Connecting
client: typing.Optional[paramiko.SSHClient]
fs: typing.Optional[ForwardServer]
def __init__(self, server, port, username, password, localPort, redirectHost, redirectPort, waitTime, fingerPrints):
def __init__(
self,
server,
port,
username,
password,
localPort,
redirectHost,
redirectPort,
waitTime,
fingerPrints,
):
threading.Thread.__init__(self)
self.client = None
self.fs = None
@ -116,9 +160,19 @@ class ForwardThread(threading.Thread):
if localPort is None:
localPort = random.randrange(33000, 53000)
ft = ForwardThread(self.server, self.port, self.username, self.password, localPort, redirectHost, redirectPort, self.waitTime, self.fingerPrints)
ft = ForwardThread(
self.server,
self.port,
self.username,
self.password,
localPort,
redirectHost,
redirectPort,
self.waitTime,
self.fingerPrints,
)
ft.client = self.client
self.client.useCount += 1 # One more using this client
self.client.useCount += 1 # type: ignore
ft.start()
while ft.status == 0:
@ -126,7 +180,6 @@ class ForwardThread(threading.Thread):
return (ft, localPort)
def _timerFnc(self):
self.timer = None
logger.debug('Timer fnc: %s', self.currentConnections)
@ -138,14 +191,23 @@ class ForwardThread(threading.Thread):
if self.client is None:
try:
self.client = paramiko.SSHClient()
self.client.useCount = 1 # Custom added variable, to keep track on when to close tunnel
self.client.useCount = 1 # type: ignore
self.client.load_system_host_keys()
self.client.set_missing_host_key_policy(CheckfingerPrints(self.fingerPrints))
self.client.set_missing_host_key_policy(
CheckfingerPrints(self.fingerPrints)
)
logger.debug('Connecting to ssh host %s:%d ...', self.server, self.port)
# To disable ssh-ageng asking for passwords: allow_agent=False
self.client.connect(self.server, self.port, username=self.username, password=self.password, timeout=5, allow_agent=False)
self.client.connect(
self.server,
self.port,
username=self.username,
password=self.password,
timeout=5,
allow_agent=False,
)
except Exception:
logger.exception('Exception connecting: ')
self.status = 2 # Error
@ -173,18 +235,30 @@ class ForwardThread(threading.Thread):
self.timer.cancel()
self.stopEvent.set()
self.fs.shutdown()
if self.fs:
self.fs.shutdown()
if self.client is not None:
self.client.useCount -= 1
if self.client.useCount == 0:
self.client.useCount -= 1 # type: ignore
if self.client.useCount == 0: # type: ignore
self.client.close()
self.client = None # Clean up
except Exception:
logger.exception('Exception stopping')
def forward(server, port, username, password, redirectHost, redirectPort, localPort=None, waitTime=10, fingerPrints=None):
def forward(
server,
port,
username,
password,
redirectHost,
redirectPort,
localPort=None,
waitTime=10,
fingerPrints=None,
):
'''
Instantiates an ssh connection to server:port
Returns the Thread created and the local redirected port as a list: (thread, port)
@ -194,10 +268,28 @@ def forward(server, port, username, password, redirectHost, redirectPort, localP
if localPort is None:
localPort = random.randrange(40000, 50000)
logger.debug('Connecting to %s:%s using %s/%s redirecting to %s:%s, listening on 127.0.0.1:%s',
server, port, username, password, redirectHost, redirectPort, localPort)
logger.debug(
'Connecting to %s:%s using %s/%s redirecting to %s:%s, listening on 127.0.0.1:%s',
server,
port,
username,
password,
redirectHost,
redirectPort,
localPort,
)
ft = ForwardThread(server, port, username, password, localPort, redirectHost, redirectPort, waitTime, fingerPrints)
ft = ForwardThread(
server,
port,
username,
password,
localPort,
redirectHost,
redirectPort,
waitTime,
fingerPrints,
)
ft.start()

View File

@ -1,6 +1,6 @@
# -*- coding: utf-8 -*-
#
# Copyright (c) 2014 Virtual Cable S.L.
# Copyright (c) 2014-2021 Virtual Cable S.L.U.
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without modification,
@ -29,27 +29,35 @@
'''
@author: Adolfo Gómez, dkmaster at dkmon dot com
'''
from __future__ import unicode_literals
import logging
import os
import os.path
import sys
import tempfile
if sys.platform.startswith('linux'):
from os.path import expanduser # pylint: disable=ungrouped-imports
logFile = expanduser('~/udsclient.log')
LOGLEVEL = logging.INFO
DEBUG = False
# Update debug level if uds-debug-on exists
if 'linux' in sys.platform or 'darwin' in sys.platform:
logFile = os.path.expanduser('~/udsclient.log')
if os.path.isfile(os.path.expanduser('~/uds-debug-on')):
LOGLEVEL = logging.DEBUG
DEBUG = True
else:
logFile = os.path.join(tempfile.gettempdir(), b'udsclient.log')
logFile = os.path.join(tempfile.gettempdir(), 'udsclient.log')
if os.path.isfile(os.path.join(tempfile.gettempdir(), 'uds-debug-on')):
LOGLEVEL = logging.DEBUG
DEBUG = True
try:
logging.basicConfig(
filename=logFile,
filemode='a',
format='%(levelname)s %(asctime)s %(message)s',
level=logging.INFO
level=LOGLEVEL,
)
except Exception:
logging.basicConfig(format='%(levelname)s %(asctime)s %(message)s', level=logging.INFO)
logging.basicConfig(format='%(levelname)s %(asctime)s %(message)s', level=LOGLEVEL)
logger = logging.getLogger('udsclient')

View File

@ -1,7 +1,7 @@
# -*- coding: utf-8 -*-
#
# Copyright (c) 2017 Virtual Cable S.L.
# Copyright (c) 2017-2021 Virtual Cable S.L.U.
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without modification,
@ -30,14 +30,13 @@
'''
@author: Adolfo Gómez, dkmaster at dkmon dot com
'''
from __future__ import unicode_literals
import sys
LINUX = 'Linux'
WINDOWS = 'Windows'
MAC_OS_X = 'Mac os x'
def getOs():
if sys.platform.startswith('linux'):
return LINUX

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