# Pantera - Web Pen-Test Proxy
#
# FILENAME      : panteraFile.py
# CODER         : Simon Roses Femerling
# DATE          : 07/04/2006
# LAST UPDATE   : 07/04/2006
# ABSTRACT      : Python Web Pen-Test Proxy :)
#                 Pantera File Operation center!
#
# - Roses Labs Innovations (RL+I)
# Roses Labs
# http://www.roseslabs.com
#
# Copyright (c) 2003-2006 Roses Labs.
#
# You may not distribute, transmit, repost this software for commercial 
# purposes without Roses Labs written permission. 
#
# Permission is hereby granted, free of charge, to any person obtaining
# a copy of this software and associated documentation files (the
# "Software"), to deal in the Software without restriction, including
# without limitation the rights to use, copy, modify, publish,
# distribute the Software, and to permit persons to whom the Software 
# is furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included
# in all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
# IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
# CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
# TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#

'''
@author:       Simon Roses Femerling
@license:      GNU General Public License 2.0 or later
@contact:      pantera.proxy@gmail.com
@organization: OWASP / Roses Labs
'''

import panterautils
import os
import sys
import cPickle
import re

#############################################################################################
# Our Functions
#############################################################################################

#############################################################################################
# FUNC     : 
# PARAMS   : string
# RETURN   : file pointer
# ABSTRACT : Open a binary file
class PanteraFile:
    '''
    
    '''
    
    #############################################################################################
    # FUNC     : 
    # PARAMS   : string
    # RETURN   : file pointer
    # ABSTRACT : Open a binary file
    def __init__(self):
        '''
    
        '''
        self.iClear()

    #############################################################################################
    # FUNC     : 
    # PARAMS   : string
    # RETURN   : file pointer
    # ABSTRACT : Open a binary file
    def iClear(self):
        '''
    
        '''
        self.error_msg = ""
    
    #############################################################################################
    # FUNC     : 
    # PARAMS   : string
    # RETURN   : file pointer
    # ABSTRACT : Open a binary file
    def GetErroMsg(self):
        '''
    
        '''
        return self.error_msg

    #############################################################################################
    # FUNC     : 
    # PARAMS   : string
    # RETURN   : file pointer
    # ABSTRACT : Open a binary file
    def SetErrorMsg(self,m):
        '''
    
        '''
        self.error_msg = m

    #############################################################################################
    # FUNC     : 
    # PARAMS   : string
    # RETURN   : file pointer
    # ABSTRACT : Open a binary file
    def OpenBFile(self, file):
        '''
    
        '''
        #unpickle
        try:
            infile=open(file,"rb")
            obj=cPickle.load(infile)
            infile.close()
        except IOError,e:
            er = ""
            er += "Error: Opening file %s\r\n" % file
            er += "%s" % e
            self.SetErrorMsg(er)
            return ""
        return obj
    # EOF: def OpenBFile
                
    #############################################################################################
    # FUNC     : 
    # PARAMS   : ...
    # RETURN   : ...
    # ABSTRACT : 
    def displayResponse(self,file):
        '''
    
        '''
        """Return page response."""
        result=""
        #realfile=panterautils.pathjoin(self.basedir,file)
        obj = self.OpenBFile(file)
        if obj == "": return ""
        #load response
        result+=obj.getResponse()
        #send it out
        return result

    #############################################################################################
    def JustResponseHeader(self, file):
        '''
    
        '''
        """Return just page response (header)"""
        result=""
        #realfile=panterautils.pathjoin(self.basedir,file)
        obj = self.OpenBFile(file)
        if obj == "": return ""
        #load response
        result+=obj.JustResponseHeader()
        #send it out
        return result

    #############################################################################################
    def printRequestFile(self,realfile):
        '''
    
        '''
        """Return page request."""
        obj = self.OpenBFile(realfile)
        if obj == "": return ""
        data=obj.printme()
        return data

    #############################################################################################
    # FUNC     : 
    # PARAMS   : ...
    # RETURN   : ...
    # ABSTRACT : 
    def displayClientHeader(self,file):
        '''
    
        '''
        """Return client header."""
        result=""
        #print file
        #realfile=panterautils.pathjoin(self.basedir,file)
        #print realfile
        #print file
        obj = self.OpenBFile(file)
        if obj == "": return ""
        #send it out
        return obj.clientheader

    #############################################################################################
    # FUNC     : 
    # PARAMS   : ...
    # RETURN   : ...
    # ABSTRACT : 
    def ReturnServerHeader(self, file):
        '''
    
        '''
        """Return server header."""
        result=""
        #realfile=panterautils.pathjoin(self.basedir,file)
        obj = self.OpenBFile(file)
        #load response
        result+=obj.getResponseHeader()
        if obj == "": return ""
        #send it out
        return result

    #############################################################################################
    def ReturnServerFirstLine(self,file):
        '''
    
        '''
        """Return server header first line."""
        result=""
        #realfile=panterautils.pathjoin(self.basedir,file)
        obj = self.OpenBFile(file)
        if obj == "": return ""
        #load response
        result+=obj.ReturnServerFirstLine()
        p = re.compile('30') #if HTTP 30X show location tag!
        if p.search(result):
            r = obj.GetServerHeader('Location')
            if r!="":
                result += " -> Location: %s" % panterautils.TruncateURL(r,80)
        #send it out
        return result
        
    #############################################################################################
    # FUNC     : 
    # PARAMS   : ...
    # RETURN   : ...
    # ABSTRACT : 
    def displayClientBody(self,file):
        '''
    
        '''
        """Return client body."""
        result=""
        #realfile=panterautils.pathjoin(self.basedir,file)
        obj = self.OpenBFile(file)
        if obj == "": return ""
        #load response
        return obj.clientbody
        #send it out
        #return result
        
    #############################################################################################
    def ReturnPageBody(self, f):
        '''
    
        '''
        """Return pahe body."""
        obj = self.OpenBFile(f)
        if obj == "": return ""
        return obj.printBody(1) #enable gzip 

    def ReturnClientHeader(self, obj):
        '''
    
        '''
        """ Return client header and parse values. """
        str_h = ""

        str_h += "%s %s%s" % (obj.verb,obj.connectHost,obj.URL) 
        args = ""
        if obj.useRawArguments == 0:
            if len(obj.allURLargs) > 0:
                args += "?%s" % obj.allURLargs
            else:
                if len(obj.URLargsDict) > 0:
                    args += "?"
                    args += panterautils.joinargs(obj.URLargsDict,orderlist=obj.orderlist)
        str_h += "%s %s\r\n" % (args,obj.version)
        i = len(obj.headerValuesDict)
        #z = 1
        for hkey in obj.headerValuesDict.keys():
            for val in obj.headerValuesDict[hkey]:
                if val.count('"')>0:
                    str_h += "%s: %s\r\n" % (hkey,panterautils.FixString(val)) 
                else:
                    str_h += "%s: %s\r\n" % (hkey,val) 
                #if z < i:
                #    str_h += "\\r\\n\"+\r\n"
                #    z += 1
        return str_h

