## This file is part of Scapy
## See http://www.secdev.org/projects/scapy for more informations
## Copyright (C) Philippe Biondi <phil@secdev.org>
## This program is published under a GPLv2 license

"""
TFTP (Trivial File Transfer Protocol).
"""

from __future__ import absolute_import
import os,random
from scapy.packet import *
from scapy.fields import *
from scapy.automaton import *
from scapy.layers.inet import UDP, IP
from scapy.modules.six.moves import range



TFTP_operations = { 1:"RRQ",2:"WRQ",3:"DATA",4:"ACK",5:"ERROR",6:"OACK" }


class TFTP(Packet):
    name = "TFTP opcode"
    fields_desc = [ ShortEnumField("op", 1, TFTP_operations), ]
    


class TFTP_RRQ(Packet):
    name = "TFTP Read Request"
    fields_desc = [ StrNullField("filename", ""),
                    StrNullField("mode", "octet") ]
    def answers(self, other):
        return 0
    def mysummary(self):
        return self.sprintf("RRQ %filename%"),[UDP]
        

class TFTP_WRQ(Packet):
    name = "TFTP Write Request"
    fields_desc = [ StrNullField("filename", ""),
                    StrNullField("mode", "octet") ]
    def answers(self, other):
        return 0
    def mysummary(self):
        return self.sprintf("WRQ %filename%"),[UDP]

class TFTP_DATA(Packet):
    name = "TFTP Data"
    fields_desc = [ ShortField("block", 0) ]
    def answers(self, other):
        return  self.block == 1 and isinstance(other, TFTP_RRQ)
    def mysummary(self):
        return self.sprintf("DATA %block%"),[UDP]

class TFTP_Option(Packet):
    fields_desc = [ StrNullField("oname",""),
                    StrNullField("value","") ]
    def extract_padding(self, pkt):
        return "",pkt

class TFTP_Options(Packet):
    fields_desc = [ PacketListField("options", [], TFTP_Option, length_from=lambda x:None) ]

    
class TFTP_ACK(Packet):
    name = "TFTP Ack"
    fields_desc = [ ShortField("block", 0) ]
    def answers(self, other):
        if isinstance(other, TFTP_DATA):
            return self.block == other.block
        elif isinstance(other, TFTP_RRQ) or isinstance(other, TFTP_WRQ) or isinstance(other, TFTP_OACK):
            return self.block == 0
        return 0
    def mysummary(self):
        return self.sprintf("ACK %block%"),[UDP]

TFTP_Error_Codes = {  0: "Not defined",
                      1: "File not found",
                      2: "Access violation",
                      3: "Disk full or allocation exceeded",
                      4: "Illegal TFTP operation",
                      5: "Unknown transfer ID",
                      6: "File already exists",
                      7: "No such user",
                      8: "Terminate transfer due to option negotiation",
                      }
    
class TFTP_ERROR(Packet):
    name = "TFTP Error"
    fields_desc = [ ShortEnumField("errorcode", 0, TFTP_Error_Codes),
                    StrNullField("errormsg", "")]
    def answers(self, other):
        return (isinstance(other, TFTP_DATA) or
                isinstance(other, TFTP_RRQ) or
                isinstance(other, TFTP_WRQ) or 
                isinstance(other, TFTP_ACK))
    def mysummary(self):
        return self.sprintf("ERROR %errorcode%: %errormsg%"),[UDP]


class TFTP_OACK(Packet):
    name = "TFTP Option Ack"
    fields_desc = [  ]
    def answers(self, other):
        return isinstance(other, TFTP_WRQ) or isinstance(other, TFTP_RRQ)


bind_layers(UDP, TFTP, dport=69)
bind_layers(TFTP, TFTP_RRQ, op=1)
bind_layers(TFTP, TFTP_WRQ, op=2)
bind_layers(TFTP, TFTP_DATA, op=3)
bind_layers(TFTP, TFTP_ACK, op=4)
bind_layers(TFTP, TFTP_ERROR, op=5)
bind_layers(TFTP, TFTP_OACK, op=6)
bind_layers(TFTP_RRQ, TFTP_Options)
bind_layers(TFTP_WRQ, TFTP_Options)
bind_layers(TFTP_OACK, TFTP_Options)
    

