From 559928de5b6b251eb278e70b2edfd48b410a4d02 Mon Sep 17 00:00:00 2001 From: Bryan Roe Date: Thu, 24 Jan 2019 11:19:33 -0800 Subject: [PATCH] The following updates, fix KVM for openSUSE and other distros with similar behavior 1. Removed 'setDisplay()' because it doesn't work 2. Added more descriptive error message when XOpenDisplay fails 3. Added ability to set XAUTHORITY in the child process if it wasn't set, by finding how X was started --- meshcore/KVM/Linux/linux_kvm.c | 45 +++++++++------------------------- meshcore/KVM/Linux/linux_kvm.h | 2 +- meshcore/agentcore.c | 34 ++++++++++++++++++++++++- test/authtest.js | 33 ++++++++++++++++--------- 4 files changed, 67 insertions(+), 47 deletions(-) diff --git a/meshcore/KVM/Linux/linux_kvm.c b/meshcore/KVM/Linux/linux_kvm.c index 0e2a8af..4809913 100644 --- a/meshcore/KVM/Linux/linux_kvm.c +++ b/meshcore/KVM/Linux/linux_kvm.c @@ -231,29 +231,6 @@ int getNextDisplay() { return 0; } -int setDisplay(unsigned short display_no) { - char cmd[BUFSIZ] = ""; - char authFile[BUFSIZ] = ""; - FILE *pfile = NULL; - int dispNo; - - sprintf(cmd, "ps aux 2>/dev/null | grep '/X.* :[0-9][0-9]* .*-auth' | egrep -v 'startx|xinit' | sed -e 's,^.*/X.* :\\([0-9][0-9]*\\) .* -auth \\([^ ][^ ]*\\).*$,\\1\\,\\2,' | grep '%d,'", display_no); - pfile = popen(cmd, "r"); - - if (pfile == NULL) { - return -1; - } - - if (fscanf(pfile, "%d,%510s", &dispNo, authFile) != 2) { - fclose(pfile); - return -1; - } - - fclose(pfile); - - return setenv("XAUTHORITY", authFile, 1); -} - void kvm_send_display_list() { unsigned short *displays = NULL; @@ -343,26 +320,26 @@ int kvm_init(int displayNo) sprintf(displayString, ":%d", (int)displayNo); - while (setDisplay(displayNo) != 0 && count++ < 10); - if (count == 10) { return -1; } count = 0; eventdisplay = x11_exports->XOpenDisplay(displayString); //fprintf(logFile, "XAUTHORITY is %s", getenv("XAUTHORITY")); fflush(logFile); if (eventdisplay == NULL) { + char tmpBuff[1024]; + sprintf_s(tmpBuff, sizeof(tmpBuff), "XOpenDisplay(%s) failed, using XAUTHORITY: %s", displayString, getenv("XAUTHORITY")); //fprintf(logFile, "DisplayString=%s\n", displayString); //fprintf(logFile, "XAUTHORITY is %s", getenv("XAUTHORITY")); fflush(logFile); //fprintf(logFile, "Error calling XOpenDisplay()\n"); fflush(logFile); - kvm_send_error("Error occured calling XOpenDisplay()"); + kvm_send_error(tmpBuff); } if (eventdisplay != NULL) { current_display = (unsigned short)displayNo; } - while (eventdisplay == NULL && count++ < 100) { + while (eventdisplay == NULL && count++ < 100) + { if (getNextDisplay() == -1) { return -1; } sprintf(displayString, ":%d", (int)current_display); - if (setDisplay(current_display) != 0) { continue; } eventdisplay = x11_exports->XOpenDisplay(displayString); } @@ -608,8 +585,6 @@ void* kvm_server_mainloop(void* parm) CheckDesktopSwitch(1); //fprintf(logFile, "After CheckDesktopSwitch.\n"); fflush(logFile); - setDisplay(current_display); - sprintf(displayString, ":%d", (int)current_display); imagedisplay = x11_exports->XOpenDisplay(displayString); @@ -756,7 +731,7 @@ void kvm_relay_readSink(ILibProcessPipe_Pipe sender, char *buffer, int bufferLen } *bytesConsumed = 0; } -void* kvm_relay_restart(int paused, void *processPipeMgr, ILibKVM_WriteHandler writeHandler, void *reserved, int uid) +void* kvm_relay_restart(int paused, void *processPipeMgr, ILibKVM_WriteHandler writeHandler, void *reserved, int uid, char* authToken) { int r; int count = 0; @@ -794,6 +769,10 @@ void* kvm_relay_restart(int paused, void *processPipeMgr, ILibKVM_WriteHandler w if (uid != 0) { ignore_result(setuid(uid)); } //fprintf(logFile, "Starting kvm_server_mainloop\n"); + if (authToken != NULL) + { + setenv("XAUTHORITY", authToken, 1); + } kvm_server_mainloop((void*)0); return(NULL); } @@ -810,11 +789,11 @@ void* kvm_relay_restart(int paused, void *processPipeMgr, ILibKVM_WriteHandler w // Setup the KVM session. Return 1 if ok, 0 if it could not be setup. -void* kvm_relay_setup(void *processPipeMgr, ILibKVM_WriteHandler writeHandler, void *reserved, int uid) +void* kvm_relay_setup(void *processPipeMgr, ILibKVM_WriteHandler writeHandler, void *reserved, int uid, char *authToken) { if (kvmthread != (pthread_t)NULL || g_slavekvm != 0) return 0; g_restartcount = 0; - return kvm_relay_restart(1, processPipeMgr, writeHandler, reserved, uid); + return kvm_relay_restart(1, processPipeMgr, writeHandler, reserved, uid, authToken); } // Force a KVM reset & refresh diff --git a/meshcore/KVM/Linux/linux_kvm.h b/meshcore/KVM/Linux/linux_kvm.h index 1f86142..30c9c45 100644 --- a/meshcore/KVM/Linux/linux_kvm.h +++ b/meshcore/KVM/Linux/linux_kvm.h @@ -40,7 +40,7 @@ typedef ILibTransport_DoneState(*ILibKVM_WriteHandler)(char *buffer, int bufferL void kvm_set_x11_locations(char *libx11, char *libx11tst, char *libx11ext); int kvm_relay_feeddata(char* buf, int len); void kvm_pause(int pause); -void* kvm_relay_setup(void *processPipeMgr, ILibKVM_WriteHandler writeHandler, void *reserved, int uid); +void* kvm_relay_setup(void *processPipeMgr, ILibKVM_WriteHandler writeHandler, void *reserved, int uid, char *authToken); void kvm_relay_reset(); void kvm_cleanup(); diff --git a/meshcore/agentcore.c b/meshcore/agentcore.c index 8e78457..3667ffd 100644 --- a/meshcore/agentcore.c +++ b/meshcore/agentcore.c @@ -1248,7 +1248,39 @@ duk_ret_t ILibDuktape_MeshAgent_getRemoteDesktop(duk_context *ctx) ptrs->kvmPipe = kvm_relay_setup(agent->exePath, agent->pipeManager, ILibDuktape_MeshAgent_RemoteDesktop_KVM_WriteSink, ptrs, console_uid); } #else - ptrs->kvmPipe = kvm_relay_setup(agent->pipeManager, ILibDuktape_MeshAgent_RemoteDesktop_KVM_WriteSink, ptrs, console_uid); + // For Linux, we need to determine where the XAUTHORITY is: + char *updateXAuth = NULL; + int needPop = 0; + if (getenv("XAUTHORITY") == NULL) + { + if (duk_peval_string(ctx, "(function getAuthToken()\ + {\ + var child = require('child_process').execFile('/bin/sh', ['sh']);\ + child.stdout.str = '';\ + child.stdin.write('ps -e -o user -o command | awk {\\'printf \"%s,\",$1;$1=\"\";printf \"%s\\\\n\", $0\\'} | grep X\\nexit\\n');\ + child.stdout.on('data', function(chunk) { this.str += chunk.toString(); });\ + child.waitExit();\ + var lines = child.stdout.str.split('\\n');\ + for (var i in lines) {\ + var tokens = lines[i].split(',');\ + if (tokens[0]) {\ + var items = tokens[1].split(' ');\ + for (var x = 0; x < items.length; ++x) {\ + if (items[x] == '-auth' && items.length >(x + 1)) {\ + return (items[x + 1]);\ + }\ + }\ + }\ + }\ + return (null);\ + })();") == 0) + { + updateXAuth = (char*)duk_get_string(ctx, -1); + } + needPop = 1; + } + ptrs->kvmPipe = kvm_relay_setup(agent->pipeManager, ILibDuktape_MeshAgent_RemoteDesktop_KVM_WriteSink, ptrs, console_uid, updateXAuth); + if (needPop!= 0) {duk_pop(ctx); } #endif #endif return 1; diff --git a/test/authtest.js b/test/authtest.js index 5045829..d69828c 100644 --- a/test/authtest.js +++ b/test/authtest.js @@ -1,16 +1,25 @@ -var child = require('child_process').execFile('/bin/sh', ['sh']); -child.stdout.str = ''; -child.stdin.write('ps -e -o user -o command | awk {\'printf "%s,",$1;$1="";printf "%s\\n", $0\'} | grep X\nexit\n'); -child.stdout.on('data', function (chunk) { this.str += chunk.toString(); }); -child.waitExit(); - -var lines = child.stdout.str.split('\n'); -for (var i in lines) +function getAuthToken() { - var tokens = lines[i].split(','); - console.log(tokens[0] + ' => ' + tokens[1]); + var child = require('child_process').execFile('/bin/sh', ['sh']); + child.stdout.str = ''; + child.stdin.write('ps -e -o user -o command | awk {\'printf "%s,",$1;$1="";printf "%s\\n", $0\'} | grep X\nexit\n'); + child.stdout.on('data', function (chunk) { this.str += chunk.toString(); }); + child.waitExit(); + + var lines = child.stdout.str.split('\n'); + for (var i in lines) { + var tokens = lines[i].split(','); + if (tokens[0]) { + var items = tokens[1].split(' '); + for (var x = 0; x < items.length; ++x) { + if (items[x] == '-auth' && items.length > (x + 1)) { + return (items[x + 1]); + } + } + } + } + return (null); } - -//console.log(child.stdout.str); +console.log('AuthToken => ' + getAuthToken()); process.exit();