/* Nessuslib -- the Nessus Library
 * Copyright (C) 1998-1999 Renaud Deraison
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Library General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library 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
 * Library General Public License for more details.
 *
 * You should have received a copy of the GNU Library General Public
 * License along with this library; if not, write to the Free
 * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 *
 * Plugutils -- plugin-specific stuff
 */

#define EXPORTING
#include <includes.h>
#include "comm.h"

#ifdef ENABLE_CRYPTO_LAYER
#include "peks.h"
#endif

/* want version stuff */
#include "libvers.h"

ExtFunc
void nessus_lib_version(major, minor, rev)
 int * major, *minor, *rev;
{
 *major = NL_MAJOR;
 *minor = NL_MINOR;
 *rev   = NL_REV;
}

#ifdef ENABLE_CRYPTO_LAYER
ExtFunc
int nessuslib_cipher_enabled()
{
 int enabled = 1;
 return(enabled);
}
#endif

#ifdef USE_PTHREADS
ExtFunc 
int nessuslib_pthreads_enabled()
{
 int enabled = 1;
 return(enabled);
}
#endif

ExtFunc
void plug_set_family(desc, family, language)
 struct arglist * desc; 
 const char * family;
 const char * language;
{
  char * s_language;
  struct arglist * prefs = arg_get_value(desc, "preferences");
  
  s_language = arg_get_value(prefs,"language");
  if(s_language && language)
   {
    if(!strcmp(s_language, language))
    {
    if(family)
    arg_add_value(desc, "FAMILY", ARG_STRING,
    			strlen(family), estrdup(family));
    }
   }
  else if(family)
    {
     if(!arg_get_value(desc, "FAMILY"))
      arg_add_value(desc, "FAMILY", ARG_STRING,
    			strlen(family), estrdup(family));
    }
}

ExtFunc
void plug_require_key(desc, keyname)
 struct arglist * desc;
 const char * keyname;
{
 struct arglist * keys;
 if(keyname)
 {
  keys = arg_get_value(desc, "required_keys");
  if(!keys)
  {
   keys = emalloc(sizeof(struct arglist));
   arg_add_value(desc, "required_keys", ARG_ARGLIST, -1, keys);
  }
  arg_add_value(keys, "key", ARG_STRING, strlen(keyname), strdup(keyname));
 }
}

ExtFunc
void plug_exclude_key(desc, keyname)
 struct arglist * desc;
 const char * keyname;
{
 struct arglist * keys;
 if(keyname)
 {
  keys = arg_get_value(desc, "excluded_keys");
  if(!keys)
  {
   keys = emalloc(sizeof(struct arglist));
   arg_add_value(desc, "excluded_keys", ARG_ARGLIST, -1, keys);
  }
  arg_add_value(keys, "key", ARG_STRING, strlen(keyname), strdup(keyname));
 }
}


ExtFunc 
void plug_require_port(desc, portname)
 struct arglist * desc;
 const char * portname;
{
 struct arglist * ports;
 int iport = atoi(portname);
 
 if(portname)
 {
  ports = arg_get_value(desc, "required_ports");
  if(!ports)
  {
   ports = emalloc(sizeof(struct arglist));
   arg_add_value(desc, "required_ports", ARG_ARGLIST, -1, ports);
  }
  

  if(iport)
   arg_add_value(ports, portname, ARG_INT, sizeof(iport), (char*)iport);
  else 
   arg_add_value(ports, portname, ARG_STRING, strlen(portname), strdup(portname));

 }
}
 


ExtFunc
void plug_set_dep(desc, depname)
 struct arglist * desc;
 const char * depname;
{
 struct arglist * deps;
 if(depname)
 {
  deps = arg_get_value(desc, "DEPENDENCIES");
  if(!deps){
   deps = emalloc(sizeof(struct arglist));
   arg_add_value(desc, "DEPENDENCIES", ARG_ARGLIST, -1, deps);
   }
  arg_add_value(deps, estrdup(depname), ARG_STRING, 0, "");
 }
}
ExtFunc
void plug_set_timeout(desc, timeout)
 struct arglist * desc; 
 int timeout;
{
    arg_add_value(desc, "TIMEOUT", ARG_INT,
    			sizeof(int), (void *)timeout);
}


ExtFunc
const char * plug_get_family(desc)
 struct arglist * desc;
{
 return(arg_get_value(desc, "FAMILY"));
}
		