class TFTP_read(Automaton):
    def parse_args(self, filename, server, sport = None, port=69, **kargs):
        Automaton.parse_args(self, **kargs)
        self.filename = filename
        self.server = server
        self.port = port
        self.sport = sport


    def master_filter(self, pkt):
        return ( IP in pkt and pkt[IP].src == self.server and UDP in pkt
                 and pkt[UDP].dport == self.my_tid
                 and (self.server_tid is None or pkt[UDP].sport == self.server_tid) )
        
    # BEGIN
    @ATMT.state(initial=1)
    def BEGIN(self):
        self.blocksize=512
        self.my_tid = self.sport or RandShort()._fix()
        bind_bottom_up(UDP, TFTP, dport=self.my_tid)
        self.server_tid = None
        self.res = ""

        self.l3 = IP(dst=self.server)/UDP(sport=self.my_tid, dport=self.port)/TFTP()
        self.last_packet = self.l3/TFTP_RRQ(filename=self.filename, mode="octet")
        self.send(self.last_packet)
        self.awaiting=1
        
        raise self.WAITING()
        
    # WAITING
    @ATMT.state()
    def WAITING(self):
        pass


    @ATMT.receive_condition(WAITING)
    def receive_data(self, pkt):
        if TFTP_DATA in pkt and pkt[TFTP_DATA].block == self.awaiting:
            if self.server_tid is None:
                self.server_tid = pkt[UDP].sport
                self.l3[UDP].dport = self.server_tid
            raise self.RECEIVING(pkt)

    @ATMT.receive_condition(WAITING, prio=1)
    def receive_error(self, pkt):
        if TFTP_ERROR in pkt:
            raise self.ERROR(pkt)
    
        
    @ATMT.timeout(WAITING, 3)
    def timeout_waiting(self):
        raise self.WAITING()
    @ATMT.action(timeout_waiting)
    def retransmit_last_packet(self):
        self.send(self.last_packet)

    @ATMT.action(receive_data)
#    @ATMT.action(receive_error)
    def send_ack(self):
        self.last_packet = self.l3 / TFTP_ACK(block = self.awaiting)
        self.send(self.last_packet)
    

    # RECEIVED
    @ATMT.state()
    def RECEIVING(self, pkt):
        if conf.raw_layer in pkt:
            recvd = pkt[conf.raw_layer].load
        else:
            recvd = ""
        self.res += recvd
        self.awaiting += 1
        if len(recvd) == self.blocksize:
            raise self.WAITING()
        raise self.END()

    # ERROR
    @ATMT.state(error=1)
    def ERROR(self,pkt):
        split_bottom_up(UDP, TFTP, dport=self.my_tid)
        return pkt[TFTP_ERROR].summary()
    
    #END
    @ATMT.state(final=1)
    def END(self):
        split_bottom_up(UDP, TFTP, dport=self.my_tid)
        return self.res




