Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
elif isinstance(pkt, TftpPacketRRQ):
self.sendError(TftpErrors.IllegalTftpOp)
raise TftpException("Received RRQ from server while in upload")
elif isinstance(pkt, TftpPacketDAT):
self.sendError(TftpErrors.IllegalTftpOp)
raise TftpException("Received DAT from server while in upload")
else:
self.sendError(TftpErrors.IllegalTftpOp)
raise TftpException("Received unknown packet type from server: %s" % pkt)
# By default, no state change.
return self
class TftpStateSentRRQ(TftpState):
"""Just sent an RRQ packet."""
def handle(self, pkt, raddress, rport):
"""Handle the packet in response to an RRQ to the server."""
if not self.context.tidport:
self.context.tidport = rport
log.info("Set remote port for session to %s" % rport)
# Now check the packet type and dispatch it properly.
if isinstance(pkt, TftpPacketOACK):
log.info("Received OACK from server")
try:
self.handleOACK(pkt)
except TftpException as err:
log.error("Failed to negotiate options: %s" % str(err))
self.sendError(TftpErrors.FailedNegotiation)
raise
def __init__(self, context):
TftpState.__init__(self, context)
# This variable is used to store the absolute path to the file being
# managed.
self.full_path = None
self.sendOACK()
else:
log.debug("No requested options, expecting transfer to begin...")
self.sendACK()
# Whether we're sending an oack or not, we're expecting a DAT for
# block 1
self.context.next_block = 1
# We may have sent an OACK, but we're expecting a DAT as the response
# to either the OACK or an ACK, so lets unconditionally use the
# TftpStateExpectDAT state.
return TftpStateExpectDAT(self.context)
# Note, we don't have to check any other states in this method, that's
# up to the caller.
class TftpStateServerStart(TftpState):
"""The start state for the server. This is a transitory state since at
this point we don't know if we're handling an upload or a download. We
will commit to one of them once we interpret the initial packet."""
def handle(self, pkt, raddress, rport):
"""Handle a packet we just received."""
log.debug("In TftpStateServerStart.handle")
if isinstance(pkt, TftpPacketRRQ):
log.debug("Handling an RRQ packet")
return TftpStateServerRecvRRQ(self.context).handle(pkt,
raddress,
rport)
elif isinstance(pkt, TftpPacketWRQ):
log.debug("Handling a WRQ packet")
return TftpStateServerRecvWRQ(self.context).handle(pkt,
raddress,
rport)
import fs
import os
import logging
import tftpy
import time
from gevent import socket
from fs import errors
from tftpy import TftpException, TftpErrors
from tftpy.TftpStates import TftpStateExpectACK, TftpStateExpectDAT
from tftpy.TftpPacketTypes import TftpPacketRRQ, TftpPacketWRQ
from conpot.helpers import sanitize_file_name
logger = logging.getLogger(__name__)
class TFTPState(tftpy.TftpStates.TftpState):
def __int__(self, context):
super().__init__(context)
def handle(self, pkt, raddress, rport):
raise NotImplementedError
class TFTPServerState(TFTPState):
"""The base class for server states. """
# We had to rewrite the because -- had to check os.* wrappers.
vfs, data_fs = None, None
full_path = None
def handle(self, pkt, raddress, rport):
raise NotImplementedError
self.sendOACK()
else:
log.debug("No requested options, expecting transfer to begin...")
self.sendACK()
# Whether we're sending an oack or not, we're expecting a DAT for
# block 1
self.context.next_block = 1
# We may have sent an OACK, but we're expecting a DAT as the response
# to either the OACK or an ACK, so lets unconditionally use the
# TftpStateExpectDAT state.
return TftpStateExpectDAT(self.context)
# Note, we don't have to check any other states in this method, that's
# up to the caller.
class TftpStateServerStart(TftpState):
"""The start state for the server. This is a transitory state since at
this point we don't know if we're handling an upload or a download. We
will commit to one of them once we interpret the initial packet."""
def handle(self, pkt, raddress, rport):
"""Handle a packet we just received."""
log.debug("In TftpStateServerStart.handle")
if isinstance(pkt, TftpPacketRRQ):
log.debug("Handling an RRQ packet")
return TftpStateServerRecvRRQ(self.context).handle(pkt,
raddress,
rport)
elif isinstance(pkt, TftpPacketWRQ):
log.debug("Handling a WRQ packet")
return TftpStateServerRecvWRQ(self.context).handle(pkt,
raddress,
rport)
log.debug("In TftpStateServerStart.handle")
if isinstance(pkt, TftpPacketRRQ):
log.debug("Handling an RRQ packet")
return TftpStateServerRecvRRQ(self.context).handle(pkt,
raddress,
rport)
elif isinstance(pkt, TftpPacketWRQ):
log.debug("Handling a WRQ packet")
return TftpStateServerRecvWRQ(self.context).handle(pkt,
raddress,
rport)
else:
self.sendError(TftpErrors.IllegalTftpOp)
raise TftpException("Invalid packet to begin up/download: %s" % pkt)
class TftpStateExpectACK(TftpState):
"""This class represents the state of the transfer when a DAT was just
sent, and we are waiting for an ACK from the server. This class is the
same one used by the client during the upload, and the server during the
download."""
def handle(self, pkt, raddress, rport):
"Handle a packet, hopefully an ACK since we just sent a DAT."
if isinstance(pkt, TftpPacketACK):
log.debug("Received ACK for packet %d" % pkt.blocknumber)
# Is this an ack to the one we just sent?
if self.context.next_block == pkt.blocknumber:
if self.context.pending_complete:
log.info("Received ACK to final DAT, we're done.")
return None
else:
log.debug("Good ACK, sending next DAT")
self.context.next_block += 1
self.sendError(TftpErrors.IllegalTftpOp)
raise TftpException("Received ACK from peer when expecting DAT")
elif isinstance(pkt, TftpPacketWRQ):
self.sendError(TftpErrors.IllegalTftpOp)
raise TftpException("Received WRQ from peer when expecting DAT")
elif isinstance(pkt, TftpPacketERR):
self.sendError(TftpErrors.IllegalTftpOp)
raise TftpException("Received ERR from peer: " + str(pkt))
else:
self.sendError(TftpErrors.IllegalTftpOp)
raise TftpException("Received unknown packet type from peer: " + str(pkt))
class TftpStateSentWRQ(TftpState):
"""Just sent an WRQ packet for an upload."""
def handle(self, pkt, raddress, rport):
"""Handle a packet we just received."""
if not self.context.tidport:
self.context.tidport = rport
log.debug("Set remote port for session to %s", rport)
# If we're going to successfully transfer the file, then we should see
# either an OACK for accepted options, or an ACK to ignore options.
if isinstance(pkt, TftpPacketOACK):
log.info("Received OACK from server")
try:
self.handleOACK(pkt)
except TftpException:
log.error("Failed to negotiate options")
self.sendError(TftpErrors.FailedNegotiation)
% pkt.blocknumber)
self.context.metrics.add_dup(pkt)
else:
log.warning("Oooh, time warp. Received ACK to packet we "
"didn't send yet. Discarding.")
self.context.metrics.errors += 1
return self
elif isinstance(pkt, TftpPacketERR):
log.error("Received ERR packet from peer: %s" % str(pkt))
raise TftpException("Received ERR packet from peer: %s" % str(pkt))
else:
log.warning("Discarding unsupported packet: %s" % str(pkt))
return self
class TftpStateExpectDAT(TftpState):
"""Just sent an ACK packet. Waiting for DAT."""
def handle(self, pkt, raddress, rport):
"""Handle the packet in response to an ACK, which should be a DAT."""
if isinstance(pkt, TftpPacketDAT):
return self.handleDat(pkt)
# Every other packet type is a problem.
elif isinstance(pkt, TftpPacketACK):
# Umm, we ACK, you don't.
self.sendError(TftpErrors.IllegalTftpOp)
raise TftpException("Received ACK from peer when expecting DAT")
elif isinstance(pkt, TftpPacketWRQ):
self.sendError(TftpErrors.IllegalTftpOp)
raise TftpException("Received WRQ from peer when expecting DAT")
def __init__(self, context):
TftpState.__init__(self, context)
# This variable is used to store the absolute path to the file being
# managed.
self.full_path = None
elif isinstance(pkt, TftpPacketRRQ):
self.sendError(TftpErrors.IllegalTftpOp)
raise TftpException("Received RRQ from server while in upload")
elif isinstance(pkt, TftpPacketDAT):
self.sendError(TftpErrors.IllegalTftpOp)
raise TftpException("Received DAT from server while in upload")
else:
self.sendError(TftpErrors.IllegalTftpOp)
raise TftpException("Received unknown packet type from server: %s" % pkt)
# By default, no state change.
return self
class TftpStateSentRRQ(TftpState):
"""Just sent an RRQ packet."""
def handle(self, pkt, raddress, rport):
"""Handle the packet in response to an RRQ to the server."""
if not self.context.tidport:
self.context.tidport = rport
log.info("Set remote port for session to %s" % rport)
# Now check the packet type and dispatch it properly.
if isinstance(pkt, TftpPacketOACK):
log.info("Received OACK from server")
try:
self.handleOACK(pkt)
except TftpException as err:
log.error("Failed to negotiate options: %s" % str(err))
self.sendError(TftpErrors.FailedNegotiation)
raise