From 6696b3c3167f9cdb8a7d8ca0388fc76d88742070 Mon Sep 17 00:00:00 2001 From: Dave Page Date: Mon, 6 Mar 2017 14:53:49 +0000 Subject: [PATCH] Authenticate the runtime to the server. Fixes #2228 --- runtime/Server.cpp | 6 ++++-- runtime/Server.h | 3 ++- runtime/pgAdmin4.cpp | 9 +++++++-- web/pgAdmin4.py | 7 +++++++ web/pgadmin/__init__.py | 15 ++++++++++++++- 5 files changed, 34 insertions(+), 6 deletions(-) diff --git a/runtime/Server.cpp b/runtime/Server.cpp index e5be20569..d655119cb 100644 --- a/runtime/Server.cpp +++ b/runtime/Server.cpp @@ -43,10 +43,11 @@ static void add_to_path(QString &python_path, QString path, bool prepend=false) } } -Server::Server(quint16 port) +Server::Server(quint16 port, QString key) { - // Appserver port + // Appserver port etc m_port = port; + m_key = key; m_wcAppName = NULL; // Initialise Python @@ -255,6 +256,7 @@ void Server::run() // Set the port number PyRun_SimpleString(QString("PGADMIN_PORT = %1").arg(m_port).toLatin1()); + PyRun_SimpleString(QString("PGADMIN_KEY = '%1'").arg(m_key).toLatin1()); // Run the app! #ifdef PYTHON2 diff --git a/runtime/Server.h b/runtime/Server.h index 8df8503bb..c8afbddb1 100644 --- a/runtime/Server.h +++ b/runtime/Server.h @@ -23,7 +23,7 @@ class Server : public QThread Q_OBJECT public: - Server(quint16 port); + Server(quint16 port, QString key); ~Server(); bool Init(); @@ -39,6 +39,7 @@ private: QString m_error; quint16 m_port; + QString m_key; wchar_t *m_wcAppName; }; diff --git a/runtime/pgAdmin4.cpp b/runtime/pgAdmin4.cpp index a16420bc0..0130e027e 100644 --- a/runtime/pgAdmin4.cpp +++ b/runtime/pgAdmin4.cpp @@ -23,6 +23,7 @@ #include #include #include +#include #endif // App headers @@ -70,6 +71,10 @@ int main(int argc, char * argv[]) port = socket.localPort(); } + // Generate a random key to authenticate the client to the server + QString key = QUuid::createUuid().toString(); + key = key.mid(1, key.length() - 2); + // Fire up the webserver Server *server; @@ -77,7 +82,7 @@ int main(int argc, char * argv[]) while (done != true) { - server = new Server(port); + server = new Server(port, key); if (!server->Init()) { @@ -140,7 +145,7 @@ int main(int argc, char * argv[]) // Generate the app server URL - QString appServerUrl = QString("http://localhost:%1/").arg(port); + QString appServerUrl = QString("http://localhost:%1/?key=%2").arg(port).arg(key); // Now the server should be up, we'll attempt to connect and get a response. // We'll retry in a loop a few time before aborting if necessary. diff --git a/web/pgAdmin4.py b/web/pgAdmin4.py index 0959b8321..b95ad1cc9 100644 --- a/web/pgAdmin4.py +++ b/web/pgAdmin4.py @@ -74,6 +74,13 @@ else: # Let the application save the status about the runtime for using it later. app.PGADMIN_RUNTIME = PGADMIN_RUNTIME +# Set the key if appropriate +if 'PGADMIN_KEY' in globals(): + app.PGADMIN_KEY = globals()['PGADMIN_KEY'] + app.logger.debug("Desktop security key: %s" % app.PGADMIN_KEY) +else: + app.PGADMIN_KEY = '' + # Output a startup message if we're not under the runtime and startup. # If we're under WSGI, we don't need to worry about this if __name__ == '__main__': diff --git a/web/pgadmin/__init__.py b/web/pgadmin/__init__.py index b9750e809..c5d312b72 100644 --- a/web/pgadmin/__init__.py +++ b/web/pgadmin/__init__.py @@ -414,7 +414,13 @@ def create_app(app_name=config.APP_NAME): @app.before_request def before_request(): """Login the default user if running in desktop mode""" - if config.SERVER_MODE is False: + if app.PGADMIN_RUNTIME == True: + if ( + (not 'key' in request.args or request.args['key'] != app.PGADMIN_KEY) and + request.cookies.get('PGADMIN_KEY') != app.PGADMIN_KEY + ): + abort(401) + user = user_datastore.get_user(config.DESKTOP_USER) # Throw an error if we failed to find the desktop user, to give @@ -429,6 +435,13 @@ def create_app(app_name=config.APP_NAME): login_user(user) + @app.after_request + def after_request(response): + if 'key' in request.args: + response.set_cookie('PGADMIN_KEY', value=request.args['key']) + + return response + ########################################################################## # Minify output ##########################################################################