/**
 * @brief Convert a string into an ISO time string.
 * @naslfn{isotime_scan}
 *
 *
 * @nasluparam
 *
 * - A string
 *
 * @naslret A ISO time string on success or NULL on error.
 *
 * @param[in] lexic  Lexical context of the NASL interpreter.
 *
 * @return A tree cell.
 */
tree_cell *
nasl_isotime_scan (lex_ctxt *lexic)
{
  tree_cell *retc;
  my_isotime_t timebuf;
  int datalen;
  const char *string;

  *timebuf = 0;
  string = get_str_var_by_num (lexic, 0);
  if (!string)
    return NULL;
  switch (get_var_type_by_num (lexic, 0))
    {
    case VAR2_DATA:
      datalen = get_var_size_by_num (lexic, 0);
      if (datalen < ISOTIME_SIZE - 1)
        return NULL; /* Too short */
      memcpy (timebuf, string, ISOTIME_SIZE - 1);
      timebuf[ISOTIME_SIZE - 1] = 0;
      string = timebuf;
      /* FALLTHRU */
    case VAR2_STRING:
      if (!string2isotime (timebuf, string))
        return NULL;
      break;
    default:
      return NULL;
    }

  retc = alloc_typed_cell (CONST_STR);
  retc->x.str_val = estrdup (timebuf);
  retc->size = strlen (timebuf);
  return retc;
}
/**
 * @brief Check whether an ISO time string is valid
 * @naslfn{isotime_is_valid}
 *
 *
 * @nasluparam
 *
 * - A string.  Both, the standard 15 byte string and the better human
 *   readable up to 19 byte format are accepted here.  If a plain data
 *   type is is provided only the 15 byte format is accepted.
 *
 * @naslret True is this is an ISO string; false if not.
 *
 * @param[in] lexic  Lexical context of the NASL interpreter.
 *
 * @return A tree cell.
 */
tree_cell *
nasl_isotime_is_valid (lex_ctxt *lexic)
{
  int result = 0;
  tree_cell *retc;
  my_isotime_t timebuf;
  const char *string;
  int datalen;

  string = get_str_var_by_num (lexic, 0);
  if (string)
    {
      switch (get_var_type_by_num (lexic, 0))
        {
        case VAR2_DATA:
          datalen = get_var_size_by_num (lexic, 0);
          if (datalen < ISOTIME_SIZE - 1)
            break; /* Too short */
          memcpy (timebuf, string, ISOTIME_SIZE - 1);
          timebuf[ISOTIME_SIZE -1] = 0;
          string = timebuf;
          /* FALLTHRU */
        case VAR2_STRING:
          if (isotime_p (string) || isotime_human_p (string))
            result = 1;
          break;
        default:
          break;
        }
    }

  retc = alloc_typed_cell (CONST_INT);
  retc->x.i_val = result;
  return retc;
}
Example #3
0
tree_cell* nasl_isnull(lex_ctxt* lexic)
{
  int		t;
  tree_cell	*retc;

  t = get_var_type_by_num(lexic, 0);
  retc = alloc_tree_cell(0, NULL);
  retc->type = CONST_INT;
  retc->x.i_val = (t == VAR2_UNDEF);
  return retc;
}
Example #4
0
tree_cell*
nasl_func_has_arg(lex_ctxt* lexic)
{
  nasl_func	*f; 
  char		*s;
  int		vt, i, flag = 0;
  tree_cell	*retc;


  s = get_str_var_by_num(lexic, 0);
  if (s == NULL)
    {
      nasl_perror(lexic, "func_has_arg: missing parameter\n");
      return NULL;
    }

  f = get_func_ref_by_name(lexic, s);
  if (f == NULL)
    {
      nasl_perror(lexic, "func_args: unknown function \"%s\"\n", s);
      return NULL;
    }

  vt = get_var_type_by_num(lexic, 1);
  switch(vt)
    {
    case VAR2_INT:
      i = get_int_var_by_num(lexic, 1, -1);
      if (i >= 0 &&  i < f->nb_unnamed_args)
	flag = 1;
      break;

    case VAR2_STRING:
    case VAR2_DATA:
      s = get_str_var_by_num(lexic, 1);
      for (i = 0; i < f->nb_named_args && ! flag; i ++)
	if (strcmp(s, f->args_names[i]) == 0)
	  flag = 1;
      break;

    default:
      nasl_perror(lexic, "func_has_arg: string or integer expected as 2nd parameter\n");
      return NULL;
    }

  retc = alloc_typed_cell(CONST_INT);
  retc->x.i_val = flag;
  return retc;
}
/*
 * Syntax: substr(s, i1) or substr(s, i1, i2)
 * Returns character from string s starting for position i1 till the end or
 * position i2 (start of string is 0)
 */
