Skip to content

Commit 908bb68

Browse files
authored
Improve Check Point Gaia (#3748)
* Working on check point gaia expert mode * Working 'enable' mode on check point gaia * Check point gaia enable handling * Improve Gaia 'enable()' mode behavior * Minor cleanup * Exit enable mode for Gaia * Add test for exit enable mode * Linter * Update platforms
1 parent a8fb494 commit 908bb68

File tree

4 files changed

+96
-21
lines changed

4 files changed

+96
-21
lines changed

PLATFORMS.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
- Calix B6
2626
- Casa Systems CMTS
2727
- Centec Networks
28+
- Check Point GAiA
2829
- Cisco AireOS (Wireless LAN Controllers)
2930
- Cisco ASA
3031
- Cisco S200
@@ -92,7 +93,6 @@
9293
- Cisco APIC (Linux)
9394
- Cisco Telepresence
9495
- Cisco Viptela
95-
- Check Point GAiA
9696
- Corelight Linux
9797
- Coriant
9898
- Cumulus VX Linux

netmiko/base_connection.py

Lines changed: 26 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2011,6 +2011,29 @@ def check_enable_mode(self, check_string: str = "") -> bool:
20112011
output = self.read_until_prompt(read_entire_line=True)
20122012
return check_string in output
20132013

2014+
def enable_secret_handler(
2015+
self,
2016+
pattern: str,
2017+
output: str,
2018+
re_flags: int = re.IGNORECASE,
2019+
) -> str:
2020+
"""
2021+
Some platforms require special handling when entering 'enable' mode.
2022+
2023+
Send the "secret" in response to password pattern
2024+
2025+
:param pattern: pattern to search for indicating device is waiting for password
2026+
2027+
:param output: Accumulated output from 'enable()' method.
2028+
2029+
:param re_flags: Regular expression flags used in conjunction with pattern
2030+
2031+
"""
2032+
if re.search(pattern, output, flags=re_flags):
2033+
self.write_channel(self.normalize_cmd(self.secret))
2034+
new_output = self.read_until_prompt()
2035+
return new_output
2036+
20142037
def enable(
20152038
self,
20162039
cmd: str = "",
@@ -2054,10 +2077,9 @@ def enable(
20542077
pattern=pattern, re_flags=re_flags, read_entire_line=True
20552078
)
20562079

2057-
# Send the "secret" in response to password pattern
2058-
if re.search(pattern, output, flags=re_flags):
2059-
self.write_channel(self.normalize_cmd(self.secret))
2060-
output += self.read_until_prompt()
2080+
output += self.enable_secret_handler(
2081+
pattern=pattern, output=output, re_flags=re_flags
2082+
)
20612083

20622084
# Search for terminating pattern if defined
20632085
if enable_pattern and not re.search(enable_pattern, output):

netmiko/checkpoint/checkpoint_gaia_ssh.py

Lines changed: 61 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import time
22
import re
3+
from typing import Optional, Any
34

45
from netmiko.no_config import NoConfig
56
from netmiko.base_connection import BaseConnection
@@ -13,6 +14,13 @@ class CheckPointGaiaSSH(NoConfig, BaseConnection):
1314

1415
prompt_pattern = r"[>#]"
1516

17+
def __init__(self, *args: Any, **kwargs: Any) -> None:
18+
# Kept running into issues with command_echo and duplicate echoes of commands.
19+
self.fast_cli = False
20+
fast_cli = kwargs.get("fast_cli") or False
21+
kwargs["fast_cli"] = fast_cli
22+
return super().__init__(*args, **kwargs)
23+
1624
def session_preparation(self) -> None:
1725
"""
1826
Prepare the session after the connection has been established.
@@ -27,26 +35,63 @@ def session_preparation(self) -> None:
2735
time.sleep(0.3 * self.global_delay_factor)
2836
self.clear_buffer()
2937

30-
def command_echo_read(self, cmd: str, read_timeout: float) -> str:
31-
"""Check Point clish double echoes the command (at least sometimes)"""
38+
def check_enable_mode(self, check_string: str = "#") -> bool:
39+
"""Check if in enable mode. Return boolean."""
40+
return super().check_enable_mode(check_string=check_string)
3241

33-
re_cmd = re.escape(cmd)
34-
pattern = rf"{self.prompt_pattern}\s{re_cmd}"
42+
def enable_secret_handler(
43+
self,
44+
pattern: str,
45+
output: str,
46+
re_flags: int = re.IGNORECASE,
47+
) -> str:
48+
"""
49+
Check Point Gaia requires very particular timing for this 'expert'
50+
password handling to work.
3551
36-
# Make sure you read until you detect the command echo (avoid getting out of sync)
37-
new_data = self.read_until_pattern(pattern=pattern, read_timeout=read_timeout)
52+
Send the "secret" in response to password pattern
53+
"""
54+
if re.search(pattern, output, flags=re_flags):
55+
self.write_channel(self.secret)
56+
time.sleep(0.3 * self.global_delay_factor)
57+
self.write_channel(self.RETURN)
58+
time.sleep(0.3 * self.global_delay_factor)
59+
new_output = self.read_until_pattern(pattern=self.prompt_pattern)
60+
return new_output
3861

39-
# There can be echoed prompts that haven't been cleared before the cmd echo
40-
# this can later mess up the trailing prompt pattern detection. Clear this out.
41-
lines = new_data.split(cmd)
42-
if len(lines) in [2, 3]:
43-
# lines[-1] should realistically just be the null string
44-
new_data = f"{cmd}{lines[-1]}"
45-
else:
46-
# cmd exists in the output multiple times? Just retain the original output
47-
pass
62+
def enable(
63+
self,
64+
cmd: str = "expert",
65+
pattern: str = r"expert password",
66+
enable_pattern: Optional[str] = r"\#",
67+
check_state: bool = True,
68+
re_flags: int = re.IGNORECASE,
69+
) -> str:
70+
"""
71+
Enter expert mode.
72+
73+
Check Point Gaia is very finicky on the timing of sending this 'expert' password.
74+
"""
75+
output = super().enable(
76+
cmd=cmd,
77+
pattern=pattern,
78+
enable_pattern=enable_pattern,
79+
check_state=check_state,
80+
re_flags=re_flags,
81+
)
82+
self.set_base_prompt()
83+
return output
4884

49-
return new_data
85+
def exit_enable_mode(self, exit_command: str = "exit") -> str:
86+
"""Exit expert mode."""
87+
output = ""
88+
if self.check_enable_mode():
89+
self.write_channel(self.normalize_cmd(exit_command))
90+
output += self.read_until_pattern(pattern=r">")
91+
self.set_base_prompt()
92+
if self.check_enable_mode():
93+
raise ValueError("Failed to exit enable mode.")
94+
return output
5095

5196
def save_config(
5297
self, cmd: str = "", confirm: bool = False, confirm_response: str = ""

tests/test_netmiko_show.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -374,6 +374,14 @@ def test_enable_mode(net_connect, commands, expected_responses):
374374
except AttributeError:
375375
assert True
376376

377+
# Now verify you can exit enable mode
378+
try:
379+
net_connect.exit_enable_mode()
380+
prompt = net_connect.find_prompt()
381+
assert prompt == expected_responses["router_prompt"]
382+
except AttributeError:
383+
assert True
384+
377385

378386
def test_disconnect(net_connect, commands, expected_responses):
379387
"""Terminate the SSH session."""

0 commit comments

Comments
 (0)