diff --git a/SOURCES/sos-bz2011337-dropbox-to-sftp.patch b/SOURCES/sos-bz2011337-dropbox-to-sftp.patch
new file mode 100644
index 0000000..c3d74b7
--- /dev/null
+++ b/SOURCES/sos-bz2011337-dropbox-to-sftp.patch
@@ -0,0 +1,605 @@
+From a0d7fc6560439fc6de7ae7d246604c7b8f605182 Mon Sep 17 00:00:00 2001
+From: Pavel Moravec <pmoravec@redhat.com>
+Date: Wed, 6 Oct 2021 14:05:53 +0200
+Subject: [PATCH] [Red Hat] Update policy to use SFTP instead of legacy FTP
+ dropbox
+
+This is a backport of #2552 / #2467 to reflect on python2 systems the
+planned FTP dropbox replacement by SFTP system.
+
+Related: #2552
+Resolves: #2715
+
+Signed-off-by: Pavel Moravec <pmoravec@redhat.com>
+---
+ man/en/sosreport.1       |  14 +++++
+ sos/__init__.py          |   6 +-
+ sos/policies/__init__.py | 115 ++++++++++++++++++++++++++++++++++---
+ sos/policies/redhat.py   | 121 ++++++++++++++++++++++++++++-----------
+ sos/sosreport.py         |   3 +
+ 5 files changed, 215 insertions(+), 44 deletions(-)
+
+diff --git a/man/en/sosreport.1 b/man/en/sosreport.1
+index 4f7185f1..210f073f 100644
+--- a/man/en/sosreport.1
++++ b/man/en/sosreport.1
+@@ -32,6 +32,7 @@ sosreport \- Collect and package diagnostic and support data
+           [--encrypt-pass PASS]\fR
+           [--upload] [--upload-url url] [--upload-user user]\fR
+           [--upload-directory dir] [--upload-pass pass]\fR
++          [--upload-protocol protocol]\fR
+           [--experimental]\fR
+           [-h|--help]\fR
+ 
+@@ -314,6 +315,19 @@ when prompted rather than using this option.
+ Specify a directory to upload to, if one is not specified by a vendor default location
+ or if your destination server does not allow writes to '/'.
+ .TP
++.B \--upload-protocol PROTO
++Manually specify the protocol to use for uploading to the target \fBupload-url\fR.
++
++Normally this is determined via the upload address, assuming that the protocol is part
++of the address provided, e.g. 'https://example.com'. By using this option, sos will skip
++the protocol check and use the method defined for the specified PROTO.
++
++For RHEL systems, setting this option to \fBsftp\fR will skip the initial attempt to
++upload to the Red Hat Customer Portal, and only attempt an upload to Red Hat's SFTP server,
++which is typically used as a fallback target.
++
++Valid values for PROTO are: 'auto' (default), 'https', 'ftp', 'sftp'.
++.TP
+ .B \--experimental
+ Enable plugins marked as experimental. Experimental plugins may not have
+ been tested for this port or may still be under active development.
+diff --git a/sos/__init__.py b/sos/__init__.py
+index 111e066e..b4abf533 100644
+--- a/sos/__init__.py
++++ b/sos/__init__.py
+@@ -58,7 +58,7 @@ _arg_names = [
+     'no_postproc', 'note', 'onlyplugins', 'plugin_timeout', 'plugopts',
+     'preset', 'profiles', 'quiet', 'since', 'sysroot', 'threads', 'tmp_dir',
+     'upload', 'upload_url', 'upload_directory', 'upload_user', 'upload_pass',
+-    'verbosity', 'verify'
++    'upload_protocol', 'verbosity', 'verify'
+ ]
+ 
+ #: Arguments with non-zero default values
+@@ -69,7 +69,8 @@ _arg_defaults = {
+     "preset": "auto",
+     # Verbosity has an explicit zero default since the ArgumentParser
+     # count action default is None.
+-    "verbosity": 0
++    "verbosity": 0,
++    "upload_protocol": "auto"
+ }
+ 
+ 
+@@ -200,6 +201,7 @@ class SoSOptions(object):
+         self.upload_directory = ""
+         self.upload_user = ""
+         self.upload_pass = ""
++        self.upload_protocol = _arg_defaults["upload_protocol"]
+         self.verbosity = _arg_defaults["verbosity"]
+         self.verify = False
+         self._nondefault = set()
+diff --git a/sos/policies/__init__.py b/sos/policies/__init__.py
+index 1579ff5d..acda6379 100644
+--- a/sos/policies/__init__.py
++++ b/sos/policies/__init__.py
+@@ -15,7 +15,8 @@ from pwd import getpwuid
+ from sos.utilities import (ImporterHelper,
+                            import_module,
+                            shell_out,
+-                           sos_get_command_output)
++                           sos_get_command_output,
++                           is_executable)
+ from sos.plugins import IndependentPlugin, ExperimentalPlugin
+ from sos import _sos as _
+ from sos import SoSOptions, _arg_names
+@@ -944,6 +945,7 @@ class LinuxPolicy(Policy):
+         self.upload_user = cmdline_opts.upload_user
+         self.upload_directory = cmdline_opts.upload_directory
+         self.upload_password = cmdline_opts.upload_pass
++        self.upload_archive_name = ''
+ 
+         if not cmdline_opts.batch and not \
+                 cmdline_opts.quiet:
+@@ -1029,7 +1031,7 @@ class LinuxPolicy(Policy):
+                                             this method
+ 
+         """
+-        self.upload_archive = archive
++        self.upload_archive_name = archive
+         if not self.upload_url:
+             self.upload_url = self.get_upload_url()
+         if not self.upload_url:
+@@ -1051,7 +1053,9 @@ class LinuxPolicy(Policy):
+             'sftp': self.upload_sftp,
+             'https': self.upload_https
+         }
+-        if '://' not in self.upload_url:
++        if self.commons['cmdlineopts'].upload_protocol in prots.keys():
++            return prots[self.commons['cmdlineopts'].upload_protocol]
++        elif '://' not in self.upload_url:
+             raise Exception("Must provide protocol in upload URL")
+         prot, url = self.upload_url.split('://')
+         if prot not in prots.keys():
+@@ -1092,7 +1096,7 @@ class LinuxPolicy(Policy):
+         """
+         return self.upload_password or self._upload_password
+ 
+-    def upload_sftp(self):
++    def upload_sftp(self, user=None, password=None):
+         """Attempts to upload the archive to an SFTP location.
+ 
+         Due to the lack of well maintained, secure, and generally widespread
+@@ -1102,7 +1106,102 @@ class LinuxPolicy(Policy):
+         Do not override this method with one that uses python-paramiko, as the
+         upstream sos team will reject any PR that includes that dependency.
+         """
+-        raise NotImplementedError("SFTP support is not yet implemented")
++        # if we somehow don't have sftp available locally, fail early
++        if not is_executable('sftp'):
++            raise Exception('SFTP is not locally supported')
++
++        # soft dependency on python-pexpect, which we need to use to control
++        # sftp login since as of this writing we don't have a viable solution
++        # via ssh python bindings commonly available among downstreams
++        try:
++            import pexpect
++        except ImportError:
++            raise Exception('SFTP upload requires python-pexpect, which is '
++                            'not currently installed')
++
++        sftp_connected = False
++
++        if not user:
++            user = self.get_upload_user()
++        if not password:
++            password = self.get_upload_password()
++
++        # need to strip the protocol prefix here
++        sftp_url = self.get_upload_url().replace('sftp://', '')
++        sftp_cmd = "sftp -oStrictHostKeyChecking=no %s@%s" % (user, sftp_url)
++        ret = pexpect.spawn(sftp_cmd, encoding='utf-8')
++
++        sftp_expects = [
++            u'sftp>',
++            u'password:',
++            u'Connection refused',
++            pexpect.TIMEOUT,
++            pexpect.EOF
++        ]
++
++        idx = ret.expect(sftp_expects, timeout=15)
++
++        if idx == 0:
++            sftp_connected = True
++        elif idx == 1:
++            ret.sendline(password)
++            pass_expects = [
++                u'sftp>',
++                u'Permission denied',
++                pexpect.TIMEOUT,
++                pexpect.EOF
++            ]
++            sftp_connected = ret.expect(pass_expects, timeout=10) == 0
++            if not sftp_connected:
++                ret.close()
++                raise Exception("Incorrect username or password for %s"
++                                % self.get_upload_url_string())
++        elif idx == 2:
++            raise Exception("Connection refused by %s. Incorrect port?"
++                            % self.get_upload_url_string())
++        elif idx == 3:
++            raise Exception("Timeout hit trying to connect to %s"
++                            % self.get_upload_url_string())
++        elif idx == 4:
++            raise Exception("Unexpected error trying to connect to sftp: %s"
++                            % ret.before)
++
++        if not sftp_connected:
++            ret.close()
++            raise Exception("Unable to connect via SFTP to %s"
++                            % self.get_upload_url_string())
++
++        put_cmd = 'put %s %s' % (self.upload_archive_name,
++                                 self._get_sftp_upload_name())
++        ret.sendline(put_cmd)
++
++        put_expects = [
++            u'100%',
++            pexpect.TIMEOUT,
++            pexpect.EOF
++        ]
++
++        put_success = ret.expect(put_expects, timeout=180)
++
++        if put_success == 0:
++            ret.sendline('bye')
++            return True
++        elif put_success == 1:
++            raise Exception("Timeout expired while uploading")
++        elif put_success == 2:
++            raise Exception("Unknown error during upload: %s" % ret.before)
++        else:
++            raise Exception("Unexpected response from server: %s" % ret.before)
++
++    def _get_sftp_upload_name(self):
++        """If a specific file name pattern is required by the SFTP server,
++        override this method in the relevant Policy. Otherwise the archive's
++        name on disk will be used
++
++        :returns:       Filename as it will exist on the SFTP server
++        :rtype:         ``str``
++        """
++        return self.upload_archive_name.split('/')[-1]
+ 
+     def _upload_https_streaming(self, archive):
+         """If upload_https() needs to use requests.put(), this method is used
+@@ -1148,7 +1247,7 @@ class LinuxPolicy(Policy):
+             raise Exception("Unable to upload due to missing python requests "
+                             "library")
+ 
+-        with open(self.upload_archive, 'rb') as arc:
++        with open(self.upload_archive_name, 'rb') as arc:
+             if not self._use_https_streaming:
+                 r = self._upload_https_no_stream(arc)
+             else:
+@@ -1214,9 +1313,9 @@ class LinuxPolicy(Policy):
+                                 % directory)
+ 
+         try:
+-            with open(self.upload_archive, 'rb') as _arcfile:
++            with open(self.upload_archive_name, 'rb') as _arcfile:
+                 session.storbinary(
+-                    "STOR %s" % self.upload_archive.split('/')[-1],
++                    "STOR %s" % self.upload_archive_name.split('/')[-1],
+                     _arcfile
+                 )
+             session.quit()
+diff --git a/sos/policies/redhat.py b/sos/policies/redhat.py
+index 3412f445..4da96894 100644
+--- a/sos/policies/redhat.py
++++ b/sos/policies/redhat.py
+@@ -10,6 +10,7 @@
+ 
+ # This enables the use of with syntax in python 2.5 (e.g. jython)
+ from __future__ import print_function
++import json
+ import os
+ import sys
+ import re
+@@ -19,6 +20,12 @@ from sos.policies import LinuxPolicy, PackageManager, PresetDefaults
+ from sos import _sos as _
+ from sos import SoSOptions
+ 
++try:
++    import requests
++    REQUESTS_LOADED = True
++except ImportError:
++    REQUESTS_LOADED = False
++
+ OS_RELEASE = "/etc/os-release"
+ 
+ # In python2.7, input() will not properly return strings, and on python3.x
+@@ -44,9 +51,8 @@ class RedHatPolicy(LinuxPolicy):
+     _host_sysroot = '/'
+     default_scl_prefix = '/opt/rh'
+     name_pattern = 'friendly'
+-    upload_url = 'dropbox.redhat.com'
+-    upload_user = 'anonymous'
+-    upload_directory = '/incoming'
++    upload_url = None
++    upload_user = None
+ 
+     def __init__(self, sysroot=None):
+         super(RedHatPolicy, self).__init__(sysroot=sysroot)
+@@ -252,7 +258,7 @@ No changes will be made to system configuration.
+ """
+ 
+ RH_API_HOST = "https://access.redhat.com"
+-RH_FTP_HOST = "ftp://dropbox.redhat.com"
++RH_SFTP_HOST = "sftp://sftp.access.redhat.com"
+ 
+ 
+ class RHELPolicy(RedHatPolicy):
+@@ -268,9 +274,7 @@ An archive containing the collected information will be \
+ generated in %(tmpdir)s and may be provided to a %(vendor)s \
+ support representative.
+ """ + disclaimer_text + "%(vendor_text)s\n")
+-    _upload_url = RH_FTP_HOST
+-    _upload_user = 'anonymous'
+-    _upload_directory = '/incoming'
++    _upload_url = RH_SFTP_HOST
+ 
+     def __init__(self, sysroot=None):
+         super(RHELPolicy, self).__init__(sysroot=sysroot)
+@@ -309,33 +313,17 @@ support representative.
+             return
+         if self.case_id:
+             self.upload_user = input(_(
+-                "Enter your Red Hat Customer Portal username (empty to use "
+-                "public dropbox): ")
++                "Enter your Red Hat Customer Portal username for uploading ["
++                "empty for anonymous SFTP]: ")
+             )
+-            if not self.upload_user:
+-                self.upload_url = RH_FTP_HOST
+-                self.upload_user = self._upload_user
+-
+-    def _upload_user_set(self):
+-        user = self.get_upload_user()
+-        return user and (user != 'anonymous')
+ 
+     def get_upload_url(self):
+         if self.upload_url:
+             return self.upload_url
+-        if self.commons['cmdlineopts'].upload_url:
++        elif self.commons['cmdlineopts'].upload_url:
+             return self.commons['cmdlineopts'].upload_url
+-        # anonymous FTP server should be used as fallback when either:
+-        # - case id is not set, or
+-        # - upload user isn't set AND batch mode prevents to prompt for it
+-        if (not self.case_id) or \
+-           ((not self._upload_user_set()) and
+-               self.commons['cmdlineopts'].batch):
+-            self.upload_user = self._upload_user
+-            if self.upload_directory is None:
+-                self.upload_directory = self._upload_directory
+-            self.upload_password = None
+-            return RH_FTP_HOST
++        elif self.commons['cmdlineopts'].upload_protocol == 'sftp':
++            return RH_SFTP_HOST
+         else:
+             rh_case_api = "/hydra/rest/cases/%s/attachments"
+             return RH_API_HOST + rh_case_api % self.case_id
+@@ -348,13 +336,78 @@ support representative.
+     def get_upload_url_string(self):
+         if self.get_upload_url().startswith(RH_API_HOST):
+             return "Red Hat Customer Portal"
+-        return self.upload_url or RH_FTP_HOST
++        elif self.get_upload_url().startswith(RH_SFTP_HOST):
++            return "Red Hat Secure FTP"
++        return self.upload_url
+ 
+-    def get_upload_user(self):
+-        # if this is anything other than dropbox, annonymous won't work
+-        if self.upload_url != RH_FTP_HOST:
+-            return self.upload_user
+-        return self._upload_user
++    def _get_sftp_upload_name(self):
++        """The RH SFTP server will only automatically connect file uploads to
++        cases if the filename _starts_ with the case number
++        """
++        if self.case_id:
++            return "%s_%s" % (self.case_id,
++                              self.upload_archive_name.split('/')[-1])
++        return self.upload_archive_name
++
++    def upload_sftp(self):
++        """Override the base upload_sftp to allow for setting an on-demand
++        generated anonymous login for the RH SFTP server if a username and
++        password are not given
++        """
++        if RH_SFTP_HOST.split('//')[1] not in self.get_upload_url():
++            return super(RHELPolicy, self).upload_sftp()
++
++        if not REQUESTS_LOADED:
++            raise Exception("python-requests is not installed and is required"
++                            " for obtaining SFTP auth token.")
++        _token = None
++        _user = None
++        # we have a username and password, but we need to reset the password
++        # to be the token returned from the auth endpoint
++        if self.get_upload_user() and self.get_upload_password():
++            url = RH_API_HOST + '/hydra/rest/v1/sftp/token'
++            auth = self.get_upload_https_auth()
++            ret = requests.get(url, auth=auth, timeout=10)
++            if ret.status_code == 200:
++                # credentials are valid
++                _user = self.get_upload_user()
++                _token = json.loads(ret.text)['token']
++            else:
++                print("Unable to retrieve Red Hat auth token using provided "
++                      "credentials. Will try anonymous.")
++        # we either do not have a username or password/token, or both
++        if not _token:
++            aurl = RH_API_HOST + '/hydra/rest/v1/sftp/token?isAnonymous=true'
++            anon = requests.get(aurl, timeout=10)
++            if anon.status_code == 200:
++                resp = json.loads(anon.text)
++                _user = resp['username']
++                _token = resp['token']
++                print("Using anonymous user %s for upload. Please inform your "
++                      "support engineer." % _user)
++        if _user and _token:
++            return super(RHELPolicy, self).upload_sftp(user=_user,
++                                                       password=_token)
++        raise Exception("Could not retrieve valid or anonymous credentials")
++
++    def upload_archive(self, archive):
++        """Override the base upload_archive to provide for automatic failover
++        from RHCP failures to the public RH dropbox
++        """
++        try:
++            if not self.get_upload_user() or not self.get_upload_password():
++                self.upload_url = RH_SFTP_HOST
++            uploaded = super(RHELPolicy, self).upload_archive(archive)
++        except Exception:
++            uploaded = False
++            if not self.upload_url.startswith(RH_API_HOST):
++                raise
++            else:
++                print("Upload to Red Hat Customer Portal failed. Trying %s"
++                      % RH_SFTP_HOST)
++                self.upload_url = RH_SFTP_HOST
++                uploaded = super(RHELPolicy, self).upload_archive(archive)
++        return uploaded
+ 
+     def dist_version(self):
+         try:
+diff --git a/sos/sosreport.py b/sos/sosreport.py
+index 5f3fb411..170129ea 100644
+--- a/sos/sosreport.py
++++ b/sos/sosreport.py
+@@ -255,6 +255,9 @@ def _get_parser():
+                         help="Username to authenticate to upload server with")
+     parser.add_argument("--upload-pass", default=None,
+                         help="Password to authenticate to upload server with")
++    parser.add_argument("--upload-protocol", default='auto',
++                        choices=['auto', 'https', 'ftp', 'sftp'],
++                        help="Manually specify the upload protocol")
+ 
+     # Group to make add/del preset exclusive
+     preset_grp = parser.add_mutually_exclusive_group()
+-- 
+2.31.1
+
+From 97de66bc3228b29ff33e5ba67733f15065705d89 Mon Sep 17 00:00:00 2001
+From: root <root@bvassova-satellite69.gsslab.brq.redhat.com>
+Date: Tue, 23 Nov 2021 11:44:33 +0100
+Subject: [PATCH] [redhat] SFTP api change Backporting SFTP related changes
+ from #2764 and #2772.
+
+Related to: #2764, #2772
+Resolves: #2771
+
+Signed-off-by: Barbora Vassova <bvassova@redhat.com>
+---
+ sos/policies/__init__.py |  7 +++++--
+ sos/policies/redhat.py   | 18 +++++++++---------
+ 2 files changed, 14 insertions(+), 11 deletions(-)
+
+diff --git a/sos/policies/__init__.py b/sos/policies/__init__.py
+index acda63795..d78e79cfc 100644
+--- a/sos/policies/__init__.py
++++ b/sos/policies/__init__.py
+@@ -1178,7 +1178,8 @@ def upload_sftp(self, user=None, password=None):
+         put_expects = [
+             u'100%',
+             pexpect.TIMEOUT,
+-            pexpect.EOF
++            pexpect.EOF,
++            u'No such file or directory'
+         ]
+ 
+         put_success = ret.expect(put_expects, timeout=180)
+@@ -1190,6 +1191,8 @@ def upload_sftp(self, user=None, password=None):
+             raise Exception("Timeout expired while uploading")
+         elif put_success == 2:
+             raise Exception("Unknown error during upload: %s" % ret.before)
++        elif put_success == 3:
++            raise Exception("Unable to write archive to destination")
+         else:
+             raise Exception("Unexpected response from server: %s" % ret.before)
+ 
+@@ -1252,7 +1255,7 @@ def upload_https(self):
+                 r = self._upload_https_no_stream(arc)
+             else:
+                 r = self._upload_https_streaming(arc)
+-            if r.status_code != 201:
++            if r.status_code != 200 and r.status_code != 201:
+                 if r.status_code == 401:
+                     raise Exception(
+                         "Authentication failed: invalid user credentials"
+diff --git a/sos/policies/redhat.py b/sos/policies/redhat.py
+index 4da968945..960e7cd2a 100644
+--- a/sos/policies/redhat.py
++++ b/sos/policies/redhat.py
+@@ -257,7 +257,7 @@ def get_tmp_dir(self, opt_tmp_dir):
+ No changes will be made to system configuration.
+ """
+ 
+-RH_API_HOST = "https://access.redhat.com"
++RH_API_HOST = "https://api.access.redhat.com"
+ RH_SFTP_HOST = "sftp://sftp.access.redhat.com"
+ 
+ 
+@@ -325,7 +325,7 @@ def get_upload_url(self):
+         elif self.commons['cmdlineopts'].upload_protocol == 'sftp':
+             return RH_SFTP_HOST
+         else:
+-            rh_case_api = "/hydra/rest/cases/%s/attachments"
++            rh_case_api = "/support/v1/cases/%s/attachments"
+             return RH_API_HOST + rh_case_api % self.case_id
+ 
+     def _get_upload_headers(self):
+@@ -344,10 +344,10 @@ def _get_sftp_upload_name(self):
+         """The RH SFTP server will only automatically connect file uploads to
+         cases if the filename _starts_ with the case number
+         """
++        fname = self.upload_archive_name.split('/')[-1]
+         if self.case_id:
+-            return "%s_%s" % (self.case_id,
+-                              self.upload_archive_name.split('/')[-1])
+-        return self.upload_archive_name
++            return "%s_%s" % (self.case_id, fname)
++        return fname
+ 
+     def upload_sftp(self):
+         """Override the base upload_sftp to allow for setting an on-demand
+@@ -362,12 +362,12 @@ def upload_sftp(self):
+                             " for obtaining SFTP auth token.")
+         _token = None
+         _user = None
++        url = RH_API_HOST + '/support/v2/sftp/token'
+         # we have a username and password, but we need to reset the password
+         # to be the token returned from the auth endpoint
+         if self.get_upload_user() and self.get_upload_password():
+-            url = RH_API_HOST + '/hydra/rest/v1/sftp/token'
+             auth = self.get_upload_https_auth()
+-            ret = requests.get(url, auth=auth, timeout=10)
++            ret = requests.post(url, auth=auth, timeout=10)
+             if ret.status_code == 200:
+                 # credentials are valid
+                 _user = self.get_upload_user()
+@@ -377,8 +377,8 @@ def upload_sftp(self):
+                       "credentials. Will try anonymous.")
+         # we either do not have a username or password/token, or both
+         if not _token:
+-            aurl = RH_API_HOST + '/hydra/rest/v1/sftp/token?isAnonymous=true'
+-            anon = requests.get(aurl, timeout=10)
++            adata = {"isAnonymous": True}
++            anon = requests.post(url, data=json.dumps(adata), timeout=10)
+             if anon.status_code == 200:
+                 resp = json.loads(anon.text)
+                 _user = resp['username']
+From f231f9e502b2f98910c864c6c9000ae499280051 Mon Sep 17 00:00:00 2001
+From: Jake Hunsaker <jhunsake@redhat.com>
+Date: Tue, 4 Jan 2022 11:16:57 -0500
+Subject: [PATCH] [report] Handle exceptionally old pexpect versions
+
+Depending on configuration, certain downstreams may provide pexpect 2.3
+or 4.6 (or later). The backport for SFTP upload support assumed a 4.x
+version pexpect, however 2.x does not support the `encoding` parameter
+to `pexpect.spawn()`.
+
+Add a version check to determine if that parameter needs to be used or
+not. Note that this does not need to be implemented against `main`, as
+all supported downstreams for `main` support a minimum version of 4.x.
+
+Signed-off-by: Jake Hunsaker <jhunsake@redhat.com>
+---
+ sos/policies/__init__.py | 8 +++++++-
+ 1 file changed, 7 insertions(+), 1 deletion(-)
+
+diff --git a/sos/policies/__init__.py b/sos/policies/__init__.py
+index d78e79cfc..562ccad25 100644
+--- a/sos/policies/__init__.py
++++ b/sos/policies/__init__.py
+@@ -1129,7 +1129,13 @@ def upload_sftp(self, user=None, password=None):
+         # need to strip the protocol prefix here
+         sftp_url = self.get_upload_url().replace('sftp://', '')
+         sftp_cmd = "sftp -oStrictHostKeyChecking=no %s@%s" % (user, sftp_url)
+-        ret = pexpect.spawn(sftp_cmd, encoding='utf-8')
++
++        if int(pexpect.__version__[0]) >= 4:
++            # newer expect requires decoding from subprocess
++            ret = pexpect.spawn(sftp_cmd, encoding='utf-8')
++        else:
++            # older pexpect does not
++            ret = pexpect.spawn(sftp_cmd)
+ 
+         sftp_expects = [
+             u'sftp>',
diff --git a/SOURCES/sos-centos-branding.patch b/SOURCES/sos-centos-branding.patch
deleted file mode 100644
index 52b7c6d..0000000
--- a/SOURCES/sos-centos-branding.patch
+++ /dev/null
@@ -1,150 +0,0 @@
-diff -uNrp sos-3.9.orig/sos/policies/redhat.py sos-3.9/sos/policies/redhat.py
---- sos-3.9.orig/sos/policies/redhat.py	2020-03-24 15:33:13.000000000 +0000
-+++ sos-3.9/sos/policies/redhat.py	2020-10-03 12:48:32.088747085 +0000
-@@ -89,7 +89,7 @@ class RedHatPolicy(LinuxPolicy):
-     def check(cls):
-         """This method checks to see if we are running on Red Hat. It must be
-         overriden by concrete subclasses to return True when running on a
--        Fedora, RHEL or other Red Hat distribution or False otherwise."""
-+        Fedora, CentOS, RHEL or other Red Hat distribution or False otherwise."""
-         return False
- 
-     def check_usrmove(self, pkgs):
-@@ -187,29 +187,29 @@ _opts_all_logs_verify = SoSOptions(all_l
- _cb_profiles = ['boot', 'storage', 'system']
- _cb_plugopts = ['boot.all-images=on', 'rpm.rpmva=on', 'rpm.rpmdb=on']
- 
--RHEL_RELEASE_STR = "Red Hat Enterprise Linux"
-+RHEL_RELEASE_STR = "CentOS Linux"
- 
- RHV = "rhv"
--RHV_DESC = "Red Hat Virtualization"
-+RHV_DESC = "Virtualization"
- 
- RHEL = "rhel"
- RHEL_DESC = RHEL_RELEASE_STR
- 
- RHOSP = "rhosp"
--RHOSP_DESC = "Red Hat OpenStack Platform"
-+RHOSP_DESC = "OpenStack Platform"
- 
- RHOCP = "ocp"
--RHOCP_DESC = "OpenShift Container Platform by Red Hat"
-+RHOCP_DESC = "OpenShift Container Platform"
- RHOSP_OPTS = SoSOptions(plugopts=[
-                              'process.lsof=off',
-                              'networking.ethtool_namespaces=False',
-                              'networking.namespaces=200'])
- 
- RH_CFME = "cfme"
--RH_CFME_DESC = "Red Hat CloudForms"
-+RH_CFME_DESC = "CloudForms"
- 
- RH_SATELLITE = "satellite"
--RH_SATELLITE_DESC = "Red Hat Satellite"
-+RH_SATELLITE_DESC = "Satellite"
- SAT_OPTS = SoSOptions(verify=True, plugopts=['apache.log=on'])
- 
- CB = "cantboot"
-@@ -257,8 +257,8 @@ RH_FTP_HOST = "ftp://dropbox.redhat.com"
- 
- class RHELPolicy(RedHatPolicy):
-     distro = RHEL_RELEASE_STR
--    vendor = "Red Hat"
--    vendor_url = "https://access.redhat.com/support/"
-+    vendor = "CentOS"
-+    vendor_url = "https://wiki.centos.org/support"
-     msg = _("""\
- This command will collect diagnostic and configuration \
- information from this %(distro)s system and installed \
-@@ -280,7 +280,7 @@ support representative.
-     def check(cls):
-         """Test to see if the running host is a RHEL installation.
- 
--            Checks for the presence of the "Red Hat Enterprise Linux"
-+            Checks for the presence of the "CentOS Linux"
-             release string at the beginning of the NAME field in the
-             `/etc/os-release` file and returns ``True`` if it is
-             found, and ``False`` otherwise.
-@@ -334,7 +334,7 @@ support representative.
- 
-     def get_upload_url_string(self):
-         if self.get_upload_url().startswith(RH_API_HOST):
--            return "Red Hat Customer Portal"
-+            return "Customer Portal"
-         return self.upload_url or RH_FTP_HOST
- 
-     def get_upload_user(self):
-@@ -389,7 +389,7 @@ class CentOsPolicy(RHELPolicy):
- 
- ATOMIC = "atomic"
- ATOMIC_RELEASE_STR = "Atomic"
--ATOMIC_DESC = "Red Hat Enterprise Linux Atomic Host"
-+ATOMIC_DESC = "Atomic Host"
- 
- atomic_presets = {
-     ATOMIC: PresetDefaults(name=ATOMIC, desc=ATOMIC_DESC, note=NOTE_TIME,
-@@ -398,7 +398,7 @@ atomic_presets = {
- 
- 
- class RedHatAtomicPolicy(RHELPolicy):
--    distro = "Red Hat Atomic Host"
-+    distro = "Atomic Host"
-     msg = _("""\
- This command will collect diagnostic and configuration \
- information from this %(distro)s system.
-@@ -435,7 +435,7 @@ support representative.
- 
- 
- class RedHatCoreOSPolicy(RHELPolicy):
--    distro = "Red Hat CoreOS"
-+    distro = "CoreOS"
-     msg = _("""\
- This command will collect diagnostic and configuration \
- information from this %(distro)s system.
-@@ -456,7 +456,7 @@ support representative.
-         host_release = os.environ[ENV_HOST_SYSROOT] + cls._redhat_release
-         try:
-             for line in open(host_release, 'r').read().splitlines():
--                coreos |= 'Red Hat CoreOS' in line
-+                coreos |= 'CoreOS' in line
-         except IOError:
-             pass
-         return coreos
-diff -uNrp sos-3.9.orig/sos/policies/redhat.py sos-3.9/sos/policies/redhat.py
---- sos-3.9.orig/sos/policies/redhat.py	2021-02-02 15:39:49.180326048 +0000
-+++ sos-3.9/sos/policies/redhat.py	2021-02-02 15:44:02.907874181 +0000
-@@ -31,9 +31,9 @@ except NameError:
- 
- 
- class RedHatPolicy(LinuxPolicy):
--    distro = "Red Hat"
--    vendor = "Red Hat"
--    vendor_url = "https://www.redhat.com/"
-+    distro = "CentOS"
-+    vendor = "CentOS"
-+    vendor_url = "https://www.centos.org/"
-     _redhat_release = '/etc/redhat-release'
-     _tmp_dir = "/var/tmp"
-     _rpmq_cmd = 'rpm -qa --queryformat "%{NAME}|%{VERSION}|%{RELEASE}\\n"'
-@@ -87,9 +87,9 @@ class RedHatPolicy(LinuxPolicy):
- 
-     @classmethod
-     def check(cls):
--        """This method checks to see if we are running on Red Hat. It must be
-+        """This method checks to see if we are running on CentOS Linux. It must be
-         overriden by concrete subclasses to return True when running on a
--        Fedora, CentOS, RHEL or other Red Hat distribution or False otherwise."""
-+        Fedora, CentOS, RHEL or other CentOS distribution or False otherwise."""
-         return False
- 
-     def check_usrmove(self, pkgs):
-@@ -309,7 +309,7 @@ support representative.
-             return
-         if self.case_id:
-             self.upload_user = input(_(
--                "Enter your Red Hat Customer Portal username (empty to use "
-+                "Enter your Customer Portal username (empty to use "
-                 "public dropbox): ")
-             )
-             if not self.upload_user:
diff --git a/SPECS/sos.spec b/SPECS/sos.spec
index 798c72e..3f58a74 100644
--- a/SPECS/sos.spec
+++ b/SPECS/sos.spec
@@ -1,8 +1,9 @@
 %{!?python_sitelib: %define python_sitelib %(%{__python} -c "from distutils.sysconfig import get_python_lib; print get_python_lib()")}
+%global __python /usr/bin/python2
 Summary: A set of tools to gather troubleshooting information from a system
 Name: sos
 Version: 3.9
-Release: 5%{?dist}.7
+Release: 5%{?dist}.10
 Group: Applications/System
 Source0: https://github.com/sosreport/sos/archive/%{version}.tar.gz
 License: GPLv2+
@@ -54,7 +55,7 @@ Patch31: sos-bz1964000-foreman-collect-all-apache-foreman.patch
 Patch32: sos-bz1964000-foreman-follow-sizelimit-to-foreman-maintain-and-installer-logs.patch
 Patch33: sos-bz1946641-sssd-plugin-when-sssd-common.patch
 Patch34: sos-bz1959781-migrationresults-new-plugin.patch
-Patch35: sos-centos-branding.patch
+Patch35: sos-bz2011337-dropbox-to-sftp.patch
 
 %description
 Sos is a set of tools that gathers information about system
@@ -123,8 +124,17 @@ rm -rf ${RPM_BUILD_ROOT}
 %config(noreplace) %{_sysconfdir}/sos.conf
 
 %changelog
-* Tue Aug 31 2021 CentOS Sources <bugs@centos.org> - 3.9-5.el7.centos.7
-- Roll in CentOS Branding
+* Fri Jan 07 2022 Barbora Vassova <bvassova@redhat.com = 3.9-5.10
+- [report] Handle exceptionally old pexpect versions
+  Resolves: bz2011337
+
+* Tue Dec 07 2021 Barbora Vassova <bvassova@redhat.com = 3.9-5.9
+- [Red Hat] SFTP api change
+  Resolves: bz2011337
+
+* Wed Oct 20 2021 Pavel Moravec <pmoravec@redhat.com = 3.9-5.8
+- [Red Hat] Update policy to use SFTP instead of legacy FTP
+  Resolves: bz2011337
 
 * Sat Aug 07 2021 Jan Jansky <jjansky@redhat.com> = 3.9-5.7
 - [migrationresults] new plugin