tree_cell* nasl_substr(lex_ctxt* lexic)
{
  char		*s1;
  int		sz1, sz2, i1, i2, typ;
  tree_cell	*retc;

  s1 = get_str_var_by_num(lexic, 0);
  sz1 = get_var_size_by_num(lexic, 0);
  typ = get_var_type_by_num(lexic, 0);
  i1 = get_int_var_by_num(lexic, 1, -1);
#ifndef MAX_INT
#define MAX_INT (~(1 << (sizeof(int) * 8 - 1)))
#endif
  i2 = get_int_var_by_num(lexic, 2, MAX_INT);
  if (i2 > sz1) i2 = sz1-1;

  if (s1 == NULL || i1 < 0)
    {
      nasl_perror(lexic, "Usage: substr(string, idx_start [,idx_end])\n");
      return NULL;
    }

  retc = alloc_tree_cell(0, NULL);
  retc->type = (typ == CONST_STR ? CONST_STR : CONST_DATA);
  if (i1 > i2)
    {
      retc->x.str_val = emalloc(0);
      retc->size = 0;
      return retc;
    }
  sz2 = i2 - i1 + 1;
  retc->size = sz2;
  retc->x.str_val = emalloc(sz2);
  memcpy(retc->x.str_val, s1 + i1, sz2);
  return retc;
}
/**
 * @brief Get info pertaining to a socket.
 * @naslfn{get_sock_info}
 *
 * This function is used to retrieve various information about an
 * active socket.  It requires the NASL socket number and a string to
 * select the information to retrieve.
 *
 * Supported keywords are:
 *
 * - @a dport Return the destination port.  This is an integer.  NOTE:
 *   Not yet implemented.
 *
 * - @a sport Return the source port.  This is an integer.  NOTE: Not
 *   yet implemented.
 *
 * - @a encaps Return the encapsulation of the socket.  Example
 *   output: "TLScustom".
 *
 * - @a tls-proto Return a string with the actual TLS protocol in use.
 *   n/a" is returned if no SSL/TLS session is active.  Example
 *   output: "TLSv1".
 *
 * - @a tls-kx Return a string describing the key exchange algorithm.
 *   Example output: "RSA".
 *
 * - @a tls-certtype Return the type of the certificate in use by the
 *   session.  Example output: "X.509"
 *
 * - @a tls-cipher Return the cipher algorithm in use by the session;
 *   Example output: "AES-256-CBC".
 *
 * - @a tls-mac Return the message authentication algorithms used by
 *   the session.  Example output: "SHA1".
 *
 * - @a tls-comp Return the compression algorithms in use by the
 *   session.  Example output: "DEFLATE".
 *
 * - @a tls-auth Return the peer's authentication type.  Example
 *   output: "CERT".
 *
 * - @a tls-cert Return the peer's certificates for an SSL or TLS
 *   connection.  This is an array of binary strings or NULL if no
 *   certificate is known.
 *
 * @nasluparam
 *
 * - A NASL socket
 *
 * - A string keyword; see above.
 *
 * @naslnparam
 *
 * - @a asstring If true return a human readable string instead of
 *   an integer.  Used only with these keywords: encaps.
 *
 * @naslret An integer or a string or NULL on error.
 *
 * @param[in] lexic  Lexical context of the NASL interpreter.
 *
 * @return A tree cell.
 */