ExtFunc
void plug_set_launch(desc, launch)
 struct arglist * desc;
 int launch;
{
  if(arg_set_value(desc, "ENABLED", sizeof(int), (void *)launch))
  {
   arg_add_value(desc, "ENABLED", ARG_INT, sizeof(int), (void *)launch);
  }
}


ExtFunc
int plug_get_launch(desc)
 struct arglist * desc;
{
 return((int)arg_get_value(desc, "ENABLED"));
}	
	
	
ExtFunc
void plug_set_name(desc, name, language)
 struct arglist * desc; 
 const char * name; 
 const char * language;
{
 char * s_language;
 struct arglist * prefs = arg_get_value(desc, "preferences");
  
  s_language = arg_get_value(prefs,"language");
  if(s_language && language)
   {
    if(!strcmp(s_language, language))
    {
    if(name)
    arg_add_value(desc, "NAME", ARG_STRING,
    			strlen(name), estrdup(name));
    }
   }
  else if(name)
  {
    if(!arg_get_value(desc, "NAME"))
    	arg_add_value(desc, "NAME", ARG_STRING,
    			strlen(name), estrdup(name));	
  }
}


ExtFunc
void plug_set_summary(desc, summary,language)
 struct arglist * desc;
 const char * summary;
 const char * language;
{
 char * s_language;
 struct arglist * prefs = arg_get_value(desc, "preferences");
  
  s_language = arg_get_value(prefs,"language");
  if(s_language && language)
   {
    if(!strcmp(s_language, language))
    {
    if(summary)
    arg_add_value(desc, "SUMMARY", ARG_STRING,
    			strlen(summary), estrdup(summary));
    }
   }
  else if(summary)
  {
    if(!arg_get_value(desc, "SUMMARY"))
    	arg_add_value(desc, "SUMMARY", ARG_STRING,
    			strlen(summary), estrdup(summary));	
  }
}


ExtFunc
void plug_set_description(desc, description,language)
 struct arglist * desc;
 const char * description;
 const char * language;
{
  char * s_language;
 struct arglist * prefs = arg_get_value(desc, "preferences");
  
  s_language = arg_get_value(prefs,"language");
  if(s_language && language)
   {
    if(!strcmp(s_language, language))
    {
    if(description)
    arg_add_value(desc, "DESCRIPTION", ARG_STRING,
    			strlen(description), estrdup(description));
    }
   }
  else if(description)
  {
    if(!arg_get_value(desc, "DESCRIPTION"))
    	arg_add_value(desc, "DESCRIPTION", ARG_STRING,
    			strlen(description), estrdup(description));	
  }
}


ExtFunc
void plug_set_copyright(desc, copyright,language)
 struct arglist * desc;
 const char * copyright;
 const char * language;
{
 char * s_language;
 struct arglist * prefs = arg_get_value(desc, "preferences");
  
  s_language = arg_get_value(prefs,"language");
  if(s_language && language)
   {
    if(!strcmp(s_language, language))
    {
    if(copyright)
    arg_add_value(desc, "COPYRIGHT", ARG_STRING,
    			strlen(copyright), estrdup(copyright));
    }
   }
  else if(copyright)
  {
    if(!arg_get_value(desc, "COPYRIGHT"))
    	arg_add_value(desc, "COPYRIGHT", ARG_STRING,
    			strlen(copyright), estrdup(copyright));	
  }
}


ExtFunc
void plug_set_category(desc, category)
 struct arglist * desc;
 int category;
{
       arg_add_value(desc, "CATEGORY", ARG_INT, sizeof(int), (void *)category);
}


ExtFunc
void plug_set_attacklevel(desc, attacklevel)
 struct arglist * desc;
 int attacklevel;
{
	arg_add_value(desc, "ATTACKLEVEL", ARG_INT, sizeof(int), (void *)attacklevel);
}


ExtFunc
void plug_add_host(desc, hostname)
 struct arglist * desc;
 struct arglist * hostname;
{
	struct arglist * h;
	
	h = arg_get_value(desc, "HOSTNAME");
	if(!h)arg_add_value(desc, "HOSTNAME", ARG_ARGLIST, sizeof(hostname), hostname);
	else arg_set_value(desc, "HOSTNAME", sizeof(hostname), hostname);
}


