Skip to content

Commit

Permalink
IPMI Tests
Browse files Browse the repository at this point in the history
  • Loading branch information
xandfury committed Jul 28, 2018
1 parent 8ee0227 commit 69a477c
Show file tree
Hide file tree
Showing 6 changed files with 162 additions and 142 deletions.
1 change: 1 addition & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ addons:
- libxml2-utils
- python-mysqldb
- libmysqlclient-dev
- ipmitool
install:
- export PYTHONIOENCODING=UTF8
- git show HEAD:conpot/__init__.py > docs/source/conpot_version.py
Expand Down
9 changes: 5 additions & 4 deletions conpot/protocols/ipmi/fakebmc.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,19 +16,20 @@
# Brno University of Technology, Faculty of Information Technology

import logging

from pyghmi.ipmi.bmc import Bmc


logger = logging.getLogger(__name__)
logger = logging.getLogger()


class FakeBmc(Bmc):

def __init__(self, authdata, port):
self.authdata = authdata
self.port = port
self.port = 623
self.powerstate = 'off'
self.bootdevice = 'default'
super(FakeBmc, self).__init__(authdata=authdata, port=port)
logger.info('IPMI BMC initialized.')

def get_boot_device(self):
Expand Down Expand Up @@ -69,4 +70,4 @@ def power_cycle(self):

def power_shutdown(self):
logger.info('IPMI BMC Power_Shutdown request.')
self.powerstate = 'off'
self.powerstate = 'off'
45 changes: 21 additions & 24 deletions conpot/protocols/ipmi/fakesession.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,15 +38,15 @@ def _monotonic_time():


class FakeSession(Session):

def __init__(self, bmc, userid, password, port):
self.lastpayload = None
self.servermode = True
self.privlevel = 4
self.request_entry = []
self.request_entry = []
self.socket = None
self.response = None
self.stage = 0

self.bmc = bmc
self.port = port
self.bmc_handlers = {}
Expand All @@ -57,11 +57,10 @@ def __init__(self, bmc, userid, password, port):
self.userid = userid
self.password = password
self._initsession()
self.sockaddr = (bmc, port)
self.sockaddr = (bmc, port)
self.server = None
self.sol_handler = None
self.ipmicallback = self._generic_callback
super(Session, self).__init__()
logger.info('New IPMI session initialized for client (%s)', self.sockaddr)

def _generic_callback(self, response):
Expand Down Expand Up @@ -133,7 +132,7 @@ def _ipmi20(self, rawdata):
payload = list(payload[:-padsize])
if payload_type == 0:
self._ipmi15(payload)
elif payload_type == 1:
elif payload_type == 1:
if self.last_payload_type == 1:
self.lastpayload = None
self.last_payload_type = None
Expand All @@ -155,18 +154,18 @@ def _ipmi15(self, payload):
self.clientcommand = payload[5]
self._parse_payload(payload)
return

def _parse_payload(self, payload):
if hasattr(self, 'hasretried'):
if self.hasretried:
self.hasretried = 0
self.tabooseq[(self.expectednetfn, self.expectedcmd, self.seqlun)] = 16
self.expectednetfn = 0x1ff
self.expectednetfn = 0x1ff
self.expectedcmd = 0x1ff
self.waiting_sessions.pop(self, None)
self.lastpayload = None
self.last_payload_type = None
response = dict()
response = {}
response['netfn'] = payload[1] >> 2
del payload[0:5]
# remove the trailing checksum
Expand All @@ -177,8 +176,8 @@ def _parse_payload(self, payload):
self.timeout = 0.5 + (0.5 * random.random())
self.ipmicallback(response)

def _send_ipmi_net_payload(self, netfn=None, command=None, data=None, code=0, bridge_request=None,
retry=None, delay_xmit=None, timeout=None):
def _send_ipmi_net_payload(self, netfn=None, command=None, data=None, code=0, bridge_request=None, \
retry=None, delay_xmit=None):
if data is None:
data = []
if retry is None:
Expand All @@ -201,7 +200,7 @@ def _make_ipmi_payload(self, netfn, command, bridge_request=None, data=()):
self.expectednetfn = netfn + 1
# IPMI spec forbids gaps bigger then 7 in seq number.
seqincrement = 7

