Hi,

Please find the attached patch to fix RM #3122 : Backup not working on
certificate (SSL) protected servers.

The attached patch fixes the issue in the following modules:

1. Backup
2. Restore
3. Import/Export
4. Maintenance

Thanks,
Khushboo
diff --git a/web/migrations/versions/12958d9f4970_.py b/web/migrations/versions/12958d9f4970_.py
new file mode 100644
index 0000000..aa2c5fd
--- /dev/null
+++ b/web/migrations/versions/12958d9f4970_.py
@@ -0,0 +1,33 @@
+##########################################################################
+#
+# pgAdmin 4 - PostgreSQL Tools
+#
+# Copyright (C) 2013 - 2018, The pgAdmin Development Team
+# This software is released under the PostgreSQL Licence
+#
+##########################################################################
+"""
+Add SSL support for batch processes (RM #3122)
+
+Revision ID: 12958d9f4970
+Revises: 50aad68f99c2
+Create Date: 2018-03-13 21:21:25.455315
+
+"""
+from pgadmin.model import db
+
+# revision identifiers, used by Alembic.
+revision = '12958d9f4970'
+down_revision = '50aad68f99c2'
+branch_labels = None
+depends_on = None
+
+
+def upgrade():
+    db.engine.execute(
+        'ALTER TABLE process ADD COLUMN ssl TEXT'
+    )
+
+
+def downgrade():
+    pass
diff --git a/web/pgadmin/misc/bgprocess/processes.py b/web/pgadmin/misc/bgprocess/processes.py
index c456b4f..4a6e60a 100644
--- a/web/pgadmin/misc/bgprocess/processes.py
+++ b/web/pgadmin/misc/bgprocess/processes.py
@@ -19,7 +19,8 @@ from datetime import datetime
 from pickle import dumps, loads
 from subprocess import Popen
 
-from pgadmin.utils import IS_PY2, u, file_quote, fs_encoding
+from pgadmin.utils import IS_PY2, u, file_quote, fs_encoding, \
+    get_complete_file_path
 
 import pytz
 from dateutil import parser
@@ -61,13 +62,14 @@ class BatchProcess(object):
 
         self.id = self.desc = self.cmd = self.args = self.log_dir = \
             self.stdout = self.stderr = self.stime = self.etime = \
-            self.ecode = None
+            self.ecode = self.ssl = None
 
         if 'id' in kwargs:
             self._retrieve_process(kwargs['id'])
         else:
+            ssl = kwargs.get('ssl', None)
             self._create_process(
-                kwargs['desc'], kwargs['cmd'], kwargs['args']
+                kwargs['desc'], kwargs['cmd'], kwargs['args'], ssl
             )
 
     def _retrieve_process(self, _id):
@@ -110,8 +112,10 @@ class BatchProcess(object):
         self.etime = p.end_time
         # Exit code
         self.ecode = p.exit_code
+        # SSL
+        self.ssl = p.ssl
 
-    def _create_process(self, _desc, _cmd, _args):
+    def _create_process(self, _desc, _cmd, _args, ssl):
         ctime = get_current_time(format='%y%m%d%H%M%S%f')
         log_dir = os.path.join(
             config.SESSION_DB_PATH, 'process_logs'
@@ -163,6 +167,8 @@ class BatchProcess(object):
         self.etime = None
         # Exit code
         self.ecode = None
+        # SSL
+        self.ssl = dumps(ssl)
 
         # Arguments
         self.args = _args
@@ -199,7 +205,8 @@ class BatchProcess(object):
             if IS_PY2 and hasattr(args_val, 'decode') else args_val,
             logdir=log_dir,
             desc=tmp_desc,
-            user_id=current_user.id
+            user_id=current_user.id,
+            ssl=self.ssl
         )
         db.session.add(j)
         db.session.commit()
@@ -330,6 +337,20 @@ class BatchProcess(object):
         env['OUTDIR'] = self.log_dir
         env['PGA_BGP_FOREGROUND'] = "1"
 
+        # Set environment variable for SSL
+        ssl = loads(self.ssl)
+        if ssl and isinstance(ssl, dict):
+            ssl_mode = ssl.get('ssl_mode', None)
+            sslcert = ssl.get('sslcert', None)
+            sslkey = ssl.get('sslkey', None)
+            sslrootcert = ssl.get('sslrootcert', None)
+
+            if ssl_mode and sslcert and sslkey and sslrootcert:
+                env['PGSSLMODE'] = ssl_mode
+                env['PGSSLCERT'] = get_complete_file_path(sslcert)
+                env['PGSSLKEY'] = get_complete_file_path(sslkey)
+                env['PGSSLROOTCERT'] = get_complete_file_path(sslrootcert)
+
         if cb is not None:
             cb(env)
 
diff --git a/web/pgadmin/model/__init__.py b/web/pgadmin/model/__init__.py
index 11bc9f0..8a3f96f 100644
--- a/web/pgadmin/model/__init__.py
+++ b/web/pgadmin/model/__init__.py
@@ -238,6 +238,7 @@ class Process(db.Model):
     end_time = db.Column(db.String(), nullable=True)
     exit_code = db.Column(db.Integer(), nullable=True)
     acknowledge = db.Column(db.String(), nullable=True)
+    ssl = db.Column(db.String(), nullable=True)
 
 
 class Keys(db.Model):