class TFTP_write(Automaton):
    def parse_args(self, filename, data, server, sport=None, port=69,**kargs):
        Automaton.parse_args(self, **kargs)
        self.filename = filename
        self.server = server
        self.port = port
        self.sport = sport
        self.blocksize = 512
        self.origdata = data

    def master_filter(self, pkt):
        return ( IP in pkt and pkt[IP].src == self.server and UDP in pkt
                 and pkt[UDP].dport == self.my_tid
                 and (self.server_tid is None or pkt[UDP].sport == self.server_tid) )
        

    # BEGIN
    @ATMT.state(initial=1)
    def BEGIN(self):
        self.data = [self.origdata[i*self.blocksize:(i+1)*self.blocksize]
                     for i in range( len(self.origdata)/self.blocksize+1)]
        self.my_tid = self.sport or RandShort()._fix()
        bind_bottom_up(UDP, TFTP, dport=self.my_tid)
        self.server_tid = None
        
        self.l3 = IP(dst=self.server)/UDP(sport=self.my_tid, dport=self.port)/TFTP()
        self.last_packet = self.l3/TFTP_WRQ(filename=self.filename, mode="octet")
        self.send(self.last_packet)
        self.res = ""
        self.awaiting=0

        raise self.WAITING_ACK()
        
    # WAITING_ACK
    @ATMT.state()
    def WAITING_ACK(self):
        pass

    @ATMT.receive_condition(WAITING_ACK)    
    def received_ack(self,pkt):
        if TFTP_ACK in pkt and pkt[TFTP_ACK].block == self.awaiting:
            if self.server_tid is None:
                self.server_tid = pkt[UDP].sport
                self.l3[UDP].dport = self.server_tid
            raise self.SEND_DATA()

    @ATMT.receive_condition(WAITING_ACK)
    def received_error(self, pkt):
        if TFTP_ERROR in pkt:
            raise self.ERROR(pkt)

    @ATMT.timeout(WAITING_ACK, 3)
    def timeout_waiting(self):
        raise self.WAITING_ACK()
    @ATMT.action(timeout_waiting)
    def retransmit_last_packet(self):
        self.send(self.last_packet)
    
    # SEND_DATA
    @ATMT.state()
    def SEND_DATA(self):
        self.awaiting += 1
        self.last_packet = self.l3/TFTP_DATA(block=self.awaiting)/self.data.pop(0)
        self.send(self.last_packet)
        if self.data:
            raise self.WAITING_ACK()
        raise self.END()
    

    # ERROR
    @ATMT.state(error=1)
    def ERROR(self,pkt):
        split_bottom_up(UDP, TFTP, dport=self.my_tid)
        return pkt[TFTP_ERROR].summary()

    # END
    @ATMT.state(final=1)
    def END(self):
        split_bottom_up(UDP, TFTP, dport=self.my_tid)


class TFTP_WRQ_server(Automaton):

    def parse_args(self, ip=None, sport=None, *args, **kargs):
        Automaton.parse_args(self, *args, **kargs)
        self.ip = ip
        self.sport = sport

    def master_filter(self, pkt):
        return TFTP in pkt and (not self.ip or pkt[IP].dst == self.ip)

    @ATMT.state(initial=1)
    def BEGIN(self):
        self.blksize=512
        self.blk=1
        self.filedata=""
        self.my_tid = self.sport or random.randint(10000,65500)
        bind_bottom_up(UDP, TFTP, dport=self.my_tid)

    @ATMT.receive_condition(BEGIN)
    def receive_WRQ(self,pkt):
        if TFTP_WRQ in pkt:
            raise self.WAIT_DATA().action_parameters(pkt)
        
    @ATMT.action(receive_WRQ)
    def ack_WRQ(self, pkt):
        ip = pkt[IP]
        self.ip = ip.dst
        self.dst = ip.src
        self.filename = pkt[TFTP_WRQ].filename
        options = pkt.getlayer(TFTP_Options)
        self.l3 = IP(src=ip.dst, dst=ip.src)/UDP(sport=self.my_tid, dport=pkt.sport)/TFTP()
        if options is None:
            self.last_packet = self.l3/TFTP_ACK(block=0)
            self.send(self.last_packet)
        else:
            opt = [x for x in options.options if x.oname.upper() == "BLKSIZE"]
            if opt:
                self.blksize = int(opt[0].value)
                self.debug(2,"Negotiated new blksize at %i" % self.blksize)
            self.last_packet = self.l3/TFTP_OACK()/TFTP_Options(options=opt)
            self.send(self.last_packet)

    @ATMT.state()
    def WAIT_DATA(self):
        pass

    @ATMT.timeout(WAIT_DATA, 1)
    def resend_ack(self):
        self.send(self.last_packet)
        raise self.WAIT_DATA()
        
    @ATMT.receive_condition(WAIT_DATA)
    def receive_data(self, pkt):
        if TFTP_DATA in pkt:
            data = pkt[TFTP_DATA]
            if data.block == self.blk:
                raise self.DATA(data)

    @ATMT.action(receive_data)
    def ack_data(self):
        self.last_packet = self.l3/TFTP_ACK(block = self.blk)
        self.send(self.last_packet)

    @ATMT.state()
    def DATA(self, data):
        self.filedata += data.load
        if len(data.load) < self.blksize:
            raise self.END()
        self.blk += 1
        raise self.WAIT_DATA()

    @ATMT.state(final=1)
    def END(self):
        return self.filename,self.filedata
        split_bottom_up(UDP, TFTP, dport=self.my_tid)
        

