/*
 * security.c: Implementation of the XSLT security framework
 *
 * See Copyright for the status of this software.
 *
 * daniel@veillard.com
 */

#define IN_LIBXSLT
#include "libxslt.h"

#include <string.h>

#ifdef HAVE_SYS_TYPES_H
#include <sys/types.h>
#endif
#ifdef HAVE_SYS_STAT_H
#include <sys/stat.h>
#endif

#ifdef HAVE_MATH_H
#include <math.h>
#endif
#ifdef HAVE_FLOAT_H
#include <float.h>
#endif
#ifdef HAVE_IEEEFP_H
#include <ieeefp.h>
#endif
#ifdef HAVE_NAN_H
#include <nan.h>
#endif
#ifdef HAVE_CTYPE_H
#include <ctype.h>
#endif

#if defined(WIN32) && !defined(__CYGWIN__)
#include <windows.h>
#ifndef INVALID_FILE_ATTRIBUTES
#define INVALID_FILE_ATTRIBUTES ((DWORD)-1)
#endif
#endif

#ifndef HAVE_STAT
#  ifdef HAVE__STAT
     /* MS C library seems to define stat and _stat. The definition
      *         is identical. Still, mapping them to each other causes a warning. */
#    ifndef _MSC_VER
#      define stat(x,y) _stat(x,y)
#    endif
#    define HAVE_STAT
#  endif
#endif

#include <libxml/xmlmemory.h>
#include <libxml/tree.h>
#include <libxml/uri.h>
#include "xslt.h"
#include "xsltInternals.h"
#include "xsltutils.h"
#include "extensions.h"
#include "security.h"


struct _xsltSecurityPrefs {
    xsltSecurityCheck readFile;
    xsltSecurityCheck createFile;
    xsltSecurityCheck createDir;
    xsltSecurityCheck readNet;
    xsltSecurityCheck writeNet;
};

static xsltSecurityPrefsPtr xsltDefaultSecurityPrefs = NULL;

/************************************************************************
 *									*
 *			Module interfaces				*
 *									*
 ************************************************************************/

/**
 * xsltNewSecurityPrefs:
 *
 * Create a new security preference block
 *
 * Returns a pointer to the new block or NULL in case of error
 */
xsltSecurityPrefsPtr
xsltNewSecurityPrefs(void) {
    xsltSecurityPrefsPtr ret;

    xsltInitGlobals();

    ret = (xsltSecurityPrefsPtr) xmlMalloc(sizeof(xsltSecurityPrefs));
    if (ret == NULL) {
	xsltTransformError(NULL, NULL, NULL,
		"xsltNewSecurityPrefs : malloc failed\n");
	return(NULL);
    }
    memset(ret, 0, sizeof(xsltSecurityPrefs));
    return(ret);
}

/**
 * xsltFreeSecurityPrefs:
 * @sec:  the security block to free
 *
 * Free up a security preference block
 */
void
xsltFreeSecurityPrefs(xsltSecurityPrefsPtr sec) {
    if (sec == NULL)
	return;
    xmlFree(sec);
}

/**
 * xsltSetSecurityPrefs:
 * @sec:  the security block to update
 * @option:  the option to update
 * @func:  the user callback to use for this option
 *
 * Update the security option to use the new callback checking function
 *
 * Returns -1 in case of error, 0 otherwise
 */
int
xsltSetSecurityPrefs(xsltSecurityPrefsPtr sec, xsltSecurityOption option,
                     xsltSecurityCheck func) {
    xsltInitGlobals();
    if (sec == NULL)
	return(-1);
    switch (option) {
        case XSLT_SECPREF_READ_FILE:
            sec->readFile = func; return(0);
        case XSLT_SECPREF_WRITE_FILE:
            sec->createFile = func; return(0);
        case XSLT_SECPREF_CREATE_DIRECTORY:
            sec->createDir = func; return(0);
        case XSLT_SECPREF_READ_NETWORK:
            sec->readNet = func; return(0);
        case XSLT_SECPREF_WRITE_NETWORK:
            sec->writeNet = func; return(0);
    }
    return(-1);
}

/**
 * xsltGetSecurityPrefs:
 * @sec:  the security block to update
 * @option:  the option to lookup
 *
 * Lookup the security option to get the callback checking function
 *
 * Returns NULL if not found, the function otherwise
 */
