diff options
author | Mike Gabriel <mike.gabriel@das-netzwerkteam.de> | 2017-06-30 20:13:51 +0200 |
---|---|---|
committer | Mike Gabriel <mike.gabriel@das-netzwerkteam.de> | 2017-07-26 10:12:43 +0200 |
commit | f76c82403888bb498973ec974dbfd20e4edb02fe (patch) | |
tree | be0cb6c112d9d9fb46387fbd114727510197ddec /nxcomp/Auth.cpp | |
parent | 9193d11eeeea933e293acd5e0f03fa4e9887186b (diff) | |
download | nx-libs-f76c82403888bb498973ec974dbfd20e4edb02fe.tar.gz nx-libs-f76c82403888bb498973ec974dbfd20e4edb02fe.tar.bz2 nx-libs-f76c82403888bb498973ec974dbfd20e4edb02fe.zip |
nxcomp: Switch to autoreconf.
Diffstat (limited to 'nxcomp/Auth.cpp')
-rw-r--r-- | nxcomp/Auth.cpp | 667 |
1 files changed, 0 insertions, 667 deletions
diff --git a/nxcomp/Auth.cpp b/nxcomp/Auth.cpp deleted file mode 100644 index bc047aa30..000000000 --- a/nxcomp/Auth.cpp +++ /dev/null @@ -1,667 +0,0 @@ -/**************************************************************************/ -/* */ -/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ -/* Copyright (c) 2008-2014 Oleksandr Shneyder <o.shneyder@phoca-gmbh.de> */ -/* Copyright (c) 2014-2016 Ulrich Sibiller <uli42@gmx.de> */ -/* Copyright (c) 2014-2016 Mihai Moldovan <ionic@ionic.de> */ -/* Copyright (c) 2011-2016 Mike Gabriel <mike.gabriel@das-netzwerkteam.de>*/ -/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ -/* */ -/* NXCOMP, NX protocol compression and NX extensions to this software */ -/* are copyright of the aforementioned persons and companies. */ -/* */ -/* Redistribution and use of the present software is allowed according */ -/* to terms specified in the file LICENSE.nxcomp which comes in the */ -/* source distribution. */ -/* */ -/* All rights reserved. */ -/* */ -/* NOTE: This software has received contributions from various other */ -/* contributors, only the core maintainers and supporters are listed as */ -/* copyright holders. Please contact us, if you feel you should be listed */ -/* as copyright holder, as well. */ -/* */ -/**************************************************************************/ - -#include "Auth.h" - -#include "Misc.h" -#include "Control.h" -#include "Timestamp.h" -#include "Pipe.h" - -#define DEFAULT_STRING_LIMIT 512 - -// -// Set the verbosity level. -// - -#define PANIC -#define WARNING -#undef TEST -#undef DEBUG - -// -// Store the provided cookie as our 'fake' cookie, then -// read the 'real' cookie from the current X authority -// file. -// - -Auth::Auth(char *display, char *cookie) -{ - display_ = NULL; - - file_ = NULL; - - last_ = nullTimestamp(); - - fakeCookie_ = NULL; - realCookie_ = NULL; - - fakeData_ = NULL; - realData_ = NULL; - - dataSize_ = 0; - - generatedCookie_ = 0; - - if (display == NULL || *display == '\0' || cookie == NULL || - *cookie == '\0' || strlen(cookie) != 32) - { - #ifdef PANIC - *logofs << "Auth: PANIC! Can't create the X authorization data " - << "with cookie '" << cookie << "' and display '" - << display << "'.\n" << logofs_flush; - #endif - - cerr << "Error" << ": Can't create the X authorization data " - << "with cookie '" << cookie << "' and display '" - << display << "'.\n"; - - return; - } - - #ifdef TEST - *logofs << "Auth: Creating X authorization data with cookie '" - << cookie << "' and display '" << display << "'.\n" - << logofs_flush; - #endif - - // - // Get a local copy of all parameters. - // - - display_ = new char[strlen(display) + 1]; - file_ = new char[DEFAULT_STRING_LIMIT]; - - fakeCookie_ = new char[strlen(cookie) + 1]; - realCookie_ = new char[DEFAULT_STRING_LIMIT]; - - if (display_ == NULL || file_ == NULL || - fakeCookie_ == NULL || realCookie_ == NULL) - { - #ifdef PANIC - *logofs << "Auth: PANIC! Cannot allocate memory for the X " - << "authorization data.\n" << logofs_flush; - #endif - - cerr << "Error" << ": Cannot allocate memory for the X " - << "authorization data.\n"; - - return; - } - - strcpy(display_, display); - - *file_ = '\0'; - - strcpy(fakeCookie_, cookie); - - *realCookie_ = '\0'; - - // - // Get the real cookie from the authorization file. - // - - updateCookie(); -} - -Auth::~Auth() -{ - delete [] display_; - delete [] file_; - - delete [] fakeCookie_; - delete [] realCookie_; - - delete [] fakeData_; - delete [] realData_; -} - -// -// At the present moment the cookie is read only once, -// at the time the instance is initialized. If the auth -// file changes along the life of the session, the old -// cookie will be used. This works with X servers beca- -// use of an undocumented "feature". See nx-X11. -// - -int Auth::updateCookie() -{ - if (isTimestamp(last_) == 0) - { - #ifdef TEST - *logofs << "Auth: Reading the X authorization file " - << "with last update at " << strMsTimestamp(last_) - << ".\n" << logofs_flush; - #endif - - if (getCookie() == 1 && validateCookie() == 1) - { - // - // It should rather be the modification time - // the auth file, so we can read it again if - // the file is changed. - // - - #ifdef TEST - *logofs << "Auth: Setting last X authorization file " - << "update at " << strMsTimestamp() << ".\n" - << logofs_flush; - #endif - - last_ = getTimestamp(); - - return 1; - } - - #ifdef PANIC - *logofs << "Auth: PANIC! Cannot read the cookie from the X " - << "authorization file.\n" << logofs_flush; - #endif - - cerr << "Error" << ": Cannot read the cookie from the X " - << "authorization file.\n"; - - return -1; - } - - #ifdef TEST - *logofs << "Auth: WARNING! Skipping check on the X " - << "authorization file.\n" << logofs_flush; - #endif - - return 0; -} - -int Auth::getCookie() -{ - // - // Check the name of the auth file that we are going to use. - // It can be either the value of the XAUTHORITY environment - // or the default .Xauthority file in the user's home. - // - - char *environment; - - environment = getenv("XAUTHORITY"); - - if (environment != NULL && *environment != '\0') - { - strncpy(file_, environment, DEFAULT_STRING_LIMIT - 1); - } - else - { - snprintf(file_, DEFAULT_STRING_LIMIT - 1, "%s/.Xauthority", - control -> HomePath); - } - - *(file_ + DEFAULT_STRING_LIMIT - 1) = '\0'; - - #ifdef TEST - *logofs << "Auth: Using X authorization file '" << file_ - << "'.\n" << logofs_flush; - #endif - - // - // Use the nxauth command on Windows and the Mac, xauth - // on all the other platforms. On Windows we assume that - // the nxauth command is located under bin in the client - // installation directory. On Mac OS X we assume that the - // command is located directly in the client installation - // directory, to make bundle shipping easier. On all the - // other platforms we use the default xauth command that - // is in our path. - // - - char command[DEFAULT_STRING_LIMIT]; - - #if defined(__CYGWIN32__) - - snprintf(command, DEFAULT_STRING_LIMIT - 1, - "%s/bin/nxauth", control -> SystemPath); - - *(command + DEFAULT_STRING_LIMIT - 1) = '\0'; - - #elif defined(__APPLE__) - - snprintf(command, DEFAULT_STRING_LIMIT - 1, - "%s/nxauth", control -> SystemPath); - - *(command + DEFAULT_STRING_LIMIT - 1) = '\0'; - - #else - - strcpy(command, "xauth"); - - #endif - - #ifdef TEST - *logofs << "Auth: Using X auth command '" << command - << "'.\n" << logofs_flush; - #endif - - // - // The SSH code forces using the unix:n port when passing localhost:n. - // This is probably because localhost:n can fail to return a valid - // entry on machines where the hostname for localhost doesn't match - // exactly the 'localhost' string. For example, on a freshly installed - // Fedora Core 3 I get a 'localhost.localdomain/unix:0' entry. Query- - // ing 'xauth list localhost:0' results in an empty result, while the - // query 'xauth list unix:0' works as expected. Note anyway that if - // the cookie for the TCP connection on 'localhost' is set to a dif- - // ferent cookie than the one for the Unix connections, both SSH and - // NX will match the wrong cookie and session will fail. - // - - char line[DEFAULT_STRING_LIMIT]; - - if (strncmp(display_, "localhost:", 10) == 0) - { - snprintf(line, DEFAULT_STRING_LIMIT, "unix:%s", display_ + 10); - } - else - { - snprintf(line, DEFAULT_STRING_LIMIT, "%.200s", display_); - } - - const char *parameters[256]; - - parameters[0] = command; - parameters[1] = command; - parameters[2] = "-f"; - parameters[3] = file_; - parameters[4] = "list"; - parameters[5] = line; - parameters[6] = NULL; - - #ifdef TEST - *logofs << "Auth: Executing command "; - - for (int i = 0; i < 256 && parameters[i] != NULL; i++) - { - *logofs << "[" << parameters[i] << "]"; - } - - *logofs << ".\n" << logofs_flush; - #endif - - // - // Use the popen() function to read the result - // of the command. We would better use our own - // implementation. - // - - FILE *data = Popen((char *const *) parameters, "r"); - - int result = -1; - - if (data == NULL) - { - #ifdef PANIC - *logofs << "Auth: PANIC! Failed to execute the X auth command.\n" - << logofs_flush; - #endif - - cerr << "Error" << ": Failed to execute the X auth command.\n"; - - goto AuthGetCookieResult; - } - - if (fgets(line, DEFAULT_STRING_LIMIT, data) == NULL) - { - #ifdef WARNING - *logofs << "Auth: WARNING! Failed to read data from the X " - << "auth command.\n" << logofs_flush; - #endif - - #ifdef TEST - cerr << "Warning" << ": Failed to read data from the X " - << "auth command.\n"; - #endif - - #ifdef PANIC - *logofs << "Auth: WARNING! Generating a fake cookie for " - << "X authentication.\n" << logofs_flush; - #endif - - #ifdef TEST - cerr << "Warning" << ": Generating a fake cookie for " - << "X authentication.\n"; - #endif - - generateCookie(realCookie_); - } - else - { - #ifdef TEST - *logofs << "Auth: Checking cookie in string '" << line - << "'.\n" << logofs_flush; - #endif - - // - // Skip the hostname in the authority entry - // just in case it includes some white spaces. - // - - char *cookie = NULL; - - cookie = index(line, ':'); - - if (cookie == NULL) - { - cookie = line; - } - - if (sscanf(cookie, "%*s %*s %511s", realCookie_) != 1) - { - #ifdef PANIC - *logofs << "Auth: PANIC! Failed to identify the cookie " - << "in string '" << line << "'.\n" - << logofs_flush; - #endif - - cerr << "Error" << ": Failed to identify the cookie " - << "in string '" << line << "'.\n"; - - goto AuthGetCookieResult; - } - - #ifdef TEST - *logofs << "Auth: Got cookie '" << realCookie_ - << "' from file '" << file_ << "'.\n" - << logofs_flush; - #endif - } - - result = 1; - -AuthGetCookieResult: - - if (data != NULL) - { - Pclose(data); - } - - return result; -} - -int Auth::validateCookie() -{ - unsigned int length = strlen(realCookie_); - - if (length > DEFAULT_STRING_LIMIT / 2 - 1 || - strlen(fakeCookie_) != length) - { - #ifdef PANIC - *logofs << "Auth: PANIC! Size mismatch between cookies '" - << realCookie_ << "' and '" << fakeCookie_ << "'.\n" - << logofs_flush; - #endif - - cerr << "Error" << ": Size mismatch between cookies '" - << realCookie_ << "' and '" << fakeCookie_ << "'.\n"; - - goto AuthValidateCookieError; - } - - // - // The length of the resulting data will be - // half the size of the Hex cookie. - // - - length = length / 2; - - fakeData_ = new char[length]; - realData_ = new char[length]; - - if (fakeData_ == NULL || realData_ == NULL) - { - #ifdef PANIC - *logofs << "Auth: PANIC! Cannot allocate memory for the binary X " - << "authorization data.\n" << logofs_flush; - #endif - - cerr << "Error" << ": Cannot allocate memory for the binary X " - << "authorization data.\n"; - - goto AuthValidateCookieError; - } - - // - // Translate the real cookie from Hex data - // to its binary representation. - // - - unsigned int value; - - for (unsigned int i = 0; i < length; i++) - { - if (sscanf(realCookie_ + 2 * i, "%2x", &value) != 1) - { - #ifdef PANIC - *logofs << "Auth: PANIC! Bad X authorization data in real " - << "cookie '" << realCookie_ << "'.\n" << logofs_flush; - #endif - - cerr << "Error" << ": Bad X authorization data in real cookie '" - << realCookie_ << "'.\n"; - - goto AuthValidateCookieError; - } - - realData_[i] = value; - - if (sscanf(fakeCookie_ + 2 * i, "%2x", &value) != 1) - { - #ifdef PANIC - *logofs << "Auth: PANIC! Bad X authorization data in fake " - << "cookie '" << fakeCookie_ << "'.\n" << logofs_flush; - #endif - - cerr << "Error" << ": Bad X authorization data in fake cookie '" - << fakeCookie_ << "'.\n"; - - goto AuthValidateCookieError; - } - - fakeData_[i] = value; - } - - dataSize_ = length; - - #ifdef TEST - *logofs << "Auth: Validated real cookie '" - << realCookie_ << "' and fake cookie '" << fakeCookie_ - << "' with data with size " << dataSize_ << ".\n" - << logofs_flush; - - *logofs << "Auth: Ready to accept incoming connections.\n" - << logofs_flush; - #endif - - return 1; - -AuthValidateCookieError: - - delete [] fakeData_; - delete [] realData_; - - fakeData_ = NULL; - realData_ = NULL; - - dataSize_ = 0; - - return -1; -} - -int Auth::checkCookie(unsigned char *buffer) -{ - if (isValid() != 1) - { - #ifdef PANIC - *logofs << "Auth: PANIC! Attempt to check the X cookie with " - << "invalid authorization data.\n" << logofs_flush; - #endif - - cerr << "Error" << ": Attempt to check the X cookie with " - << "invalid authorization data.\n"; - - return -1; - } - - const char *protoName = "MIT-MAGIC-COOKIE-1"; - int protoSize = strlen(protoName); - - int matchedProtoSize; - int matchedDataSize; - - if (buffer[0] == 0x42) - { - // - // Byte order is MSB first. - // - - matchedProtoSize = 256 * buffer[6] + buffer[7]; - matchedDataSize = 256 * buffer[8] + buffer[9]; - } - else if (buffer[0] == 0x6c) - { - // - // Byte order is LSB first. - // - - matchedProtoSize = buffer[6] + 256 * buffer[7]; - matchedDataSize = buffer[8] + 256 * buffer[9]; - } - else - { - #ifdef WARNING - *logofs << "Auth: WARNING! Bad X connection data in the buffer.\n" - << logofs_flush; - #endif - - cerr << "Warning" << ": Bad X connection data in the buffer.\n"; - - return -1; - } - - // - // Check if both the authentication protocol - // and the fake cookie match our data. - // - - int protoOffset = 12; - - #ifdef TEST - *logofs << "Auth: Received a protocol size of " - << matchedProtoSize << " bytes.\n" - << logofs_flush; - #endif - - if (matchedProtoSize != protoSize || - memcmp(buffer + protoOffset, protoName, protoSize) != 0) - { - #ifdef WARNING - *logofs << "Auth: WARNING! Protocol mismatch or no X " - << "authentication data.\n" << logofs_flush; - #endif - - cerr << "Warning" << ": Protocol mismatch or no X " - << "authentication data.\n"; - - return -1; - } - - int dataOffset = protoOffset + ((matchedProtoSize + 3) & ~3); - - #ifdef TEST - *logofs << "Auth: Received a data size of " - << matchedDataSize << " bytes.\n" - << logofs_flush; - #endif - - if (matchedDataSize != dataSize_ || - memcmp(buffer + dataOffset, fakeData_, dataSize_) != 0) - { - #ifdef WARNING - *logofs << "Auth: WARNING! Cookie mismatch in the X " - << "authentication data.\n" << logofs_flush; - #endif - - cerr << "Warning" << ": Cookie mismatch in the X " - << "authentication data.\n"; - - return -1; - } - - // - // Everything is OK. Replace the fake data. - // - - #ifdef TEST - *logofs << "Auth: Replacing fake X authentication data " - << "with the real data.\n" << logofs_flush; - #endif - - memcpy(buffer + dataOffset, realData_, dataSize_); - - return 1; -} - -void Auth::generateCookie(char *cookie) -{ - // - // Code is from the SSH implementation, except that - // we use a much weaker random number generator. - // This is not critical, anyway, as this is just a - // fake cookie. The X server doesn't have a cookie - // for the display, so it will ignore the value we - // feed to it. - // - - T_timestamp timer = getTimestamp(); - - srand((unsigned int) timer.tv_usec); - - unsigned int data = rand(); - - for (int i = 0; i < 16; i++) - { - if (i % 4 == 0) - { - data = rand(); - } - - snprintf(cookie + 2 * i, 3, "%02x", data & 0xff); - - data >>= 8; - } - - generatedCookie_ = 1; - - #ifdef TEST - *logofs << "Auth: Generated X cookie string '" - << cookie << "'.\n" << logofs_flush; - #endif -} |