diff --git a/web/pgadmin/tools/backup/__init__.py b/web/pgadmin/tools/backup/__init__.py
index 940ef5b..efb9767 100644
--- a/web/pgadmin/tools/backup/__init__.py
+++ b/web/pgadmin/tools/backup/__init__.py
@@ -300,6 +300,7 @@ def create_backup_job(sid):
         '--database',
         server.maintenance_db
     ]
+
     if 'role' in data and data['role']:
         args.append('--role')
         args.append(data['role'])
@@ -310,6 +311,16 @@ def create_backup_job(sid):
     if data['type'] == 'global':
         args.append('--globals-only')
 
+    # SSL
+    ssl = {}
+    if server.sslcert is not None and \
+            server.sslkey is not None and \
+            server.sslrootcert is not None:
+        ssl['ssl_mode'] = server.ssl_mode
+        ssl['sslcert'] = server.sslcert
+        ssl['sslkey'] = server.sslkey
+        ssl['sslrootcert'] = server.sslrootcert
+
     try:
         p = BatchProcess(
             desc=BackupMessage(
@@ -320,7 +331,7 @@ def create_backup_job(sid):
                 ) else data['file'],
                 *args
             ),
-            cmd=utility, args=args
+            cmd=utility, args=args, ssl=ssl
         )
         manager.export_password_env(p.id)
         p.start()
@@ -473,6 +484,16 @@ def create_backup_objects_job(sid):
 
     args.append(data['database'])
 
+    # SSL
+    ssl = {}
+    if server.sslcert is not None and \
+            server.sslkey is not None and \
+            server.sslrootcert is not None:
+        ssl['ssl_mode'] = server.ssl_mode
+        ssl['sslcert'] = server.sslcert
+        ssl['sslkey'] = server.sslkey
+        ssl['sslrootcert'] = server.sslrootcert
+
     try:
         p = BatchProcess(
             desc=BackupMessage(
@@ -483,7 +504,7 @@ def create_backup_objects_job(sid):
                 *args,
                 database=data['database']
             ),
-            cmd=utility, args=args
+            cmd=utility, args=args, ssl=ssl
         )
         manager.export_password_env(p.id)
         p.start()
diff --git a/web/pgadmin/tools/import_export/__init__.py b/web/pgadmin/tools/import_export/__init__.py
index 3f83fd4..0ad23f0 100644
--- a/web/pgadmin/tools/import_export/__init__.py
+++ b/web/pgadmin/tools/import_export/__init__.py
@@ -293,6 +293,16 @@ def create_import_export_job(sid):
 
     args = ['--command', query]
 
+    # SSL
+    ssl = {}
+    if server.sslcert is not None and \
+            server.sslkey is not None and \
+            server.sslrootcert is not None:
+        ssl['ssl_mode'] = server.ssl_mode
+        ssl['sslcert'] = server.sslcert
+        ssl['sslkey'] = server.sslkey
+        ssl['sslrootcert'] = server.sslrootcert
+
     try:
         p = BatchProcess(
             desc=IEMessage(
@@ -303,7 +313,8 @@ def create_import_export_job(sid):
                 storage_dir,
                 utility, *args
             ),
-            cmd=utility, args=args
+            cmd=utility, args=args,
+            ssl=ssl
         )
         manager.export_password_env(p.id)
 
diff --git a/web/pgadmin/tools/maintenance/__init__.py b/web/pgadmin/tools/maintenance/__init__.py
index 8416a20..cfdabf0 100644
--- a/web/pgadmin/tools/maintenance/__init__.py
+++ b/web/pgadmin/tools/maintenance/__init__.py
@@ -230,10 +230,21 @@ def create_maintenance_job(sid, did):
         '--command', query
     ]
 
+    # SSL
+    ssl = {}
+    if server.sslcert is not None and \
+            server.sslkey is not None and \
+            server.sslrootcert is not None:
+        ssl['ssl_mode'] = server.ssl_mode
+        ssl['sslcert'] = server.sslcert
+        ssl['sslkey'] = server.sslkey
+        ssl['sslrootcert'] = server.sslrootcert
+
     try:
         p = BatchProcess(
             desc=Message(sid, data, query),
-            cmd=utility, args=args
+            cmd=utility, args=args,
+            ssl=ssl
         )
         manager.export_password_env(p.id)
         p.start()
diff --git a/web/pgadmin/tools/restore/__init__.py b/web/pgadmin/tools/restore/__init__.py
index 6afa7b4..1865419 100644
--- a/web/pgadmin/tools/restore/__init__.py
+++ b/web/pgadmin/tools/restore/__init__.py
@@ -317,6 +317,16 @@ def create_restore_job(sid):
 
     args.append(fs_short_path(_file))
 
+    # SSL
+    ssl = {}
+    if server.sslcert is not None and \
+            server.sslkey is not None and \
+            server.sslrootcert is not None:
+        ssl['ssl_mode'] = server.ssl_mode
+        ssl['sslcert'] = server.sslcert
+        ssl['sslkey'] = server.sslkey
+        ssl['sslrootcert'] = server.sslrootcert
+
     try:
         p = BatchProcess(
             desc=RestoreMessage(
@@ -326,7 +336,8 @@ def create_restore_job(sid):
                 ) else data['file'],
                 *args
             ),
-            cmd=utility, args=args
+            cmd=utility, args=args,
+            ssl=ssl
         )
         manager.export_password_env(p.id)
         p.start()

Reply via email to