ExtFunc
void host_add_port_proto(args, portnum, state, proto)
 struct arglist * args;
 int portnum;
 int state;
 char * proto;
{
 char * port_s = emalloc(20+strlen(proto));
 sprintf(port_s, "Ports/%s/%d", proto, portnum);
 plug_set_key(args, port_s, ARG_INT, (void*)1);
 free(port_s);
}


ExtFunc
void host_add_port(hostdata, portnum, state)
 struct arglist * hostdata;
 int portnum;
 int state;
{
 host_add_port_proto(hostdata, portnum, state, "tcp");
}

ExtFunc
void host_add_port_udp(hostdata, portnum, state)
 struct arglist * hostdata;
 int portnum;
 int state;
{
 host_add_port_proto(hostdata, portnum, state, estrdup("udp"));
}
  

int port_in_ports(port, ports, s, e)
	u_short port, * ports;
	int s, e;
{
 int mid = (s+e)/2;
 if(s==e)return(port == ports[e]);
 if(port > ports[mid])return(port_in_ports(port, ports, mid+1, e));
 else return(port_in_ports(port, ports, s, mid));
}
 	

ExtFunc
int host_get_port_state_proto(plugdata, portnum, proto)
 struct arglist * plugdata;
 int portnum;
 char * proto;
{ 
 struct arglist * hostdata = arg_get_value(plugdata, "HOSTNAME");
 struct arglist * ports;
 char * port_s;
 unsigned short * range;
 int i,flag;
 int num;


 /* Check that we actually scanned the port */
 if(!plug_get_key(plugdata, "Host/scanned")){
#ifdef DEBUG
	printf("HOST NOT SCANNED\n");
#endif
	return(1);
	}
 range = arg_get_value(plugdata, "ports");
 if(!range){
#ifdef DEBUG
	printf("unknown port range\n");
#endif	
 	return(1);
	}
 num = (int)arg_get_value(plugdata, "ports_num");
 if(!port_in_ports(portnum, range, 0, num)){
#ifdef DEBUG
	printf("!port_in_ports\n");
#endif	
       return(1);
       }
 

 /* Ok, we scanned it. What is its state ? */
 port_s = emalloc(20+strlen(proto));
 sprintf(port_s, "Ports/%s/%d", proto, portnum);
 flag = (int)plug_get_key(plugdata, port_s);
 free(port_s);
#ifdef DEBUG
 printf("%d -> %d\n", portnum, flag);
#endif
 return(flag ? 1:0);
}


ExtFunc
int host_get_port_state(plugdata, portnum)
 struct arglist * plugdata;
 int portnum;
{
 return(host_get_port_state_proto(plugdata, portnum, "tcp"));
}

ExtFunc
int host_get_port_state_udp(plugdata, portnum)
 struct arglist * plugdata;
 int portnum;
{
 return(host_get_port_state_proto(plugdata, portnum, "udp"));
}


ExtFunc
const char * plug_get_hostname(desc)
 struct arglist * desc;
{
 struct arglist * hinfos = arg_get_value(desc, "HOSTNAME");
 if(hinfos)return((char*)arg_get_value(hinfos, "FQDN"));
 else return(NULL);
}


ExtFunc
struct in_addr * plug_get_host_ip(desc)
 struct arglist * desc;
{
 struct arglist * hinfos = arg_get_value(desc, "HOSTNAME");
 if(hinfos)return((struct in_addr*)arg_get_value(hinfos, "IP"));
 else return(NULL);
}


