/* Nessus
 * Copyright (C) 1998 Renaud Deraison
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 *
 * Nessus Communication Manager -- it manages the NTP Protocol, version 1.1
 *
 */ 
 
#include <includes.h>

#include "ntp.h"
#include "parser.h"
#include "ntp_11.h"
#include "comm.h"
#include "auth.h"
#include "rules.h"

static int ntp_11_prefs(struct arglist *);
static int ntp_11_read_prefs(struct arglist *);
static void ntp_11_send_prefs_errors(struct arglist *);
static int ntp_11_rules(struct arglist *);
static int ntp_11_new_attack(struct arglist *, char *);
/*
 * Parses the input sent by the client before
 * the NEW_ATTACK message.
 */
int ntp_11_parse_input(globals, input)
   struct arglist * globals;
   char * input;
{
 char * str;
 char * orig = emalloc(strlen(input)+1);
 strncpy(orig, input, strlen(input));
 
 str = strchr(input, '<');
 if(!str)return(1);
 str = str - 1;
 str[0] = 0;
 if(!strcmp(input, "CLIENT"))
 {
  input = str + 5;
  str = strchr(input, ' ');
  if(str)str[0]=0;
  if(input[strlen(input)-1]=='\n')input[strlen(input)-1]=0;
  if(!strcmp(input, "PREFERENCES")){
  	ntp_11_prefs(globals);
        return(1);
        }
  if(!strcmp(input, "RULES")){
  	ntp_11_rules(globals);
        return(1);
        }
  if(!strcmp(input, "NEW_ATTACK"))return(ntp_11_new_attack(globals, orig));
  return(1);
 }
 return(1);
}



static int ntp_11_prefs(globals)
 struct arglist * globals;
{
 int problem;
 
 problem = ntp_11_read_prefs(globals);
 if(!problem)ntp_11_send_prefs_errors(globals);
 return(problem);
}



static int ntp_11_read_prefs(globals)
 struct arglist * globals;
{
 struct arglist *  preferences = arg_get_value(globals, "preferences");
 int finished = 0;
 char * input = emalloc(4096);
 while(!finished)
 {
  auth_gets(globals, input, 4095);
  if(strstr(input, "<|> CLIENT"))finished = 1;
  else
  {
   char * pref;
   char * value;
   char * v;
 
    pref = input;
    v = strchr(input, '<');
    v-=1;
    v[0] = 0;
    
    value = v + 5;
    v = emalloc(strlen(value));
    strncpy(v, value, strlen(value)-1);
   if(arg_get_value(preferences, pref))
    arg_set_value(preferences, pref, strlen(v), v);
   else
    arg_add_value(preferences, pref, ARG_STRING, strlen(v), v);
  }
 }
 efree(&input);
 return(0);
}


static void ntp_11_send_prefs_errors(globals)
 struct arglist * globals;
{
 /* not implemented yet */
 auth_printf(globals, "SERVER <|> PREFERENCES_ERRORS <|>\n");
 auth_printf(globals, "<|> SERVER\n");
}



static int ntp_11_rules(globals)
 struct arglist * globals;
{
 char * main_rules = emalloc(10);
 char * buffer;
 int finished = 0;
 
 buffer = emalloc(1024); 
 while(!finished)
 {
  auth_gets(globals, buffer, 1023);
  if(strstr(buffer, "<|> CLIENT"))finished = 1;
  else
   {
    int len;
    char * t, *k;
    buffer[strlen(buffer)-1]=0;
    len = strlen(buffer) + strlen(main_rules) + 1;
    t = emalloc(len);
    sprintf(t, "%s%s", main_rules, buffer);
    k = main_rules;
    main_rules = t;
    efree(&k);
    }
  }
 efree(&buffer);
 buffer = main_rules;
 while((buffer=strchr(buffer, ';')))buffer[0]='\n';
 rules_add(arg_get_value(globals, "rules"), main_rules, 2);
 return(0);
}



static int ntp_11_new_attack(globals, input)
        struct arglist * globals;
	char * input;
	
{
 char * target = emalloc(strlen(input));
 char * clean_target;
 char * plugin_set;
 struct arglist * preferences = arg_get_value(globals, "preferences");
 
 sscanf(input, "CLIENT <|> NEW_ATTACK <|> %s <|> CLIENT\n", target);
 if(!strlen(target)){
  efree(&target);
  return(1);
 }
 clean_target = emalloc(strlen(target)+1);
 strncpy(clean_target, target, strlen(target));
 
 if(!(plugin_set = arg_get_value(preferences, "plugin_set")))
 {
  plugin_set = emalloc(3);
  sprintf(plugin_set, "-1");
 }
 comm_setup_plugins(globals, plugin_set);
 if(arg_get_value(preferences, "TARGET"))
  arg_set_value(preferences, "TARGET", strlen(clean_target), clean_target);
 else
  arg_add_value(preferences, "TARGET", ARG_STRING, strlen(clean_target), clean_target);
 efree(&target);
 return(0);
}
 
