예제 #1
0
def create_connection(
        connection_type,
        socketpath=None,
        timeout=None,
        hostname=None,
        port=None,
        certfile=None,
        keyfile=None,
        cafile=None,
        ssh_username=None,
        ssh_password=None,
        **kwargs  # pylint: disable=unused-argument
):
    if 'socket' in connection_type:
        return UnixSocketConnection(timeout=timeout, path=socketpath)

    if 'tls' in connection_type:
        return TLSConnection(
            timeout=timeout,
            hostname=hostname,
            port=port,
            certfile=certfile,
            keyfile=keyfile,
            cafile=cafile,
        )

    return SSHConnection(
        timeout=timeout,
        hostname=hostname,
        port=port,
        username=ssh_username,
        password=ssh_password,
    )
예제 #2
0
    def check_login(self):
        if (self.hostname_input.text() == ""
                or self.username_input.text() == ""
                or self.password_input.text() == ""):
            QMessageBox.about(QMainWindow(), "Error",
                              "Please enter a all Information")
        else:
            try:
                connection = SSHConnection(hostname=self.hostname_input.text())

                with Gmp(connection=connection,
                         transform=ObjectTransform()) as gmp:
                    try:
                        response = gmp.authenticate(
                            username=self.username_input.text(),
                            password=self.password_input.text(),
                        )
                        print(response)
                        self.signal.login_event.emit(gmp, self.window)
                    except GvmResponseError:
                        QMessageBox.about(QMainWindow(), "Error",
                                          "Wrong username or password.")

            except (gaierror, NoValidConnectionsError, GvmError) as ex:
                QMessageBox.about(QMainWindow(), "Error", str(ex))
예제 #3
0
    def test_init_with_none(self):
        ssh_connection = SSHConnection(timeout=None,
                                       hostname=None,
                                       port=None,
                                       username=None,
                                       password=None)

        self.check_ssh_connection_for_default_values(ssh_connection)
예제 #4
0
 def test_connect_unknown_host(self):
     ssh_connection = SSHConnection(hostname="0.0.0.1",
                                    known_hosts_file=self.known_hosts_file)
     with self.assertRaises(
             GvmError,
             msg=("Could'nt establish a connection to fetch the remote "
                  "server key: [Errno 65] No route to host"),
     ):
         ssh_connection.connect()
예제 #5
0
    def test_connect(self):
        with patch("paramiko.SSHClient") as SSHClientMock:
            client_mock = SSHClientMock.return_value
            client_mock.exec_command.return_value = ["a", "b", "c"]
            ssh_connection = SSHConnection(
                known_hosts_file=self.known_hosts_file)

            ssh_connection.connect()
            self.assertEqual(ssh_connection._stdin, "a")
            self.assertEqual(ssh_connection._stdout, "b")
            self.assertEqual(ssh_connection._stderr, "c")
            ssh_connection.disconnect()
예제 #6
0
    def test_trigger_paramiko_ssh_except_in_get_remote_key(self):
        with patch("paramiko.transport.Transport") as TransportMock:
            client_mock = TransportMock.return_value
            client_mock.start_client.side_effect = paramiko.SSHException("foo")

            ssh_connection = SSHConnection(hostname="0.0.0.0", )

            with self.assertRaises(
                    GvmError,
                    msg="Couldn't fetch the remote server key: foo",
            ):
                ssh_connection._get_remote_host_key()
예제 #7
0
    def test_connect_denied_known_hosts_file(self):
        if os.path.exists(self.known_hosts_file):
            os.chmod(self.known_hosts_file, 0000)

        ssh_connection = SSHConnection(hostname="0.0.0.1",
                                       known_hosts_file=self.known_hosts_file)
        with self.assertRaises(
                GvmError,
                msg=("Could'nt establish a connection to fetch the remote "
                     "server key: [Errno 65] No route to host"),
        ):
            ssh_connection.connect()
