aboutsummaryrefslogtreecommitdiff
path: root/nxcomp/Auth.cpp
diff options
context:
space:
mode:
authorMike Gabriel <mike.gabriel@das-netzwerkteam.de>2017-06-30 20:13:51 +0200
committerMike Gabriel <mike.gabriel@das-netzwerkteam.de>2017-07-26 10:12:43 +0200
commitf76c82403888bb498973ec974dbfd20e4edb02fe (patch)
treebe0cb6c112d9d9fb46387fbd114727510197ddec /nxcomp/Auth.cpp
parent9193d11eeeea933e293acd5e0f03fa4e9887186b (diff)
downloadnx-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.cpp667
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
-}