tree_cell *
nasl_get_sock_info (lex_ctxt * lexic)
{
  int sock;
  int type;
  int err;
  const char *keyword, *s;
  tree_cell *retc;
  int as_string;
  int transport;
  gnutls_session_t tls_session;
  char *strval;
  int intval;

  sock = get_int_var_by_num (lexic, 0, -1);
  if (sock <= 0)
    {
      nasl_perror (lexic, "error: socket %d is not valid\n");
      return NULL;
    }

  keyword = get_str_var_by_num (lexic, 1);
  if (!keyword || !((type = get_var_type_by_num (lexic, 1)) == VAR2_STRING
                    || type == VAR2_DATA))
    {
      nasl_perror (lexic, "error: second argument is not of type string\n");
      return NULL;
    }

  as_string = !!get_int_local_var_by_name (lexic, "asstring", 0);

  transport = 0;
  strval = NULL;
  intval = 0;
  retc = FAKE_CELL; /* Dummy value to detect retc == NULL.  */

  {
    void *tmp = NULL;
    err = get_sock_infos (sock, &transport, &tmp);
    tls_session = tmp;
  }
  if (err)
    {
      nasl_perror (lexic, "error retrieving infos for socket %d: %s\n",
                   sock, strerror (err));
      retc = NULL;
    }
  else if (!strcmp (keyword, "encaps"))
    {
      if (as_string)
        strval = estrdup (get_encaps_name (transport));
      else
        intval = transport;
    }
  else if (!strcmp (keyword, "tls-proto"))
    {
      if (!tls_session)
        s = "n/a";
      else
        s = gnutls_protocol_get_name
          (gnutls_protocol_get_version (tls_session));
      strval = estrdup (s?s:"[?]");
    }
  else if (!strcmp (keyword, "tls-kx"))
    {
      if (!tls_session)
        s = "n/a";
      else
        s = gnutls_kx_get_name (gnutls_kx_get (tls_session));
      strval = estrdup (s?s:"");
    }
  else if (!strcmp (keyword, "tls-certtype"))
    {
      if (!tls_session)
        s = "n/a";
      else
        s = gnutls_certificate_type_get_name
          (gnutls_certificate_type_get (tls_session));
      strval = estrdup (s?s:"");
    }
  else if (!strcmp (keyword, "tls-cipher"))
    {
      if (!tls_session)
        s = "n/a";
      else
        s = gnutls_cipher_get_name (gnutls_cipher_get (tls_session));
      strval = estrdup (s?s:"");
    }
  else if (!strcmp (keyword, "tls-mac"))
    {
      if (!tls_session)
        s = "n/a";
      else
        s = gnutls_mac_get_name (gnutls_mac_get (tls_session));
      strval = estrdup (s?s:"");
    }
  else if (!strcmp (keyword, "tls-comp"))
    {
      if (!tls_session)
        s = "n/a";
      else
        s = gnutls_compression_get_name
          (gnutls_compression_get (tls_session));
      strval = estrdup (s?s:"");
    }
  else if (!strcmp (keyword, "tls-auth"))
    {
      if (!tls_session)
        s = "n/a";
      else
        {
          switch (gnutls_auth_get_type (tls_session))
            {
            case GNUTLS_CRD_ANON:        s = "ANON"; break;
            case GNUTLS_CRD_CERTIFICATE: s = "CERT"; break;
            case GNUTLS_CRD_PSK:         s = "PSK";  break;
            case GNUTLS_CRD_SRP:         s = "SRP";  break;
            default:                     s = "[?]";  break;
            }
        }
      strval = estrdup (s?s:"");
    }
  else if (!strcmp (keyword, "tls-cert"))
    {
      /* We only support X.509 for now.  GNUTLS also allows for
         OpenPGP, but we are not prepared for that.  */
      if (!tls_session
          || gnutls_certificate_type_get (tls_session) != GNUTLS_CRT_X509)
        s = "n/a";
      else
        {
          const gnutls_datum_t *list;
          unsigned int nlist = 0;
          int i;
          nasl_array *a;
          anon_nasl_var v;

          list = gnutls_certificate_get_peers (tls_session, &nlist);
          if (!list)
            retc = NULL;  /* No certificate or other error.  */
          else
            {
              retc = alloc_tree_cell (0, NULL);
              retc->type = DYN_ARRAY;
              retc->x.ref_val = a = emalloc (sizeof *a);

              for (i=0; i < nlist; i++)
                {
                  memset (&v, 0, sizeof v);
                  v.var_type = VAR2_DATA;
                  v.v.v_str.s_val = list[i].data;
                  v.v.v_str.s_siz = list[i].size;
                  add_var_to_list (a, i, &v);
                }
            }
        }
    }
  else
    {
      nasl_perror (lexic, "unknown keyword '%s'\n", keyword);
      retc = NULL;
    }

  if (!retc)
    ;
  else if (retc != FAKE_CELL)
    ; /* Already allocated.  */
  else if (strval)
    {
      retc = alloc_typed_cell (CONST_STR);
      retc->x.str_val = strval;
      retc->size = strlen (strval);
    }
  else
    {
      retc = alloc_typed_cell (CONST_INT);
      retc->x.i_val = intval;
    }

  return retc;
}
tree_cell* nasl_string(lex_ctxt* lexic)
{
  tree_cell	*retc;
  int		vi, vn, newlen;
  int		sz, typ;
  const char	*s, *p1;
  char		*p2;


  retc = alloc_tree_cell(0, NULL);
  retc->type = CONST_DATA;
  retc->size = 0;
  retc->x.str_val = emalloc(0);

  vn = array_max_index(&lexic->ctx_vars);
  for (vi = 0; vi < vn; vi ++)
    {
      if ((typ = get_var_type_by_num(lexic, vi)) == VAR2_UNDEF)
	continue;
      s = get_str_var_by_num(lexic, vi);
      sz = get_var_size_by_num(lexic, vi);
      if (sz <= 0)
	sz = strlen(s);

      newlen = retc->size + sz;
      retc->x.str_val = erealloc(retc->x.str_val, newlen + 1);
      p2 = retc->x.str_val + retc->size;
      p1 = s;
      retc->size = newlen;
      if (typ != VAR2_STRING)
	{
	  memcpy(p2, p1, sz);
	  p2[sz] = '\0';
	}
      else
	while (*p1 != '\0')
	  {
	    if(*p1 == '\\' && p1[1] != '\0')
	      {
		switch (p1[1])
		  {
		  case 'n':
		    *p2 ++ = '\n';
		    break;
		  case 't':
		    *p2 ++ = '\t';
		    break;
		  case 'r':
		    *p2++ = '\r';
		    break;
		  case '\\':
		    *p2++ = '\\';
		    break;
		  case 'x':
		    if (isxdigit(p1[2]) && isxdigit(p1[3]))
		      {
			*p2++ = 
			  16 *
			  (isdigit(p1[2]) ? p1[2]-'0' : 10+tolower(p1[2])-'a')
			  +
			  (isdigit(p1[3]) ? p1[3]-'0' : 10+tolower(p1[3])-'a');
			p1 += 2;
			retc->size -= 2;
		      }
		    else
		      {
			nasl_perror(lexic, "Buggy hex value '\\x%c%c' skipped\n",
				isprint(p1[2]) ? p1[2] : '.',
				isprint(p1[3]) ? p1[3] : '.' );
			/* We do not increment p1 by  4,
			   we may miss the end of the string */
		      }
		    break;
		  default:
		    	nasl_perror(lexic, "Unknown%d escape sequence '\\%c'\n", getpid(),
			    isprint(p1[1]) ? p1[1] : '.' );
		    retc->size --;
		    break;
		  }
		p1 += 2;
		retc->size --;
	      }
	    else
	      *p2++ = *p1++;
	  }
    }
  retc->x.str_val[retc->size] = '\0';
  return retc;
}
tree_cell* nasl_rawstring(lex_ctxt* lexic)
{
  tree_cell	*retc;
  int		vi, vn, i, j, x;
  int		sz, typ;
  const char	*s; 
  int		total_len = 0;


  retc = alloc_tree_cell(0, NULL);
  retc->type = CONST_DATA;
  retc->size = 0;
  retc->x.str_val = emalloc(RAW_STR_LEN);

  vn = array_max_index(&lexic->ctx_vars);
  for (vi = 0; vi < vn && total_len < RAW_STR_LEN-1; vi ++)
    {
      if ((typ = get_var_type_by_num(lexic, vi)) == VAR2_UNDEF)
	continue;
      sz = get_var_size_by_num(lexic, vi);

      if (typ == VAR2_INT)
	{
	  x = get_int_var_by_num(lexic, vi, 0);
	  retc->x.str_val[total_len ++] = x;
	}
      else
	{
	  int		current_len = sz;
	  char		str[RAW_STR_LEN];
	  
	  s = get_str_var_by_num(lexic, vi);
	  if (sz <= 0)
	    sz = strlen(s);

	  if (sz >= RAW_STR_LEN) 
	    {
	      nasl_perror(lexic, "Error. Too long argument in raw_string()\n");
	      break;
	    }

	  /* Should we test if the variable is composed only of digits? */
	  if(typ == VAR2_STRING)
	    {
	      /* TBD:I should decide at last if we keep those "purified" 
	       * string or not, and if we do, if "CONST_STR" & "VAR2_STR" are
	       * "not pure" strings */
	      for(i=0, j=0; i < sz; i++)
		{
		  if(s[i]=='\\')
		    {
		      if (s[i+1] == 'n')
			{
			  str[j++]='\n';
			  i++;
			}
		      else if (s[i+1] == 't')
			{
			  str[j++]='\t';
			  i++;
			}
		      else if (s[i+1] == 'r')
			{ 
			  str[j++] = '\r';
			  i++;
			}
		      else if (s[i+1] == 'x' && 
			       isxdigit(s[i+2]) && isxdigit(s[i+3]))
			{
			  x = 0;
			  if(isdigit(s[i+2]))
			    x = (s[i+2]-'0')*16;
			  else
			    x=(10+tolower(s[i+2])-'a')*16;
			  if(isdigit(s[i+3]))
			    x += s[i+3]-'0';
			  else
			    x += tolower(s[i+3])+10-'a';
			  str[j++]=x;
			  i+=3;
			}
		      else if(s[i+1] == '\\')
			{
			  str[j++] = s[i];
			  i++;
			}
		      else
			i++;
		    }
		  else
		    str[j++] = s[i];
		}
	      current_len = j;
	    }
	  else
	    {
	      memcpy(str, s, sz);
	      str[sz] = '\0';
	      current_len = sz;
	    }
	
	  if(total_len + current_len > RAW_STR_LEN)
	    {
	      nasl_perror(lexic, "Error. Too long argument in raw_string()\n");
	      break;
	    }
	  bcopy(str, retc->x.str_val + total_len, current_len);
	  total_len += current_len;
	}
    }

 retc->size = total_len;
 return retc;
}