예제 #8
0
    def test_trigger_oserror_in_get_remote_key_disconnect(self):
        with patch("paramiko.transport.Transport") as TransportMock:
            client_mock = TransportMock.return_value
            client_mock.close.side_effect = paramiko.SSHException("foo")

            ssh_connection = SSHConnection(hostname="0.0.0.0", )

            with self.assertRaises(
                    GvmError,
                    msg="Couldn't close the connection to the"
                    "remote server key: foo",
            ):
                ssh_connection._get_remote_host_key()
예제 #9
0
    def test_trigger_oserror_in_get_remote_key_connect(self):
        with patch("socket.socket") as SocketMock:
            client_mock = SocketMock.return_value
            client_mock.connect.side_effect = OSError("foo")

            ssh_connection = SSHConnection(hostname="0.0.0.0", )

            with self.assertRaises(
                    GvmError,
                    msg="Couldn't establish a connection to fetch the"
                    "remote server key: foo",
            ):
                ssh_connection._get_remote_host_key()
예제 #10
0
    def test_send(self):
        with patch("paramiko.SSHClient") as SSHClientMock:
            client_mock = SSHClientMock.return_value
            stdin = Mock()
            stdin.channel.send.return_value = 4
            client_mock.exec_command.return_value = [stdin, None, None]
            ssh_connection = SSHConnection(
                known_hosts_file=self.known_hosts_file)

            ssh_connection.connect()
            req = ssh_connection.send("blah")
            self.assertEqual(req, 4)
            ssh_connection.disconnect()
예제 #11
0
    def test_read(self):
        with patch("paramiko.SSHClient") as SSHClientMock:
            client_mock = SSHClientMock.return_value
            stdout = Mock()
            stdout.channel.recv.return_value = b"foo bar baz"
            client_mock.exec_command.return_value = [None, stdout, None]
            ssh_connection = SSHConnection(
                known_hosts_file=self.known_hosts_file)

            ssh_connection.connect()
            recved = ssh_connection._read()
            self.assertEqual(recved, b"foo bar baz")
            ssh_connection.disconnect()
예제 #12
0
    def test_send_error(self):
        with patch("paramiko.SSHClient") as SSHClientMock:
            client_mock = SSHClientMock.return_value
            stdin = Mock()
            stdin.channel.send.return_value = None
            client_mock.exec_command.return_value = [stdin, None, None]
            ssh_connection = SSHConnection(
                known_hosts_file=self.known_hosts_file)

            ssh_connection.connect()
            with self.assertRaises(GvmError,
                                   msg="Remote closed the connection"):
                ssh_connection.send("blah")
            ssh_connection.disconnect()
예제 #13
0
    def test_disconnect_os_error(self):
        with patch("paramiko.SSHClient") as SSHClientMock:
            client_mock = SSHClientMock.return_value
            client_mock.exec_command.return_value = ["a", "b", "c"]
            client_mock.close.side_effect = OSError

            ssh_connection = SSHConnection(
                known_hosts_file=self.known_hosts_file)
            ssh_connection.connect()

            with self.assertRaises(OSError):
                with self.assertLogs("gvm.connections", level="INFO") as cm:
                    ssh_connection.disconnect()
                    self.assertEqual(cm.output, ["Connection closing error: "])
예제 #14
0
    def test_send_and_slice(self):
        with patch("paramiko.SSHClient") as SSHClientMock:
            client_mock = SSHClientMock.return_value
            stdin = Mock()
            stdin.channel.send.side_effect = [2, 2]
            client_mock.exec_command.return_value = [stdin, None, None]
            ssh_connection = SSHConnection(
                known_hosts_file=self.known_hosts_file)

            ssh_connection.connect()
            req = ssh_connection.send("blah")
            self.assertEqual(req, 4)

            stdin.channel.send.assert_called()
            with self.assertRaises(AssertionError):
                stdin.channel.send.assert_called_once()
            ssh_connection.disconnect()