class TFTP_RRQ_server(Automaton):
    def parse_args(self, store=None, joker=None, dir=None, ip=None, sport=None, serve_one=False, **kargs):
        Automaton.parse_args(self,**kargs)
        if store is None:
            store = {}
        if dir is not None:
            self.dir = os.path.join(os.path.abspath(dir),"")
        else:
            self.dir = None
        self.store = store
        self.joker = joker
        self.ip = ip
        self.sport = sport
        self.serve_one = serve_one
        self.my_tid = self.sport or random.randint(10000,65500)
        bind_bottom_up(UDP, TFTP, dport=self.my_tid)
        
    def master_filter(self, pkt):
        return TFTP in pkt and (not self.ip or pkt[IP].dst == self.ip)

    @ATMT.state(initial=1)
    def WAIT_RRQ(self):
        self.blksize=512
        self.blk=0

    @ATMT.receive_condition(WAIT_RRQ)
    def receive_rrq(self, pkt):
        if TFTP_RRQ in pkt:
            raise self.RECEIVED_RRQ(pkt)


    @ATMT.state()
    def RECEIVED_RRQ(self, pkt):
        ip = pkt[IP]
        options = pkt[TFTP_Options]
        self.l3 = IP(src=ip.dst, dst=ip.src)/UDP(sport=self.my_tid, dport=ip.sport)/TFTP()
        self.filename = pkt[TFTP_RRQ].filename
        self.blk=1
        self.data = None
        if self.filename in self.store:
            self.data = self.store[self.filename]
        elif self.dir is not None:
            fn = os.path.abspath(os.path.join(self.dir, self.filename))
            if fn.startswith(self.dir): # Check we're still in the server's directory
                try:
                    self.data=open(fn).read()
                except IOError:
                    pass
        if self.data is None:
            self.data = self.joker

        if options:
            opt = [x for x in options.options if x.oname.upper() == "BLKSIZE"]
            if opt:
                self.blksize = int(opt[0].value)
                self.debug(2,"Negotiated new blksize at %i" % self.blksize)
            self.last_packet = self.l3/TFTP_OACK()/TFTP_Options(options=opt)
            self.send(self.last_packet)
                

            

    @ATMT.condition(RECEIVED_RRQ)
    def file_in_store(self):
        if self.data is not None:
            self.blknb = len(self.data)/self.blksize+1
            raise self.SEND_FILE()

    @ATMT.condition(RECEIVED_RRQ)
    def file_not_found(self):
        if self.data is None:
            raise self.WAIT_RRQ()
    @ATMT.action(file_not_found)
    def send_error(self):
        self.send(self.l3/TFTP_ERROR(errorcode=1, errormsg=TFTP_Error_Codes[1]))

    @ATMT.state()
    def SEND_FILE(self):
        self.send(self.l3/TFTP_DATA(block=self.blk)/self.data[(self.blk-1)*self.blksize:self.blk*self.blksize])
        
    @ATMT.timeout(SEND_FILE, 3)
    def timeout_waiting_ack(self):
        raise self.SEND_FILE()
            
    @ATMT.receive_condition(SEND_FILE)
    def received_ack(self, pkt):
        if TFTP_ACK in pkt and pkt[TFTP_ACK].block == self.blk:
            raise self.RECEIVED_ACK()
    @ATMT.state()
    def RECEIVED_ACK(self):
        self.blk += 1

    @ATMT.condition(RECEIVED_ACK)
    def no_more_data(self):
        if self.blk > self.blknb:
            if self.serve_one:
                raise self.END()
            raise self.WAIT_RRQ()
    @ATMT.condition(RECEIVED_ACK, prio=2)
    def data_remaining(self):
        raise self.SEND_FILE()

    @ATMT.state(final=1)
    def END(self):
        split_bottom_up(UDP, TFTP, dport=self.my_tid)
    

        