xsltSecurityCheck
xsltGetSecurityPrefs(xsltSecurityPrefsPtr sec, xsltSecurityOption option) {
    if (sec == NULL)
	return(NULL);
    switch (option) {
        case XSLT_SECPREF_READ_FILE:
            return(sec->readFile);
        case XSLT_SECPREF_WRITE_FILE:
            return(sec->createFile);
        case XSLT_SECPREF_CREATE_DIRECTORY:
            return(sec->createDir);
        case XSLT_SECPREF_READ_NETWORK:
            return(sec->readNet);
        case XSLT_SECPREF_WRITE_NETWORK:
            return(sec->writeNet);
    }
    return(NULL);
}

/**
 * xsltSetDefaultSecurityPrefs:
 * @sec:  the security block to use
 *
 * Set the default security preference application-wide
 */
void
xsltSetDefaultSecurityPrefs(xsltSecurityPrefsPtr sec) {
    
    xsltDefaultSecurityPrefs = sec;
}

/**
 * xsltGetDefaultSecurityPrefs:
 *
 * Get the default security preference application-wide
 *
 * Returns the current xsltSecurityPrefsPtr in use or NULL if none
 */
xsltSecurityPrefsPtr
xsltGetDefaultSecurityPrefs(void) {
    return(xsltDefaultSecurityPrefs);
}

/**
 * xsltSetCtxtSecurityPrefs:
 * @sec:  the security block to use
 * @ctxt:  an XSLT transformation context
 *
 * Set the security preference for a specific transformation
 *
 * Returns -1 in case of error, 0 otherwise
 */
int                    
xsltSetCtxtSecurityPrefs(xsltSecurityPrefsPtr sec,
	                 xsltTransformContextPtr ctxt) {
    if (ctxt == NULL)
	return(-1);
    ctxt->sec = (void *) sec;
    return(0);
}


/**
 * xsltSecurityAllow:
 * @sec:  the security block to use
 * @ctxt:  an XSLT transformation context
 * @value:  unused
 *
 * Function used to always allow an operation
 *
 * Returns 1 always
 */
int
xsltSecurityAllow(xsltSecurityPrefsPtr sec ATTRIBUTE_UNUSED,
	          xsltTransformContextPtr ctxt ATTRIBUTE_UNUSED,
		  const char *value ATTRIBUTE_UNUSED) {
    return(1);
}

/**
 * xsltSecurityForbid:
 * @sec:  the security block to use
 * @ctxt:  an XSLT transformation context
 * @value:  unused
 *
 * Function used to always forbid an operation
 *
 * Returns 0 always
 */
int
xsltSecurityForbid(xsltSecurityPrefsPtr sec ATTRIBUTE_UNUSED,
	          xsltTransformContextPtr ctxt ATTRIBUTE_UNUSED,
		  const char *value ATTRIBUTE_UNUSED) {
    return(0);
}

/************************************************************************
 *									*
 *			Internal interfaces				*
 *									*
 ************************************************************************/

/**
 * xsltCheckFilename
 * @path:  the path to check
 *
 * function checks to see if @path is a valid source
 * (file, socket...) for XML.
 *
 * TODO: remove at some point !!!
 * Local copy of xmlCheckFilename to avoid a hard dependency on
 * a new version of libxml2 
 *
 * if stat is not available on the target machine,
 * returns 1.  if stat fails, returns 0 (if calling
 * stat on the filename fails, it can't be right).
 * if stat succeeds and the file is a directory,
 * returns 2.  otherwise returns 1.
 */

static int
xsltCheckFilename (const char *path)
{
#ifdef HAVE_STAT
    struct stat stat_buffer;
#if defined(WIN32) && !defined(__CYGWIN__)
    DWORD dwAttrs;

    dwAttrs = GetFileAttributes(path); 
    if (dwAttrs != INVALID_FILE_ATTRIBUTES) {
        if (dwAttrs & FILE_ATTRIBUTE_DIRECTORY) {
            return 2;
		}
    }
#endif

    if (stat(path, &stat_buffer) == -1)
        return 0;

#ifdef S_ISDIR
    if (S_ISDIR(stat_buffer.st_mode)) {
        return 2;
    }
#endif
#endif
    return 1;
}

static int
xsltCheckWritePath(xsltSecurityPrefsPtr sec,
		   xsltTransformContextPtr ctxt,
		   const char *path)
{
    int ret;
    xsltSecurityCheck check;
    char *directory;

    check = xsltGetSecurityPrefs(sec, XSLT_SECPREF_WRITE_FILE);
    if (check != NULL) {
	ret = check(sec, ctxt, path);
	if (ret == 0) {
	    xsltTransformError(ctxt, NULL, NULL,
			       "File write for %s refused\n", path);
	    return(0);
	}
    }

    directory = xmlParserGetDirectory (path);

    if (directory != NULL) {
	ret = xsltCheckFilename(directory);
	if (ret == 0) {
	    /*
	     * The directory doesn't exist check for creation
	     */
	    check = xsltGetSecurityPrefs(sec,
					 XSLT_SECPREF_CREATE_DIRECTORY);
	    if (check != NULL) {
		ret = check(sec, ctxt, directory);
		if (ret == 0) {
		    xsltTransformError(ctxt, NULL, NULL,
				       "Directory creation for %s refused\n",
				       path);
		    xmlFree(directory);
		    return(0);
		}
	    }
	    ret = xsltCheckWritePath(sec, ctxt, directory);
	    if (ret == 1)
		ret = mkdir(directory, 0755);
	}
	xmlFree(directory);
	if (ret < 0)
	    return(ret);
    }

    return(1);
}