예제 #15
0
    def test_connect_wrong_input(self, stdout_mock, input_mock):

        key_io = StringIO("""-----BEGIN OPENSSH PRIVATE KEY-----
b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAAAMwAAAAtzc2gtZW
QyNTUxOQAAACB69SvZKJh/9VgSL0G27b5xVYa8nethH3IERbi0YqJDXwAAAKhjwAdrY8AH
awAAAAtzc2gtZWQyNTUxOQAAACB69SvZKJh/9VgSL0G27b5xVYa8nethH3IERbi0YqJDXw
AAAEA9tGQi2IrprbOSbDCF+RmAHd6meNSXBUQ2ekKXm4/8xnr1K9komH/1WBIvQbbtvnFV
hryd62EfcgRFuLRiokNfAAAAI2FsZXhfZ2F5bm9yQEFsZXhzLU1hY0Jvb2stQWlyLmxvY2
FsAQI=
            -----END OPENSSH PRIVATE KEY-----""")
        key = paramiko.Ed25519Key.from_private_key(key_io)
        hostname = "0.0.0.0"
        key_type = key.get_name().replace("ssh-", "").upper()
        inputs = ["asd", "yes", "yoo", "no"]
        input_mock.side_effect = inputs
        ssh_connection = SSHConnection(hostname=hostname,
                                       known_hosts_file=self.known_hosts_file)
        ssh_connection._socket = paramiko.SSHClient()

        with self.assertLogs("gvm.connections", level="INFO") as cm:
            hostkeys = paramiko.HostKeys(filename=self.known_hosts_file)
            ssh_connection._ssh_authentication_input_loop(hostkeys=hostkeys,
                                                          key=key)
            ret = stdout_mock.getvalue()

            self.assertEqual(
                cm.output,
                [
                    "INFO:gvm.connections:Warning: "
                    f"Host '{hostname}' ({key_type}) not added to "
                    "the list of known hosts."
                ],
            )

            self.assertEqual(
                ret,
                f"The authenticity of host '{hostname}' can't be established.\n"
                f"{key_type} key fingerprint is "
                "J6VESFdD3xSChn8y9PzWzeF+1tl892mOy2TqkMLO4ow.\n"
                "Are you sure you want to continue connecting (yes/no)? "
                "Please type 'yes' or 'no': "
                "Do you want to add 0.0.0.0 to known_hosts (yes/no)? "
                "Please type 'yes' or 'no': ",
            )
예제 #16
0
    def test_connect_adding_and_dont_save_hostkey(self, input_mock):

        key_io = StringIO("""-----BEGIN OPENSSH PRIVATE KEY-----
b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAAAMwAAAAtzc2gtZW
QyNTUxOQAAACB69SvZKJh/9VgSL0G27b5xVYa8nethH3IERbi0YqJDXwAAAKhjwAdrY8AH
awAAAAtzc2gtZWQyNTUxOQAAACB69SvZKJh/9VgSL0G27b5xVYa8nethH3IERbi0YqJDXw
AAAEA9tGQi2IrprbOSbDCF+RmAHd6meNSXBUQ2ekKXm4/8xnr1K9komH/1WBIvQbbtvnFV
hryd62EfcgRFuLRiokNfAAAAI2FsZXhfZ2F5bm9yQEFsZXhzLU1hY0Jvb2stQWlyLmxvY2
FsAQI=
            -----END OPENSSH PRIVATE KEY-----""")
        key = paramiko.Ed25519Key.from_private_key(key_io)
        key_type = key.get_name().replace("ssh-", "").upper()
        hostname = "0.0.0.0"
        input_mock.side_effect = ["yes", "no"]
        ssh_connection = SSHConnection(hostname=hostname,
                                       known_hosts_file=self.known_hosts_file)
        ssh_connection._socket = paramiko.SSHClient()
        keys = self.known_hosts_file.read_text(encoding="utf-8")
        self.assertEqual(
            keys,
            "127.0.0.1 ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIBOZWi"
            "fs+DoMqIa5Nr0wiVrzQNpMbUwaLzuSTN6rNrYA\n",
        )

        with self.assertLogs("gvm.connections", level="INFO") as cm:
            hostkeys = paramiko.HostKeys(filename=self.known_hosts_file)
            ssh_connection._ssh_authentication_input_loop(hostkeys=hostkeys,
                                                          key=key)
            keys = self.known_hosts_file.read_text(encoding="utf-8")

            self.assertEqual(
                cm.output,
                [
                    "INFO:gvm.connections:Warning: "
                    f"Host '{hostname}' ({key_type}) not added to "
                    "the list of known hosts."
                ],
            )

            self.assertEqual(
                keys,
                "127.0.0.1 ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIBOZWi"
                "fs+DoMqIa5Nr0wiVrzQNpMbUwaLzuSTN6rNrYA\n",
            )