ExtFunc
void proto_post_hole(desc, port, proto, action)
 struct arglist * desc;
 int port;
 const char * proto;
 const char * action;
{

 char *t;
 char * buffer;
 int soc;
 struct arglist * globs;
 register struct arglist * hostdata;
 char c;
 char * naction;
 int len;
 ntp_caps* caps = arg_get_value(desc, "NTP_CAPS");
 
 
 if(!action)
 {
  action = arg_get_value(desc, "DESCRIPTION");
 }
 if(!action)return;
 len = strlen(action);
 c = (char)13;
 
 if(!caps)return;
 hostdata = arg_get_value(desc, "HOSTNAME");
 naction = emalloc(len+1);
 strncpy(naction, action, len);
 while((t=strchr(naction, '\n'))||(t=strchr(naction, c)))t[0]=';';
 buffer=malloc(1024+len);
 if(caps->ntp_11) {
   struct servent * service = NULL;
   char idbuffer[32];
   service = getservbyport(htons((unsigned short)port), proto);
#ifndef NESSUSNT
   endservent();
#endif
   if (caps->scan_ids) {
     /* XXX
      * This check can later be removed when we can trust in the ID being
      * present. It is mainly because I'm not sufficiently used to the
      * Nessus sources.
      *
      * 29.01.1999, Jochen Wiedmann
      */
     if (arg_get_type(desc, "ID") == -1) {
       *idbuffer = '\0';
     } else {
       int id = (int)arg_get_value(desc, "ID");
       sprintf(idbuffer, "<|> %d ", id);
     }
   } else {
     *idbuffer = '\0';
 }
  if(port>0){
      char * asc_port = malloc(20);
     sprintf(buffer,
	     "SERVER <|> HOLE <|> %s <|> %s (%d/%s) <|> %s %s<|> SERVER\n",
  	(char *)arg_get_value(hostdata, "FQDN"),
        service ? service->s_name:"unknown",
	     port, proto, naction, idbuffer);
    
   } else
     sprintf(buffer,
	     "SERVER <|> HOLE <|> %s <|> general/%s <|> %s %s<|> SERVER\n",
  	(char *)arg_get_value(hostdata, "FQDN"), 
	     proto, naction, idbuffer);
 } else {
   sprintf(buffer, "SERVER <|> HOLE <|> %s <|> %d:%s <|> SERVER\n", 
	   (char *)arg_get_value(hostdata, "FQDN"), port, naction);
 }
 soc = (int)arg_get_value(desc, "SOCKET");
 globs = emalloc(sizeof(struct arglist));
 arg_add_value(globs, "global_socket", ARG_INT, sizeof(int), (void *)soc);
 auth_send(globs, buffer);
 efree(&buffer);
 arg_free_all(globs);
 efree(&naction);
 return;
}


ExtFunc
void post_hole(desc, port, action)
 struct arglist * desc;
 int port;
 const char * action;
{
  proto_post_hole(desc, port, "tcp", action);
} 


ExtFunc
void post_hole_udp(desc, port, action)
 struct arglist * desc;
 int port;
 const char * action;
{
 proto_post_hole(desc, port, "udp", action);
}


ExtFunc
void post_info(desc, port, action)
 struct arglist * desc;
 int port;
 const char * action;
{
  proto_post_info(desc, port, "tcp", action);
} 


ExtFunc
void post_info_udp(desc, port, action)
 struct arglist * desc;
 int port;
 const char * action;
{
 proto_post_info(desc, port, "udp", action);
}


ExtFunc
void proto_post_info(desc, port, proto, action)
 struct arglist * desc;
 int port;
 const char * proto;
 const char * action;
{
 char *t;
 char * buffer;
 int soc;
 register struct arglist * hostdata;
 char c;
 char * naction;
 struct arglist * globs;
 int len;
 ntp_caps* caps = arg_get_value(desc, "NTP_CAPS");
 

 c = (char)13;
 if(!caps)return;
 hostdata = arg_get_value(desc, "HOSTNAME");
 if(!action)
 {
  action = arg_get_value(desc, "DESCRIPTION");
 }
 if(!action)return;
 len = strlen(action);
 
 naction = emalloc(len+1);
 strncpy(naction, action, len);
 while((t=strchr(naction, '\n'))||(t=strchr(naction, c)))t[0]=';';
 buffer=malloc(1024+len);
 if(caps->ntp_11) {
  struct servent * service = NULL;
   char idbuffer[32];
   if (caps->scan_ids) {
     /* XXX
      * This check can later be removed when we can trust in the ID being
      * present. It is mainly because I'm not sufficiently used to the
      * Nessus sources.
      *
      * 29.01.1999, Jochen Wiedmann
      */
     if (arg_get_type(desc, "ID") == -1) {
       *idbuffer = '\0';
     } else {
       int id = (int)arg_get_value(desc, "ID");
       sprintf(idbuffer, "<|> %d ", id);
     }
   } else {
     *idbuffer = '\0';
   }
  if(port>0){
        char * asc_port = malloc(20);
     
  	service = getservbyport(htons((unsigned short)port), proto);
#ifndef NESSUSNT
	endservent();
#endif
        sprintf(buffer,
	     "SERVER <|> INFO <|> %s <|> %s (%d/%s) <|> %s %s<|> SERVER\n",
  	(char *)arg_get_value(hostdata, "FQDN"),
        service ? service->s_name:"unknown",
	     port, proto, naction, idbuffer);
	   
   } else
     sprintf(buffer,
	     "SERVER <|> INFO <|> %s <|> general/%s <|> %s %s<|> SERVER\n",
	     (char *)arg_get_value(hostdata, "FQDN"), proto, naction,
	     idbuffer);
 } else {
   sprintf(buffer, "SERVER <|> INFO <|> %s <|> %d:%s <|> SERVER\n", 
	   (char *)arg_get_value(hostdata, "FQDN"), port, naction);
 }
 soc = (int)arg_get_value(desc, "SOCKET");
 globs = emalloc(sizeof(struct arglist));
 arg_add_value(globs, "global_socket", ARG_INT, sizeof(int), (void *)soc);

 auth_send(globs, buffer);
 efree(&buffer);
 arg_free_all (globs);
 /* efree(&globs); */
 efree(&naction);
 return;
} 