/**
 * xsltCheckWrite:
 * @sec:  the security options
 * @ctxt:  an XSLT transformation context
 * @URL:  the resource to be written
 *
 * Check if the resource is allowed to be written, if necessary makes
 * some preliminary work like creating directories
 *
 * Return 1 if write is allowed, 0 if not and -1 in case or error.
 */
int
xsltCheckWrite(xsltSecurityPrefsPtr sec,
	       xsltTransformContextPtr ctxt, const xmlChar *URL) {
    int ret;
    xmlURIPtr uri;
    xsltSecurityCheck check;

    uri = xmlParseURI((const char *)URL);
    if (uri == NULL) {
        uri = xmlCreateURI();
	if (uri == NULL) {
	    xsltTransformError(ctxt, NULL, NULL,
	     "xsltCheckWrite: out of memory for %s\n", URL);
	    return(-1);
	}
	uri->path = (char *)xmlStrdup(URL);
    }
    if ((uri->scheme == NULL) ||
	(xmlStrEqual(BAD_CAST uri->scheme, BAD_CAST "file"))) {

#if defined(WIN32) && !defined(__CYGWIN__)
    if ((uri->path)&&(uri->path[0]=='/')&&
        (uri->path[1]!='\0')&&(uri->path[2]==':'))
    ret = xsltCheckWritePath(sec, ctxt, uri->path+1);
    else
#endif

	/*
	 * Check if we are allowed to write this file
	 */
	ret = xsltCheckWritePath(sec, ctxt, uri->path);
	if (ret <= 0) {
	    xmlFreeURI(uri);
	    return(ret);
	}
    } else {
	/*
	 * Check if we are allowed to write this network resource
	 */
	check = xsltGetSecurityPrefs(sec, XSLT_SECPREF_WRITE_NETWORK);
	if (check != NULL) {
	    ret = check(sec, ctxt, (const char *)URL);
	    if (ret == 0) {
		xsltTransformError(ctxt, NULL, NULL,
			     "File write for %s refused\n", URL);
		xmlFreeURI(uri);
		return(0);
	    }
	}
    }
    xmlFreeURI(uri);
    return(1);
}


/**
 * xsltCheckRead:
 * @sec:  the security options
 * @ctxt: an XSLT transformation context
 * @URL:  the resource to be read
 *
 * Check if the resource is allowed to be read
 *
 * Return 1 if read is allowed, 0 if not and -1 in case or error.
 */
int
xsltCheckRead(xsltSecurityPrefsPtr sec,
	      xsltTransformContextPtr ctxt, const xmlChar *URL) {
    int ret;
    xmlURIPtr uri;
    xsltSecurityCheck check;

    uri = xmlParseURI((const char *)URL);
    if (uri == NULL) {
	xsltTransformError(ctxt, NULL, NULL,
	 "xsltCheckRead: URL parsing failed for %s\n",
			 URL);
	return(-1);
    }
    if ((uri->scheme == NULL) ||
	(xmlStrEqual(BAD_CAST uri->scheme, BAD_CAST "file"))) {

	/*
	 * Check if we are allowed to read this file
	 */
	check = xsltGetSecurityPrefs(sec, XSLT_SECPREF_READ_FILE);
	if (check != NULL) {
	    ret = check(sec, ctxt, uri->path);
	    if (ret == 0) {
		xsltTransformError(ctxt, NULL, NULL,
			     "Local file read for %s refused\n", URL);
		xmlFreeURI(uri);
		return(0);
	    }
	}
    } else {
	/*
	 * Check if we are allowed to write this network resource
	 */
	check = xsltGetSecurityPrefs(sec, XSLT_SECPREF_READ_NETWORK);
	if (check != NULL) {
	    ret = check(sec, ctxt, (const char *)URL);
	    if (ret == 0) {
		xsltTransformError(ctxt, NULL, NULL,
			     "Network file read for %s refused\n", URL);
		xmlFreeURI(uri);
		return(0);
	    }
	}
    }
    xmlFreeURI(uri);
    return(1);
}

