5701a-r14485.diff
src/com/goldencode/p2j/main/ClientCore.java 2023-01-27 13:53:55 +0000 | ||
---|---|---|
2 | 2 |
** Module : ClientCore.java |
3 | 3 |
** Abstract : core client loop which handles init and connects to server |
4 | 4 |
** |
5 |
** Copyright (c) 2005-2022, Golden Code Development Corporation.
|
|
5 |
** Copyright (c) 2005-2023, Golden Code Development Corporation.
|
|
6 | 6 |
** |
7 | 7 |
** -#- -I- --Date-- ----------------------------------Description--------------------------------- |
8 | 8 |
** 001 GES 20110928 Moved core logic here from ClientDriver so that the same |
... | ... | |
62 | 62 |
** CA 20220918 Added socket trust store filename and password to the ClientParameters. |
63 | 63 |
** GBB 20221209 Path to debug log file to be read from client bootstrap configs. |
64 | 64 |
** Passing arg to spawner for path to stderr log file for background processes. |
65 |
** GBB 20230127 Fixing pid in outputToFile name by replacing it in Java code. |
|
65 | 66 |
*/ |
66 | 67 |
/* |
67 | 68 |
** This program is free software: you can redistribute it and/or modify |
... | ... | |
118 | 119 | |
119 | 120 |
package com.goldencode.p2j.main; |
120 | 121 | |
122 |
import java.io.*; |
|
121 | 123 |
import java.util.*; |
122 | 124 |
import java.util.function.*; |
123 | 125 |
import java.util.logging.*; |
... | ... | |
186 | 188 |
public static void start(BootstrapConfig config, boolean file, boolean single, Supplier<String> diag) |
187 | 189 |
throws Exception |
188 | 190 |
{ |
191 |
// Load native library |
|
192 |
loadNativeLibrary(); |
|
193 |
|
|
194 |
setOutputToFile(config); |
|
195 |
|
|
189 | 196 |
String uuid = config.getString("server", "spawner", "uuid", null); |
190 | 197 |
boolean dbg = config.getBoolean("logging", "debug", "enable", false); |
191 | 198 |
String referrer = config.getString("web", "referrer", "url", null); |
... | ... | |
196 | 203 |
// iterations of the core loop |
197 | 204 |
ScreenDriver<?> driver = (uuid == null) ? null : processTemporaryClient(uuid, config); |
198 | 205 |
|
199 |
// Load native library |
|
200 |
loadNativeLibrary(); |
|
201 |
|
|
202 | 206 |
while (running) |
203 | 207 |
{ |
204 | 208 |
Object context = null; |
... | ... | |
434 | 438 |
return isStop; |
435 | 439 |
} |
436 | 440 | |
441 |
private static void setOutputToFile(BootstrapConfig config) |
|
442 |
{ |
|
443 |
String outputToFile = config.getString("server", "clientConfig", "outputToFile", null); |
|
444 |
if (outputToFile == null) |
|
445 |
{ |
|
446 |
return; |
|
447 |
} |
|
448 |
|
|
449 |
try |
|
450 |
{ |
|
451 |
outputToFile = outputToFile.replace("%pid%", String.valueOf(getPid())); |
|
452 |
System.setOut(new PrintStream(new FileOutputStream(outputToFile), true)); |
|
453 |
} |
|
454 |
catch (Throwable t) |
|
455 |
{ |
|
456 |
System.err.println("ClientCore: Unable to redirect stdout to outputToFile " + outputToFile); |
|
457 |
} |
|
458 |
} |
|
459 | ||
437 | 460 |
/** |
438 | 461 |
* Loads native library and performs required initial steps for P2J library to working. |
439 | 462 |
*/ |
src/com/goldencode/p2j/main/ProcessClientBuilder.java 2023-01-27 13:56:11 +0000 | ||
---|---|---|
2 | 2 |
** Module : ProcessClientBuilder.java |
3 | 3 |
** Abstract : build and start a platform process for P2J process. |
4 | 4 |
** |
5 |
** Copyright (c) 2014-2017, Golden Code Development Corporation.
|
|
5 |
** Copyright (c) 2014-2023, Golden Code Development Corporation.
|
|
6 | 6 |
** |
7 | 7 |
** -#- -I- --Date-- ---------------------------------Description---------------------------------- |
8 | 8 |
** 001 CA 20140206 First version. |
... | ... | |
10 | 10 |
** 003 MAG 20140722 Implemented the remote launcher. |
11 | 11 |
** 004 GES 20160219 Moved code to the parent class allowing reuse of the native secure connection |
12 | 12 |
** setup processing. |
13 |
** GBB 20230127 Fixing pid in outputToFile name by passing it as config to spawned client. |
|
13 | 14 |
*/ |
14 | 15 |
/* |
15 | 16 |
** This program is free software: you can redistribute it and/or modify |
... | ... | |
132 | 133 |
if (outputToFile != null) |
133 | 134 |
{ |
134 | 135 |
cmd.add("-O"); |
135 |
cmd.add(outputToFile); |
|
136 |
cmd.add("server:clientConfig:outputToFile=" + outputToFile);
|
|
136 | 137 |
} |
137 | 138 | |
138 | 139 |
return cmd; |
139 | 140 |
} |
140 |
} |
|
141 |
} |
src/native/spawn.c 2023-01-31 09:34:16 +0000 | ||
---|---|---|
2 | 2 |
** Module : spawn.c |
3 | 3 |
** Abstract : a simple tool able to spawn a process on an existing user account. |
4 | 4 |
** |
5 |
** Copyright (c) 2013-2021, Golden Code Development Corporation.
|
|
5 |
** Copyright (c) 2013-2023, Golden Code Development Corporation.
|
|
6 | 6 |
** |
7 | 7 |
** -#- -I- --Date-- --------------------------------Description--------------------------------- |
8 | 8 |
** 001 MAG 20131127 First version. |
... | ... | |
27 | 27 |
** IAS 20210325 Added addional parameters for command |
28 | 28 |
** EVL 20210519 Fix for segmentation fault in strcmp() library call. Added new error codes to inform |
29 | 29 |
** the caller about system errors. |
30 |
** GBB 20230131 outputToFile passed in as arg to create client process command. |
|
31 |
** stdout redirect in Java. |
|
30 | 32 |
*/ |
31 | 33 |
/* |
32 | 34 |
** This program is free software: you can redistribute it and/or modify |
... | ... | |
162 | 164 |
#define ALLPERMS (S_ISUID|S_ISGID|S_ISVTX|S_IRWXU|S_IRWXG|S_IRWXO)/* 07777 */ |
163 | 165 |
#endif |
164 | 166 | |
165 |
/* prototypes */ |
|
166 |
void stdout_redirect(); |
|
167 | ||
168 | 167 |
/* Global data */ |
169 | 168 |
struct passwd *pw; |
170 | 169 |
int extra_logging = 0; |
... | ... | |
175 | 174 | |
176 | 175 |
/* Output file name */ |
177 | 176 |
char output_file_name[MAX_FILENAME]; |
177 |
int output_to_file_opt_found = 0; |
|
178 | 178 | |
179 | 179 |
/** |
180 | 180 |
* Use syslog to audit the execution of child processes. |
... | ... | |
400 | 400 |
logMessage(message_buffer); |
401 | 401 |
exit(audit(ERR_SPAWN_CHDIR_WD, "chdir(workdir)")); |
402 | 402 |
} |
403 | ||
404 |
/* Redirect STDOUT if required */ |
|
405 |
if (output_file_name[0] != 0) |
|
406 |
{ |
|
407 |
stdout_redirect(); |
|
408 |
} |
|
409 | 403 |
|
410 | 404 |
/* Execute command */ |
411 | 405 |
exit(execvp(command, argv)); |
... | ... | |
1018 | 1012 |
/* make it 1-based, so it follows the structure of the command line arguments |
1019 | 1013 |
(0 is program name); also, one more position is needed for execvp, which requires for the |
1020 | 1014 |
arguments to be null-terminated. */ |
1021 |
char **arguments = (char**) malloc((length + 2) * sizeof(char*)); |
|
1015 |
char **arguments = (char**) malloc((length + 2 + output_to_file_opt_found) * sizeof(char*));
|
|
1022 | 1016 |
arguments[0] = NULL; |
1023 |
arguments[length + 1] = NULL; |
|
1017 |
arguments[length + 1 + output_to_file_opt_found] = NULL; |
|
1018 | ||
1019 |
if (output_to_file_opt_found == 1) |
|
1020 |
{ |
|
1021 |
int len = strlen(output_file_name) + 1; |
|
1022 |
arguments[length + 1] = (char*) malloc(len * sizeof(char)); |
|
1023 |
memset(arguments[length + 1], '\0', len); |
|
1024 |
strcpy(arguments[length + 1], output_file_name); |
|
1025 |
} |
|
1024 | 1026 |
|
1025 | 1027 |
int i; |
1026 | 1028 |
for (i = 0; i < (int) length; i++) |
... | ... | |
1151 | 1153 |
} |
1152 | 1154 | |
1153 | 1155 |
/** |
1154 |
* Redirect STDOUT to an output file. |
|
1155 |
*/ |
|
1156 |
void stdout_redirect() |
|
1157 |
{ |
|
1158 |
int output_fd; |
|
1159 |
char pid[32]; |
|
1160 |
|
|
1161 |
/* convert pid to string */ |
|
1162 |
sprintf(pid, "%u", getpid()); |
|
1163 |
|
|
1164 |
/* replace %pid% placeholder */ |
|
1165 |
char* filename = replace_str(output_file_name, "%pid%", pid); |
|
1166 |
|
|
1167 |
// Open file |
|
1168 |
output_fd = open(filename, O_WRONLY | O_CREAT | O_APPEND, 0644); |
|
1169 |
|
|
1170 |
if (output_fd == -1) |
|
1171 |
{ |
|
1172 |
fprintf(stderr, "Cannot open file %s\n", filename); |
|
1173 |
} |
|
1174 |
else |
|
1175 |
{ |
|
1176 |
/* Redirect STDOUT to file */ |
|
1177 |
if (dup2(output_fd, STDOUT_FILENO) == -1) |
|
1178 |
{ |
|
1179 |
close(output_fd); |
|
1180 |
fprintf(stderr, "Cannot redirect STDOUT to file %s\n", filename); |
|
1181 |
} |
|
1182 |
} |
|
1183 |
} |
|
1184 | ||
1185 |
/** |
|
1186 | 1156 |
* Main function which allows both password and P2J server-style authentication. |
1187 | 1157 |
* <p> |
1188 | 1158 |
* For P2J server-style authentiation, the following files need to exist in current directory: |
... | ... | |
1335 | 1305 |
if ((strcmp("-O", argv[i]) == 0) && (++i < argc)) |
1336 | 1306 |
{ |
1337 | 1307 |
strcpy(output_file_name, argv[i]); |
1308 |
output_to_file_opt_found = 1; |
|
1338 | 1309 |
} |
1339 | 1310 |
} |
1340 | 1311 |
src/native/winspawn.c 2023-01-31 09:33:05 +0000 | ||
---|---|---|
2 | 2 |
** Module : winspawn.c |
3 | 3 |
** Abstract : a simple tool able to spawn a process on an existing user account. |
4 | 4 |
** |
5 |
** Copyright (c) 2013-2022, Golden Code Development Corporation.
|
|
5 |
** Copyright (c) 2013-2023, Golden Code Development Corporation.
|
|
6 | 6 |
** |
7 | 7 |
** -#- -I- --Date-- --------------------------------Description--------------------------------- |
8 | 8 |
** 001 MAG 20131130 First version. |
... | ... | |
27 | 27 |
** to CreateProcessWithToken. |
28 | 28 |
** EVL 20220413 Fixed the issues with processes starting on behalf of different users. Some additional |
29 | 29 |
** improvements for common desktop name. |
30 |
** 010 GBB 20221209 Fix for stdout file name, incorrect calculation of the prefix length
|
|
30 |
** GBB 20221209 Fix for stdout file name, incorrect calculation of the prefix length
|
|
31 | 31 |
** when %pid% placeholder replaced. |
32 |
** GBB 20230131 outputToFile passed in as arg to create client process command. |
|
33 |
** stdout redirect in Java. |
|
32 | 34 |
*/ |
33 | 35 |
/* |
34 | 36 |
** This program is free software: you can redistribute it and/or modify |
... | ... | |
132 | 134 | |
133 | 135 |
unsigned char key1[KEY_SIZE + 1], key2[KEY_SIZE + 1], key3[KEY_SIZE + 1]; |
134 | 136 | |
135 |
/* STDOUT redirection flag. Default NO redirection */ |
|
136 |
int stdoutRedirect = 0; |
|
137 |
WCHAR szOutputFile[MAX_SIZE] = L""; |
|
137 |
int outputToFileOption = 0; |
|
138 |
char szOutputFile[MAX_SIZE]; |
|
138 | 139 | |
139 | 140 |
WCHAR szUserProfile[MAX_SIZE] = L""; |
140 | 141 |
WCHAR szCommandLine[MAX_SIZE] = L""; |
... | ... | |
510 | 511 |
} |
511 | 512 | |
512 | 513 |
/** |
513 |
* Redirect STDOUT to an output file. |
|
514 |
* |
|
515 |
* @param szWorkingDir |
|
516 |
* Working directory. |
|
517 |
* @param szOutputFile |
|
518 |
* The name of the file where the STDOUT is redirected. |
|
519 |
*/ |
|
520 |
void stdout_redirect(LPWSTR szWorkingDir, LPWSTR szOutputFile) |
|
521 |
{ |
|
522 |
HANDLE hFile; |
|
523 |
WCHAR pid[32]; |
|
524 |
|
|
525 |
/* Goto working directory */ |
|
526 |
if (!SetCurrentDirectoryW(szWorkingDir)) |
|
527 |
{ |
|
528 |
DisplayError(L"SetCurrentDirectoryW"); |
|
529 |
} |
|
530 |
|
|
531 |
/* convert pid to string */ |
|
532 |
swprintf(pid, sizeof(pid), L"%lu", GetCurrentProcessId()); |
|
533 |
|
|
534 |
/* replace %pid% placeholder */ |
|
535 |
LPWSTR szFileName = replace_str(szOutputFile, L"%pid%", pid); |
|
536 |
|
|
537 |
SECURITY_ATTRIBUTES sa; |
|
538 |
sa.nLength = sizeof(sa); |
|
539 |
sa.lpSecurityDescriptor = NULL; |
|
540 |
sa.bInheritHandle = TRUE; |
|
541 |
|
|
542 |
/* create file */ |
|
543 |
hFile = CreateFileW(szFileName, // file name |
|
544 |
FILE_APPEND_DATA, // open for writing |
|
545 |
FILE_SHARE_WRITE | FILE_SHARE_READ, // allow multiple readers |
|
546 |
&sa, // security |
|
547 |
OPEN_ALWAYS, // open or create |
|
548 |
FILE_ATTRIBUTE_NORMAL, // normal file |
|
549 |
NULL); // no template |
|
550 |
|
|
551 |
/* check for errors */ |
|
552 |
if (hFile == INVALID_HANDLE_VALUE) |
|
553 |
{ |
|
554 |
DisplayError(L"CreateFileW"); |
|
555 |
} |
|
556 |
else |
|
557 |
{ |
|
558 |
/* redirect */ |
|
559 |
si.hStdOutput = hFile; |
|
560 |
si.dwFlags |= STARTF_USESTDHANDLES; |
|
561 |
} |
|
562 |
} |
|
563 | ||
564 |
/** |
|
565 | 514 |
* Spawn a child process on the current logon account. |
566 | 515 |
* |
567 | 516 |
* @param szWorkingDir |
... | ... | |
579 | 528 |
si.wShowWindow = SW_HIDE; |
580 | 529 |
// since Windows Vista we have to specify desktop session explicitly here |
581 | 530 |
si.lpDesktop = desktopDefault; |
582 | ||
583 |
/* Redirect STDOUT if required */ |
|
584 |
if (stdoutRedirect) |
|
585 |
{ |
|
586 |
stdout_redirect(szWorkingDir, szOutputFile); |
|
587 |
} |
|
588 | 531 |
|
589 | 532 |
if (!CreateProcessW(NULL, // application name |
590 | 533 |
szCommand, // command line |
... | ... | |
681 | 624 |
} |
682 | 625 |
szWorkingDir = szUserProfile; |
683 | 626 |
} |
684 |
|
|
685 |
/* Redirect STDOUT if required */ |
|
686 |
if (stdoutRedirect) |
|
687 |
{ |
|
688 |
stdout_redirect(szWorkingDir, szOutputFile); |
|
689 |
} |
|
690 | 627 | |
691 | 628 |
if (extra_logging > 0) |
692 | 629 |
{ |
... | ... | |
914 | 851 |
/* make it 1-based, so it follows the structure of the command line arguments |
915 | 852 |
(0 is program name); also, one more position is needed for execvp, which requires for the |
916 | 853 |
arguments to be null-terminated. */ |
917 |
char **arguments = (char**) malloc((length + 2) * sizeof(char*)); |
|
854 |
char **arguments = (char**) malloc((length + 2 + outputToFileOption) * sizeof(char*));
|
|
918 | 855 |
arguments[0] = NULL; |
919 |
arguments[length + 1] = NULL; |
|
856 |
arguments[length + 1 + outputToFileOption] = NULL; |
|
857 |
|
|
858 |
if (outputToFileOption == 1) |
|
859 |
{ |
|
860 |
int len = strlen(szOutputFile) + 1; |
|
861 |
arguments[length + 1] = (char*) malloc(len * sizeof(char)); |
|
862 |
memset(arguments[length + 1], '\0', len); |
|
863 |
strcpy(arguments[length + 1], szOutputFile); |
|
864 |
} |
|
865 |
|
|
920 | 866 |
int debug_option = 0; |
921 | 867 |
char *dbg_level = NULL; |
922 | 868 |
|
... | ... | |
980 | 926 |
AnsiToUnicode(arguments[MIN_ARGS_COMMAND - 1 + debug_option], szWorkingDir); |
981 | 927 | |
982 | 928 |
/* Command line */ |
983 |
LPWSTR szCommand = CommandLineFromAnsi(MIN_ARGS_COMMAND + debug_option, length + 1, arguments); |
|
929 |
LPWSTR szCommand = CommandLineFromAnsi(MIN_ARGS_COMMAND + debug_option, length + 1 + outputToFileOption, arguments);
|
|
984 | 930 | |
985 | 931 |
/* User name */ |
986 | 932 |
AnsiToUnicode(arguments[1], szUserName); |
... | ... | |
1120 | 1066 |
/* -O <outputToFile> */ |
1121 | 1067 |
if ((wcscmp(L"-O", argv[i]) == 0) && (++i < argc)) |
1122 | 1068 |
{ |
1123 |
wcscpy(szOutputFile, argv[i]);
|
|
1124 |
stdoutRedirect = 1; // restored redirection mode
|
|
1069 |
wcstombs(szOutputFile, argv[i], MAX_SIZE);
|
|
1070 |
outputToFileOption = 1;
|
|
1125 | 1071 |
} |
1126 | 1072 |
} |
1127 | 1073 |
|