ExtFunc
void l_post_hole(desc, port, action)
 struct arglist * desc;
 const char * port;
 const char * action;
{
 struct arglist * ports;
 struct arglist * pport;
 struct arglist * report;
 char * comm;
 
 if(!action)return;
 comm = emalloc(strlen(action)+1);
 strncpy(comm, action, strlen(action));
 ports = arg_get_value(desc, "PORTS");
 if(!ports)
 {
  ports = emalloc(sizeof(struct arglist));
  arg_add_value(desc, "PORTS", ARG_ARGLIST, -1, ports);
 }
 pport = arg_get_value(ports, port);
 
 if(!pport){
 	pport = emalloc(sizeof(struct arglist));
 	arg_add_value(ports, port, ARG_ARGLIST, -1, pport);
 	arg_add_value(pport, "STATE", ARG_INT, sizeof(int),(void *)1);
 	}
 report = arg_get_value(pport, "REPORT");
 if(!report)
 {
  report = emalloc(sizeof(struct arglist));
  arg_add_value(pport, "REPORT", ARG_ARGLIST, -1, report);
 }
 while(report && report->next)report = report->next;
 arg_add_value(report, "HOLE", ARG_STRING, strlen(comm), comm);
 return;
} 


ExtFunc
void l_post_info(desc, port, action)
 struct arglist * desc;
 const char * port;
 const char * action;
{
 struct arglist * ports;
 struct arglist * pport;
 struct arglist * report;
 char * comm;
 
 if(!action)return;
 comm = emalloc(strlen(action)+1);
 strncpy(comm, action, strlen(action));
 ports = arg_get_value(desc, "PORTS");
 if(!ports)
 {
  ports = emalloc(sizeof(struct arglist));
  arg_add_value(desc, "PORTS", ARG_ARGLIST, -1, ports);
 }
 pport = arg_get_value(ports, port);
 
 if(!pport){
 	pport = emalloc(sizeof(struct arglist));
 	arg_add_value(ports, port, ARG_ARGLIST, -1, pport);
 	arg_add_value(pport, "STATE", ARG_INT, sizeof(int),(void *)1);
 	}
 report = arg_get_value(pport, "INFO");
 if(!report)
 {
  report = emalloc(sizeof(struct arglist));
  arg_add_value(pport, "INFO", ARG_ARGLIST, -1, report);
 }
 while(report && report->next)report = report->next;
 arg_add_value(report, "INFO", ARG_STRING, strlen(comm), comm);
 return;
} 
 
 
ExtFunc
char * get_preference(desc, name)
 struct arglist *desc;
 const char * name;
{
 struct arglist * prefs;
 prefs = arg_get_value(desc, "preferences");
 if(!prefs)return(NULL);
 return((char *)arg_get_value(prefs, name));
}


ExtFunc
void add_plugin_preference(desc, name, type, defaul)
 struct arglist *desc;
 const char * name;
 const char * type;
 const char * defaul;
{
 struct arglist * prefs = arg_get_value(desc, "preferences");
 char * p_name = arg_get_value(desc, "NAME");
 char * pref;
 
 if(!prefs || !p_name)return;
 pref = emalloc(strlen(p_name)+10+strlen(type)+strlen(name));
 sprintf(pref, "%s[%s]:%s", p_name, type, name);
 arg_add_value(prefs, pref, ARG_STRING, strlen(defaul), estrdup(defaul));
 efree(&pref);
}


