Skip to content

Commit

Permalink
fix: add long password ipmi error
Browse files Browse the repository at this point in the history
The given IPMI password can be longer than IPMI expect. In that case the _parse_output method in Ipmitool's
will output the following error "invalid literal for int() with base 16: 'lanplus:'". While if we look at
the line that was taken from IPMI we will see that its "lanplus: password is longer than 20 bytes.".
So the issue is that there is no check for this error and the function skips it and tries to convert
that string from a hex into an integer. I have added an execption, regex check, the match check and
a test function.

Signed-off-by: Evloev Sayfuddin <evloev.sayfuddin@wb.ru>
  • Loading branch information
FrenkenFlores authored and hthiery committed Jan 7, 2025
1 parent f0df31e commit 0de802b
Show file tree
Hide file tree
Showing 3 changed files with 22 additions and 3 deletions.
9 changes: 9 additions & 0 deletions pyipmi/errors.py
Original file line number Diff line number Diff line change
Expand Up @@ -90,3 +90,12 @@ def __init__(self, msg=None):

def __str__(self):
return "{}".format(self.msg)


class IpmiLongPasswordError(Exception):
"""Password longer than 20 bytes."""
def __init__(self, msg=None):
self.msg = msg

def __str__(self):
return "{}".format(self.msg)
8 changes: 6 additions & 2 deletions pyipmi/interfaces/ipmitool.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
from array import array

from ..session import Session
from ..errors import IpmiTimeoutError, IpmiConnectionError
from ..errors import IpmiTimeoutError, IpmiConnectionError, IpmiLongPasswordError
from ..logger import log
from ..msgs import encode_message, decode_message, create_message
from ..msgs.constants import CC_OK
Expand Down Expand Up @@ -62,7 +62,8 @@ def __init__(self, interface_type='lan', cipher=None):
r".*Unable to establish.*")
self.re_could_not_open = re.compile(
r".*Could not open device.*")

self.re_long_password = re.compile(
r".*password is longer than.*")
self._session = None

def open(self):
Expand Down Expand Up @@ -135,6 +136,9 @@ def _parse_output(self, output):
if self.re_could_not_open.match(line):
raise RuntimeError('ipmitool failed: {}'.format(output))

if self.re_long_password.match(line):
raise IpmiLongPasswordError(line)

hexstr += line.replace('\r', '').strip() + ' '

hexstr = hexstr.strip()
Expand Down
8 changes: 7 additions & 1 deletion tests/interfaces/test_ipmitool.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

import pytest

from pyipmi.errors import IpmiTimeoutError, IpmiConnectionError
from pyipmi.errors import IpmiTimeoutError, IpmiConnectionError, IpmiLongPasswordError
from pyipmi.interfaces import Ipmitool
from pyipmi import Session, Target
from pyipmi.utils import py3_array_tobytes
Expand Down Expand Up @@ -223,3 +223,9 @@ def test_parse_output_connection_error_rmcp(self):
with pytest.raises(IpmiConnectionError):
cc, rsp = self._interface._parse_output(test_str)
assert rsp is None

def test_parse_long_password_error(self):
test_str = b'lanplus: password is longer than 20 bytes.'
with pytest.raises(IpmiLongPasswordError):
cc, rsp = self._interface._parse_output(test_str)
assert rsp is None

0 comments on commit 0de802b

Please sign in to comment.