예제 #17
0
    def test_user_denies_auth(self, input_mock):

        key_io = StringIO("""-----BEGIN OPENSSH PRIVATE KEY-----
b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAAAMwAAAAtzc2gtZW
QyNTUxOQAAACB69SvZKJh/9VgSL0G27b5xVYa8nethH3IERbi0YqJDXwAAAKhjwAdrY8AH
awAAAAtzc2gtZWQyNTUxOQAAACB69SvZKJh/9VgSL0G27b5xVYa8nethH3IERbi0YqJDXw
AAAEA9tGQi2IrprbOSbDCF+RmAHd6meNSXBUQ2ekKXm4/8xnr1K9komH/1WBIvQbbtvnFV
hryd62EfcgRFuLRiokNfAAAAI2FsZXhfZ2F5bm9yQEFsZXhzLU1hY0Jvb2stQWlyLmxvY2
FsAQI=
            -----END OPENSSH PRIVATE KEY-----""")
        key = paramiko.Ed25519Key.from_private_key(key_io)
        hostname = "0.0.0.0"
        input_mock.return_value = "no"
        ssh_connection = SSHConnection(hostname=hostname,
                                       known_hosts_file=self.known_hosts_file)
        ssh_connection._socket = paramiko.SSHClient()

        with self.assertRaises(
                SystemExit,
                msg="User denied key. Host key verification failed."):
            hostkeys = paramiko.HostKeys(filename=self.known_hosts_file)
            ssh_connection._ssh_authentication_input_loop(hostkeys=hostkeys,
                                                          key=key)
예제 #18
0
    def test_disconnect(self):
        with patch("paramiko.SSHClient") as SSHClientMock:
            client_mock = SSHClientMock.return_value
            client_mock.exec_command.return_value = ["a", "b", "c"]
            ssh_connection = SSHConnection(
                known_hosts_file=self.known_hosts_file)

            ssh_connection.connect()
            self.assertEqual(ssh_connection._stdin, "a")
            self.assertEqual(ssh_connection._stdout, "b")
            self.assertEqual(ssh_connection._stderr, "c")

            ssh_connection.disconnect()
            # make sure the attributes have been deleted
            with self.assertRaises(AttributeError):
                type(ssh_connection._stdin)
            with self.assertRaises(AttributeError):
                type(ssh_connection._stdout)
            with self.assertRaises(AttributeError):
                type(ssh_connection._stderr)
            with self.assertRaises(AttributeError):
                type(ssh_connection._socket)

            with self.assertRaises(AttributeError):
                with self.assertLogs("gvm.connections", level="INFO") as cm:
                    # disconnect twice should not work ...
                    ssh_connection.disconnect()
                    self.assertEqual(
                        cm.output,
                        [
                            "Connection might already be"
                            " closed. No socket found.",
                        ],
                    )

            ssh_connection._socket = None
            ssh_connection.disconnect()
예제 #19
0
    def test_connect_error(self):
        print(self.known_hosts_file.read_text(encoding="utf-8"))

        ssh_connection = SSHConnection(known_hosts_file=self.known_hosts_file)
        with self.assertRaises(GvmError, msg="SSH Connection failed"):
            ssh_connection.connect()
