/* 
 * $Id: testhook.c,v 1.6 2003/12/09 21:14:31 hei Exp $
 * Sample hook for IPS
 *
 * Written by Harald Eilertsen
 *
 * $Log: testhook.c,v $
 * Revision 1.6  2003/12/09 21:14:31  hei
 * Fix to avoid printing garbage on Windows.
 *
 * Revision 1.5  2003/12/08 23:33:42  hei
 * Redid output slightly, fixed logging for ips 1.0.0 compatibillity, and
 * added code to verify correct version of chook interface.
 *
 * Revision 1.4  2003/10/26 21:57:45  hei
 * Changed to use direct-call callback api
 *
 * Revision 1.3  2003/10/06 23:31:48  hei
 * =Added ipsInitialize and ipsFinalize functions.
 *
 * Revision 1.2  2003/10/06 22:02:25  hei
 * =IPS callbacks now called directly.
 *
 * Revision 1.1.1.1  2003/09/22 23:06:39  hei
 * Initial revision
 *
 */

/**
 * @file testhook.c
 *
 * A sample http-plugin for IPS. This file implements a simple plugin for the
 * HTTP module in IPS. It implements the three functions that IPS will expect 
 * to find in an HTTP-plugin.
 *
 * $Revision: 1.6 $
 * @author Harald Eilertsen (haraldei@anduin.net)
 */

#include <stdlib.h>
#include <malloc.h>
#include <string.h>
#include "ipsHookInterface.h"

/*
 * Lets declare some data to be sent to the client.
 */
char  szHttpHeader[] =  "HTTP/1.1 200\nContent-Type: text/html\n\n<html>\n"
                        "<head>\n<title>IPS Plugin sample</title>\n"
                        "</head>\n<body>\n";
                        
char  szIpsVersion[] = "<h1>%s</h1>\nPlugin interface version: %d<br>\n";
char  szURI[]        = "URI: ";
char  szArgsPassed[] = "<br>\nArgs: ";

char  szHttpFooter[] = "<hr><p>Output produced by IPS sample plugin for C\n</body>\n</html>";



/**
 * Initialize the Hook DLL.
 * This method is called by IPS when the Hook-DLL is first loaded.
 *
 * The method should return \c TRUE (1) if the initialization succeeded and the
 * DLL will stay loaded. In the other case it should return \c FALSE (0) and
 * IPS will unload the DLL (without calling \c ipsFinalize).
 *
 * At this stage, the only valid IPS callback function that can be called is
 * \c Log() with the \c ILC_MAIN_LOG or \c ILC_CONSOLE classes.
 * 
 * @param   pHookInfo          \b IN Pointer to HookInfo provided by IPS
 * @return  TRUE if ok, FALSE if DLL should not be loaded.
 *
 * @version 6-okt-2003 /hei/     Created.
 */
IPSBOOL IPSEXPORT ipsInitialize(PIPSHOOKINFO pHookInfo)
{
   // Verify that we're running on the correct version of IPS
   if (pHookInfo->hookVersion == IPS_CHOOK_VERSION) {
      // Log that we're loading
      IpsLog(pHookInfo, ILC_SYSTEM_LOG_CONSOLE, 0, "TestHook Loaded!");
      return TRUE;
   } else {
      IpsLog(pHookInfo, ILC_SYSTEM_LOG_CONSOLE, 0, "TestHook uable to load, incorrect IPS version!");
   }
   return FALSE;
}

/**
 * Process the http-requestst.
 * This function is called by IPS to process the http request. The URL and 
 * parameters of the request can be queried from IPS using the \c GetValue 
 * callback.
 *
 * This example function will generate a web-page displaying the IPS and 
 * plugin system version information, and send this to the client.
 *
 * @param   pHookInfo \b IN The information passed from IPS to the plugin.
 * @return  TRUE (1) if sucessfull, FALSE (0) to fail the request.
 *
 * @warning This function is subject to buffer overflows.
 *
 * @version 6-okt-2003 /hei/     Changed to call IPS callbacks directly\n
 */
IPSBOOL IPSEXPORT ipsHttpRequest(PIPSHOOKINFO	pHookInfo)
{
   char           szBuffer[256];
   int            len;

   // Log that we're working
   IpsLog(pHookInfo, ILC_DEFAULT, 0, "TestHook Processing Request!");

	// Send reply header to client
   IpsSend(pHookInfo, szHttpHeader, sizeof(szHttpHeader)-1);
   
   // Send version and uild info to the client
   len = sprintf(szBuffer, szIpsVersion, pHookInfo->ipsVersionString, pHookInfo->hookVersion);
   if (len > 0) {
      IpsSend(pHookInfo, szBuffer, len);
   }
   
   // Retreive the request uri from IPS, and send it to the client
   IpsGetValue(pHookInfo, IVT_VARIABLEVALUE, "http.request.uri", szBuffer, sizeof(szBuffer));
   len = strlen(szBuffer);
   if (len > 0) {
      IpsSend(pHookInfo, szURI, sizeof(szURI)-1);
      IpsSend(pHookInfo, szBuffer, len);
   }
   
   // Get the arguments passed in the request, and send them to the client.
   IpsGetValue(pHookInfo, IVT_VARIABLEVALUE, "http.querystring", szBuffer, sizeof(szBuffer));
   len = strlen(szBuffer);
   if (len > 0) {
      IpsSend(pHookInfo, szArgsPassed, sizeof(szArgsPassed)-1);
      IpsSend(pHookInfo, szBuffer, len);
   }
   
   // Send page footer to client.
   IpsSend(pHookInfo, szHttpFooter, sizeof(szHttpFooter)-1);
	
   // Return TRUE to indicate we processed the event
	return TRUE;
}

/**
 * Finalize processing.
 * This method is called by IPS when the Hook-DLL is about to be unloaded.
 *
 * The same restrictions as for \c ipsInitialize also applies to this method.
 *
 * @param pHookInfo          \b IN Pointer to HookInfo provided by IPS.
 * @return This function should always return TRUE.
 *
 * @version 6-okt-2003 /hei/     Created.
 */
IPSBOOL IPSEXPORT ipsFinalize(PIPSHOOKINFO pHookInfo)
{
   // Log that we're shutting down
   IpsLog(pHookInfo, ILC_SYSTEM_LOG_CONSOLE, 0, "TestHook Unloaded!");
   return TRUE;
}
