We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Raise exception if asa_login() fails to login successfully


--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `netmiko/cisco/cisco_asa_ssh.py`
Content:
```
1 """Subclass specific to Cisco ASA."""
2 import re
3 import time
4 from netmiko.cisco_base_connection import CiscoSSHConnection, CiscoFileTransfer
5 
6 
7 class CiscoAsaSSH(CiscoSSHConnection):
8     """Subclass specific to Cisco ASA."""
9 
10     def session_preparation(self):
11         """Prepare the session after the connection has been established."""
12         self._test_channel_read()
13         self.set_base_prompt()
14         if self.secret:
15             self.enable()
16         else:
17             self.asa_login()
18         self.disable_paging(command="terminal pager 0")
19         if self.allow_auto_change:
20             try:
21                 self.send_config_set("terminal width 511")
22             except ValueError:
23                 # Don't fail for the terminal width
24                 pass
25 
26         # Clear the read buffer
27         time.sleep(0.3 * self.global_delay_factor)
28         self.clear_buffer()
29 
30     def send_command_timing(self, *args, **kwargs):
31         """
32         If the ASA is in multi-context mode, then the base_prompt needs to be
33         updated after each context change.
34         """
35         output = super().send_command_timing(*args, **kwargs)
36         if len(args) >= 1:
37             command_string = args[0]
38         else:
39             command_string = kwargs["command_string"]
40         if "changeto" in command_string:
41             self.set_base_prompt()
42         return output
43 
44     def send_command(self, *args, **kwargs):
45         """
46         If the ASA is in multi-context mode, then the base_prompt needs to be
47         updated after each context change.
48         """
49         if len(args) >= 1:
50             command_string = args[0]
51         else:
52             command_string = kwargs["command_string"]
53 
54         # If changeto in command, look for '#' to determine command is done
55         if "changeto" in command_string:
56             if len(args) <= 1:
57                 expect_string = kwargs.get("expect_string", "#")
58                 kwargs["expect_string"] = expect_string
59         output = super().send_command(*args, **kwargs)
60 
61         if "changeto" in command_string:
62             self.set_base_prompt()
63 
64         return output
65 
66     def send_command_expect(self, *args, **kwargs):
67         """Backwards compaitibility."""
68         return self.send_command(*args, **kwargs)
69 
70     def set_base_prompt(self, *args, **kwargs):
71         """
72         Cisco ASA in multi-context mode needs to have the base prompt updated
73         (if you switch contexts i.e. 'changeto')
74 
75         This switch of ASA contexts can occur in configuration mode. If this
76         happens the trailing '(config*' needs stripped off.
77         """
78         cur_base_prompt = super().set_base_prompt(*args, **kwargs)
79         match = re.search(r"(.*)\(conf.*", cur_base_prompt)
80         if match:
81             # strip off (conf.* from base_prompt
82             self.base_prompt = match.group(1)
83             return self.base_prompt
84 
85     def asa_login(self):
86         """
87         Handle ASA reaching privilege level 15 using login
88 
89         twb-dc-fw1> login
90         Username: admin
91         Password: ************
92         """
93         delay_factor = self.select_delay_factor(0)
94 
95         i = 1
96         max_attempts = 50
97         self.write_channel("login" + self.RETURN)
98         while i <= max_attempts:
99             time.sleep(0.5 * delay_factor)
100             output = self.read_channel()
101             if "sername" in output:
102                 self.write_channel(self.username + self.RETURN)
103             elif "ssword" in output:
104                 self.write_channel(self.password + self.RETURN)
105             elif "#" in output:
106                 break
107             else:
108                 self.write_channel("login" + self.RETURN)
109             i += 1
110 
111     def save_config(self, cmd="write mem", confirm=False, confirm_response=""):
112         """Saves Config"""
113         return super().save_config(
114             cmd=cmd, confirm=confirm, confirm_response=confirm_response
115         )
116 
117 
118 class CiscoAsaFileTransfer(CiscoFileTransfer):
119     """Cisco ASA SCP File Transfer driver."""
120 
121     pass
122
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/netmiko/cisco/cisco_asa_ssh.py b/netmiko/cisco/cisco_asa_ssh.py
--- a/netmiko/cisco/cisco_asa_ssh.py
+++ b/netmiko/cisco/cisco_asa_ssh.py
@@ -2,6 +2,7 @@
 import re
 import time
 from netmiko.cisco_base_connection import CiscoSSHConnection, CiscoFileTransfer
+from netmiko.ssh_exception import NetmikoAuthenticationException
 
 
 class CiscoAsaSSH(CiscoSSHConnection):
@@ -88,12 +89,14 @@
 
         twb-dc-fw1> login
         Username: admin
-        Password: ************
+
+        Raises NetmikoAuthenticationException, if we do not reach privilege
+        level 15 after 3 attempts.
         """
         delay_factor = self.select_delay_factor(0)
 
         i = 1
-        max_attempts = 50
+        max_attempts = 3
         self.write_channel("login" + self.RETURN)
         while i <= max_attempts:
             time.sleep(0.5 * delay_factor)
@@ -103,11 +106,14 @@
             elif "ssword" in output:
                 self.write_channel(self.password + self.RETURN)
             elif "#" in output:
-                break
+                return True
             else:
                 self.write_channel("login" + self.RETURN)
             i += 1
 
+        msg = "Unable to get to enable mode!"
+        raise NetmikoAuthenticationException(msg)
+
     def save_config(self, cmd="write mem", confirm=False, confirm_response=""):
         """Saves Config"""
         return super().save_config(

{"golden_diff": "diff --git a/netmiko/cisco/cisco_asa_ssh.py b/netmiko/cisco/cisco_asa_ssh.py\n--- a/netmiko/cisco/cisco_asa_ssh.py\n+++ b/netmiko/cisco/cisco_asa_ssh.py\n@@ -2,6 +2,7 @@\n import re\n import time\n from netmiko.cisco_base_connection import CiscoSSHConnection, CiscoFileTransfer\n+from netmiko.ssh_exception import NetmikoAuthenticationException\n \n \n class CiscoAsaSSH(CiscoSSHConnection):\n@@ -88,12 +89,14 @@\n \n         twb-dc-fw1> login\n         Username: admin\n-        Password: ************\n+\n+        Raises NetmikoAuthenticationException, if we do not reach privilege\n+        level 15 after 3 attempts.\n         \"\"\"\n         delay_factor = self.select_delay_factor(0)\n \n         i = 1\n-        max_attempts = 50\n+        max_attempts = 3\n         self.write_channel(\"login\" + self.RETURN)\n         while i <= max_attempts:\n             time.sleep(0.5 * delay_factor)\n@@ -103,11 +106,14 @@\n             elif \"ssword\" in output:\n                 self.write_channel(self.password + self.RETURN)\n             elif \"#\" in output:\n-                break\n+                return True\n             else:\n                 self.write_channel(\"login\" + self.RETURN)\n             i += 1\n \n+        msg = \"Unable to get to enable mode!\"\n+        raise NetmikoAuthenticationException(msg)\n+\n     def save_config(self, cmd=\"write mem\", confirm=False, confirm_response=\"\"):\n         \"\"\"Saves Config\"\"\"\n         return super().save_config(\n", "issue": "Raise exception if asa_login() fails to login successfully\n\n", "before_files": [{"content": "\"\"\"Subclass specific to Cisco ASA.\"\"\"\nimport re\nimport time\nfrom netmiko.cisco_base_connection import CiscoSSHConnection, CiscoFileTransfer\n\n\nclass CiscoAsaSSH(CiscoSSHConnection):\n    \"\"\"Subclass specific to Cisco ASA.\"\"\"\n\n    def session_preparation(self):\n        \"\"\"Prepare the session after the connection has been established.\"\"\"\n        self._test_channel_read()\n        self.set_base_prompt()\n        if self.secret:\n            self.enable()\n        else:\n            self.asa_login()\n        self.disable_paging(command=\"terminal pager 0\")\n        if self.allow_auto_change:\n            try:\n                self.send_config_set(\"terminal width 511\")\n            except ValueError:\n                # Don't fail for the terminal width\n                pass\n\n        # Clear the read buffer\n        time.sleep(0.3 * self.global_delay_factor)\n        self.clear_buffer()\n\n    def send_command_timing(self, *args, **kwargs):\n        \"\"\"\n        If the ASA is in multi-context mode, then the base_prompt needs to be\n        updated after each context change.\n        \"\"\"\n        output = super().send_command_timing(*args, **kwargs)\n        if len(args) >= 1:\n            command_string = args[0]\n        else:\n            command_string = kwargs[\"command_string\"]\n        if \"changeto\" in command_string:\n            self.set_base_prompt()\n        return output\n\n    def send_command(self, *args, **kwargs):\n        \"\"\"\n        If the ASA is in multi-context mode, then the base_prompt needs to be\n        updated after each context change.\n        \"\"\"\n        if len(args) >= 1:\n            command_string = args[0]\n        else:\n            command_string = kwargs[\"command_string\"]\n\n        # If changeto in command, look for '#' to determine command is done\n        if \"changeto\" in command_string:\n            if len(args) <= 1:\n                expect_string = kwargs.get(\"expect_string\", \"#\")\n                kwargs[\"expect_string\"] = expect_string\n        output = super().send_command(*args, **kwargs)\n\n        if \"changeto\" in command_string:\n            self.set_base_prompt()\n\n        return output\n\n    def send_command_expect(self, *args, **kwargs):\n        \"\"\"Backwards compaitibility.\"\"\"\n        return self.send_command(*args, **kwargs)\n\n    def set_base_prompt(self, *args, **kwargs):\n        \"\"\"\n        Cisco ASA in multi-context mode needs to have the base prompt updated\n        (if you switch contexts i.e. 'changeto')\n\n        This switch of ASA contexts can occur in configuration mode. If this\n        happens the trailing '(config*' needs stripped off.\n        \"\"\"\n        cur_base_prompt = super().set_base_prompt(*args, **kwargs)\n        match = re.search(r\"(.*)\\(conf.*\", cur_base_prompt)\n        if match:\n            # strip off (conf.* from base_prompt\n            self.base_prompt = match.group(1)\n            return self.base_prompt\n\n    def asa_login(self):\n        \"\"\"\n        Handle ASA reaching privilege level 15 using login\n\n        twb-dc-fw1> login\n        Username: admin\n        Password: ************\n        \"\"\"\n        delay_factor = self.select_delay_factor(0)\n\n        i = 1\n        max_attempts = 50\n        self.write_channel(\"login\" + self.RETURN)\n        while i <= max_attempts:\n            time.sleep(0.5 * delay_factor)\n            output = self.read_channel()\n            if \"sername\" in output:\n                self.write_channel(self.username + self.RETURN)\n            elif \"ssword\" in output:\n                self.write_channel(self.password + self.RETURN)\n            elif \"#\" in output:\n                break\n            else:\n                self.write_channel(\"login\" + self.RETURN)\n            i += 1\n\n    def save_config(self, cmd=\"write mem\", confirm=False, confirm_response=\"\"):\n        \"\"\"Saves Config\"\"\"\n        return super().save_config(\n            cmd=cmd, confirm=confirm, confirm_response=confirm_response\n        )\n\n\nclass CiscoAsaFileTransfer(CiscoFileTransfer):\n    \"\"\"Cisco ASA SCP File Transfer driver.\"\"\"\n\n    pass\n", "path": "netmiko/cisco/cisco_asa_ssh.py"}], "after_files": [{"content": "\"\"\"Subclass specific to Cisco ASA.\"\"\"\nimport re\nimport time\nfrom netmiko.cisco_base_connection import CiscoSSHConnection, CiscoFileTransfer\nfrom netmiko.ssh_exception import NetmikoAuthenticationException\n\n\nclass CiscoAsaSSH(CiscoSSHConnection):\n    \"\"\"Subclass specific to Cisco ASA.\"\"\"\n\n    def session_preparation(self):\n        \"\"\"Prepare the session after the connection has been established.\"\"\"\n        self._test_channel_read()\n        self.set_base_prompt()\n        if self.secret:\n            self.enable()\n        else:\n            self.asa_login()\n        self.disable_paging(command=\"terminal pager 0\")\n        if self.allow_auto_change:\n            try:\n                self.send_config_set(\"terminal width 511\")\n            except ValueError:\n                # Don't fail for the terminal width\n                pass\n\n        # Clear the read buffer\n        time.sleep(0.3 * self.global_delay_factor)\n        self.clear_buffer()\n\n    def send_command_timing(self, *args, **kwargs):\n        \"\"\"\n        If the ASA is in multi-context mode, then the base_prompt needs to be\n        updated after each context change.\n        \"\"\"\n        output = super().send_command_timing(*args, **kwargs)\n        if len(args) >= 1:\n            command_string = args[0]\n        else:\n            command_string = kwargs[\"command_string\"]\n        if \"changeto\" in command_string:\n            self.set_base_prompt()\n        return output\n\n    def send_command(self, *args, **kwargs):\n        \"\"\"\n        If the ASA is in multi-context mode, then the base_prompt needs to be\n        updated after each context change.\n        \"\"\"\n        if len(args) >= 1:\n            command_string = args[0]\n        else:\n            command_string = kwargs[\"command_string\"]\n\n        # If changeto in command, look for '#' to determine command is done\n        if \"changeto\" in command_string:\n            if len(args) <= 1:\n                expect_string = kwargs.get(\"expect_string\", \"#\")\n                kwargs[\"expect_string\"] = expect_string\n        output = super().send_command(*args, **kwargs)\n\n        if \"changeto\" in command_string:\n            self.set_base_prompt()\n\n        return output\n\n    def send_command_expect(self, *args, **kwargs):\n        \"\"\"Backwards compaitibility.\"\"\"\n        return self.send_command(*args, **kwargs)\n\n    def set_base_prompt(self, *args, **kwargs):\n        \"\"\"\n        Cisco ASA in multi-context mode needs to have the base prompt updated\n        (if you switch contexts i.e. 'changeto')\n\n        This switch of ASA contexts can occur in configuration mode. If this\n        happens the trailing '(config*' needs stripped off.\n        \"\"\"\n        cur_base_prompt = super().set_base_prompt(*args, **kwargs)\n        match = re.search(r\"(.*)\\(conf.*\", cur_base_prompt)\n        if match:\n            # strip off (conf.* from base_prompt\n            self.base_prompt = match.group(1)\n            return self.base_prompt\n\n    def asa_login(self):\n        \"\"\"\n        Handle ASA reaching privilege level 15 using login\n\n        twb-dc-fw1> login\n        Username: admin\n\n        Raises NetmikoAuthenticationException, if we do not reach privilege\n        level 15 after 3 attempts.\n        \"\"\"\n        delay_factor = self.select_delay_factor(0)\n\n        i = 1\n        max_attempts = 3\n        self.write_channel(\"login\" + self.RETURN)\n        while i <= max_attempts:\n            time.sleep(0.5 * delay_factor)\n            output = self.read_channel()\n            if \"sername\" in output:\n                self.write_channel(self.username + self.RETURN)\n            elif \"ssword\" in output:\n                self.write_channel(self.password + self.RETURN)\n            elif \"#\" in output:\n                return True\n            else:\n                self.write_channel(\"login\" + self.RETURN)\n            i += 1\n\n        msg = \"Unable to get to enable mode!\"\n        raise NetmikoAuthenticationException(msg)\n\n    def save_config(self, cmd=\"write mem\", confirm=False, confirm_response=\"\"):\n        \"\"\"Saves Config\"\"\"\n        return super().save_config(\n            cmd=cmd, confirm=confirm, confirm_response=confirm_response\n        )\n\n\nclass CiscoAsaFileTransfer(CiscoFileTransfer):\n    \"\"\"Cisco ASA SCP File Transfer driver.\"\"\"\n\n    pass\n", "path": "netmiko/cisco/cisco_asa_ssh.py"}]}