#############################################################################################
# FUNC     : 
# PARAMS   : string
# RETURN   : file pointer
# ABSTRACT : Open a binary file
class PanteraFileManager:
    '''
    
    '''

    #############################################################################################
    # FUNC     : 
    # PARAMS   : string
    # RETURN   : file pointer
    # ABSTRACT : Open a binary file
    def __init__(self):
        '''
    
        '''
        self.iClear()

    #############################################################################################
    # FUNC     : 
    # PARAMS   : string
    # RETURN   : file pointer
    # ABSTRACT : Open a binary file
    def iClear(self):
        '''
    
        '''
        self.error_msg = ""
        self.filename = ''
        self.fp = ''
    
    #############################################################################################
    # FUNC     : 
    # PARAMS   : string
    # RETURN   : file pointer
    # ABSTRACT : Open a binary file
    def GetErroMsg(self):
        '''
    
        '''
        return self.error_msg

    #############################################################################################
    # FUNC     : 
    # PARAMS   : string
    # RETURN   : file pointer
    # ABSTRACT : Open a binary file
    def SetErrorMsg(self,m):
        '''
    
        '''
        self.error_msg = m

    def SetFilename(self, f):
        '''
    
        '''
        self.filename = f
        
    def ReturnFilename(self):
        '''
    
        '''
        return self.filename
    
    def ReturnFilePointer(self):
        '''
    
        '''
        return self.fp

    def OpenFile(self):
        '''
    
        '''
        try:
            self.fp=open(self.filename,"w")
        except IOError,e:
            er = ""
            er += "Error: Opening file %s\r\n" % self.filename
            er += "%s" % e
            self.SetErrorMsg(er)
            return -1
        return 0

    def CloseFile(self):
        '''
    
        '''
        try:
            self.fp.close()
        except IOError,e:
            er = ""
            er += "Error: Opening file %s\r\n" % self.filename
            er += "%s" % e
            self.SetErrorMsg(er)
            return -1
        return 0
            
    def WriteData(self, d):
        '''
    
        '''
        l = len(d)
        try:
            self.fp.write(d)
            self.fp.flush()
        except IOError,e:
            er = ""
            er += "Error: Opening file %s\r\n" % self.filename
            er += "%s" % e
            self.SetErrorMsg(er)
            return -1
        return l
            
# RL+I EOF