예제 #20
0
    def test_init_no_args(self):
        ssh_connection = SSHConnection()

        self.check_ssh_connection_for_default_values(ssh_connection)
예제 #21
0
def exportReports(filterID, filterString, optPagination, optDetails,
                  optRewrite, taskName, genPDF):
    print('Loading previously completed reports data')
    ranReports = readRanReportsFile(taskName)

    #connect to our host as defined in the config file
    print("Trying to connect to: '", config['DEFAULT']['host'], "' on port: '",
          config['DEFAULT']['port'], "'")
    connection = SSHConnection(hostname=config['DEFAULT']['host'],
                               timeout=18000)
    if config['DEFAULT']['port']:
        connection = SSHConnection(hostname=config['DEFAULT']['host'],
                                   port=config['DEFAULT']['port'],
                                   timeout=18000)
    print('Starting report processing')

    with Gmp(connection) as gmp:
        # Login
        print("Attempting to authenticate")
        gmp.authenticate(config['DEFAULT']['username'],
                         config['DEFAULT']['password'])
        print('Connected to:', config['DEFAULT']['host'])

        #Get the CSV report format ID. We use CSV as the base format to transform into json
        reportFormatID = "c1645568-627a-11e3-a660-406186ea4fc5"  #holds the format id for CSV
        report_format = gmp.get_report_formats()
        report_root = ET.fromstring(report_format)
        for report in report_root:
            report.tag == "report_format"
            for report_format in report:
                if report_format.text == 'CSV result list.':
                    reportFormatID = report.attrib.get('id')

        getReports = []  #array of reportIDs
        print('Getting reports')
        allreports = gmp.get_reports(
            filter=taskName, details=0
        )  #we only need the reportID so minimize the data returned
        print('Retreived reports')
        allreports_root = ET.fromstring(allreports)
        print("Fetched the following scans from %s" %
              (config['DEFAULT']['host']))
        for report in allreports_root:
            if report.tag == 'report':
                for onereport in report:
                    if onereport.tag == 'report':
                        pretty_print(onereport)
                        print(report.attrib)
                        getReports.append(report.attrib.get('id'))

        #Step through the reportID list and grab them as csv files
        for reportID in getReports:
            print("Processing Report ID: {0}".format(reportID))

            # we have a reportID. Check to see if it matches any existing reports already written to disk
            # if it does then we can skip this one. Note: we make sure filterID is null because we
            # only need to do the hashing once.
            if filterString and not filterID:
                # we need a consistent identify for this string so hashes to the rescue
                # we are going to reuse the filterID variable to hold it
                sha_1 = hashlib.sha1()  #instantiate hash
                sha_1.update(
                    filterString.encode('utf-8')
                )  #hash the string being sure to use proper encoding
                filterID = sha_1.hexdigest()  #return the hash as a hex string

            # we use the filterID and the reportID to create a key for the ranReports dict. If it exists then skip
            # that report unless we are over writing (or regenerating) reports.
            ranReportsKey = filterID + reportID
            if ranReportsKey in ranReports and not optRewrite:
                print("This report was processed on %s" %
                      (ranReports[ranReportsKey]))
                continue

            if filterString:  #if they are using a custom filter string entered on the CLI
                reportscv = gmp.get_report(reportID,
                                           filter=filterString,
                                           report_format_id=reportFormatID,
                                           ignore_pagination=optPagination,
                                           details=optDetails)
            else:
                reportscv = gmp.get_report(reportID,
                                           filter_id=filterID,
                                           report_format_id=reportFormatID,
                                           ignore_pagination=optPagination,
                                           details=optDetails)

            obj = untangle.parse(reportscv)
            resultID = obj.get_reports_response.report['id']
            base64CVSData = obj.get_reports_response.report.cdata
            data = str(base64.b64decode(base64CVSData), "utf-8")

            #Write the result to file
            writeResultToFile(resultID, data, filterID, filterString, taskName,
                              genPDF, gmp, optPagination, optDetails)