if bridge_request:
addr = bridge_request.get('addr', 0x0)
channel = bridge_request.get('channel', 0x0)
Expand All @@ -224,6 +223,7 @@ def _make_ipmi_payload(self, netfn, command, bridge_request=None, data=()):
payload.append(tail_csum)
return payload


def _aespad(self, data):
newdata = list(data)
currlen = len(data) + 1
Expand All @@ -237,8 +237,7 @@ def _aespad(self, data):
newdata.append(neededpad)
return newdata

def send_payload(self, payload=(), payload_type=None, retry=True, delay_xmit=None, needskeepalive=False,
timeout=None):
def send_payload(self, payload=(), payload_type=None, retry=True, delay_xmit=None, needskeepalive=False):
if payload and self.lastpayload:
self.pendingpayloads.append((payload, payload_type, retry))
return
Expand All @@ -247,7 +246,7 @@ def send_payload(self, payload=(), payload_type=None, retry=True, delay_xmit=Non
if not payload:
payload = self.lastpayload
# constant RMCP header for IPMI
message = [0x6, 0x00, 0xff, 0x07]
message = [0x6, 0x00, 0xff, 0x07]
if retry:
self.lastpayload = payload
self.last_payload_type = payload_type
Expand All @@ -262,7 +261,7 @@ def send_payload(self, payload=(), payload_type=None, retry=True, delay_xmit=Non
message.append(payload_type)
if baretype == 2:
raise NotImplementedError("OEM Payloads")
elif baretype not in list(constants.payload_types.values()):
elif baretype not in constants.payload_types.values():
raise NotImplementedError("Unrecognized payload type %d" % baretype)
message += struct.unpack("!4B", struct.pack("<I", self.sessionid))
message += struct.unpack("!4B", struct.pack("<I", self.sequencenumber))
Expand All @@ -275,12 +274,12 @@ def send_payload(self, payload=(), payload_type=None, retry=True, delay_xmit=Non
totlen = 34 + len(message)
if totlen in (56, 84, 112, 128, 156):
# Legacy pad as mandated by ipmi spec
message.append(0)
message.append(0)
elif self.ipmiversion == 2.0:
psize = len(payload)
if self.confalgo:
pad = (psize + 1) % 16
if pad:
if pad:
# if no pad needed, then we take no more action
pad = 16 - pad
newpsize = psize + pad + 17
Expand All @@ -293,7 +292,7 @@ def send_payload(self, payload=(), payload_type=None, retry=True, delay_xmit=Non
crypted = crypter.encrypt(struct.pack("%dB" % len(payloadtocrypt), *payloadtocrypt))
crypted = list(struct.unpack("%dB" % len(crypted), crypted))
message += crypted
else:
else:
# no confidetiality algorithm
message.append(psize & 0xff)
message.append(psize >> 8)
Expand All @@ -319,15 +318,15 @@ def send_ipmi_response(self, data=None, code=0):
data = []
self._send_ipmi_net_payload(data=data, code=code)

def _xmit_packet(self, retry=True, delay_xmit=None, timeout=None):
def _xmit_packet(self, retry=True, delay_xmit=None):
if self.sequencenumber:
self.sequencenumber += 1
if delay_xmit is not None:
# skip transmit, let retry timer do it's thing
self.waiting_sessions[self] = {}
self.waiting_sessions[self]['ipmisession'] = self
self.waiting_sessions[self]['timeout'] = delay_xmit + _monotonic_time()
return
self.waiting_sessions[self]['timeout'] = delay_xmit + _monotonic_time()
return
if self.sockaddr:
self.send_data(self.netpacket, self.sockaddr)
else:
Expand All @@ -351,6 +350,4 @@ def _xmit_packet(self, retry=True, delay_xmit=None, timeout=None):

def send_data(self, packet, address):
logger.info('IPMI response sent to %s', address)
self.socket.sendto(packet, address)


self.socket.sendto(packet, address)
Loading

0 comments on commit 69a477c

Please sign in to comment.