ExtFunc
char * get_plugin_preference(desc, name)
  struct arglist * desc;
  const char * name;
{
 struct arglist * prefs = arg_get_value(desc, "preferences");
 char * plug_name = arg_get_value(desc, "NAME");
 while(prefs && prefs->next)
 {
  char * a= NULL, *b = NULL;
  int c = 0;
  char * t = estrdup(prefs->name);
  
  a = strchr(t, '[');
  if(a)b=strchr(t, ']');
  if(b)c=(b[1]==':');
  
  if(c)
  {
   b+=2*sizeof(char);
   if(!strcmp(name, b)){
   	a[0] = 0;
	if(!strcmp(t, plug_name)){
		efree(&t);
		return(prefs->value);
		}
	}
  }
  efree(&t);
  prefs = prefs->next;
 }
 return(NULL);
}


ExtFunc
void plug_set_key(args, name, type, value)
 struct arglist * args;
 char * name;
 int type;
 void * value;
{
 int pip = (int)arg_get_value(args, "pipe");
 char * str = NULL;
#ifdef DEBUG
 printf("set key %s -> %d\n", name, value);
#endif 
 
 if(!name || !value)return;
 switch(type)
 {
  case ARG_STRING :
   str = emalloc(strlen(name)+strlen(value)+10);
   sprintf(str, "%d %s=%s;\n", ARG_STRING, name, (char *)value);
   break;
  case ARG_INT :
   str = emalloc(strlen(name)+20);
   sprintf(str, "%d %s=%d;\n", ARG_STRING, name, (int)value);
   break;
#ifdef NOT_IMPLEMENTED_YET
  case ARG_ARGLIST :
   {
    struct arglist * t = (struct arglist *)value;
    str = emalloc(20+strlen(name));
    sprintf(str, "%d %s/START_AL\n", type, name);
    write(pip, str, strlen(str));
    while(t && t->next){
    	plug_set_key(args, t->name, t->type, t->value);
        t = t->next;
        }
    sprintf(str, "%d %s/END_AL\n",type, name);
   }
   break;
#endif
 }
 if(str)
 {
   int len = strlen(str);
   int sent = 0;
   
   while(sent < len)
   {
    sent += send(pip, str+sent, len+1, 0);
    if(sent < 0){
    	perror("send ");
	return;
	}
   }
  }
} 



ExtFunc void
scanner_add_port(args, port, proto)
 struct arglist * args;
 int port;
 char * proto;
{
 ntp_caps* caps = arg_get_value(args, "NTP_CAPS");
 struct arglist * hostdata = arg_get_value(args, "HOSTNAME");
 char * buf;
 struct servent * serv = getservbyport(htons(port), proto);
 char * hn = arg_get_value(hostdata, "FQDN");
 int len;
 int soc;
 struct arglist * globs;
 
 
 
 host_add_port(args, port, 1);
 
 len = 255 + (hn ? strlen(hn):0) + 
 	    (serv ?strlen(serv->s_name):strlen("unknown"));
 buf = emalloc(len);
 if(caps->ntp_11)
  sprintf(buf, "SERVER <|> PORT <|> %s <|> %s (%d/%s) <|> SERVER\n",
 		hn,serv ? serv->s_name:"unknown",
		port, proto);
 else
  {
   if(!strcmp(proto, "tcp"))
     sprintf(buf, "SERVER <|> PORT <|> %s <|> %d <|> SERVER\n",
  		hn, port);
  }
   
 soc = (int)arg_get_value(args, "SOCKET");
 globs = emalloc(sizeof(struct arglist));
 arg_add_value(globs, "global_socket", ARG_INT, sizeof(int), (void *)soc);
 
 auth_send(globs, buf);
 free(buf);
 arg_free(globs);
}



void * plug_get_key(args, name)
 struct arglist * args;
 char * name;
{
 struct arglist * key = (struct arglist *)arg_get_value(args, "key");
 if(!key)return(NULL);
 return(arg_get_value(key, name));
}

ExtFunc unsigned int 
plug_get_host_open_port(struct arglist * desc)
{
 int soc;
 struct arglist * h = arg_get_value(desc, "key");
 char * str = "Ports/tcp/";
 char * t;
 int port = 0;
 
 while(h && h->next)
 {
  if((strlen(h->name) > strlen(str)) && 
     !strncmp(h->name, str, strlen(str))){
     	t = h->name + strlen(str);
	port = atoi(t);
	break;
	}
  h = h->next;	
 }
 
 return(port);
}
       
 

