Пример #1
0
static bool ch_ir_tokenizer_does_token_contain_only_numerals(
   uint8_t *puc_token)
{
   bool b_only_numerals = false;
   uint8_t uc_c = 0;
   uint32_t ui_i = 0;

   if (NULL == puc_token)
   {
      CH_IR_LOG_MED("Invalid Args");
      goto CLEAN_RETURN;
   }

   ui_i = pal_strlen (puc_token) - 1;

   while (ui_i > 0)
   {
      uc_c = puc_token [ui_i];

      if (uc_c < '0' || uc_c > '9')
      {
         break;
      }

      ui_i--;
   }

   if (0 == ui_i)
   {
      b_only_numerals = true;
   }

CLEAN_RETURN:
   return b_only_numerals;
}
Пример #2
0
pal_regex_t *
bgp_regcomp (char *regstr)
{
  /* Convert _ character to generic regular expression. */
  int i, j;
  int len;
  int magic = 0;
  char *magic_str;
  int magic_str_len;
  char magic_regexp[] = "(^|[,{}() ]|$)";
  int ret;
  pal_regex_t *regex;

  len = pal_strlen (regstr);
  for (i = 0; i < len; i++)
    if (regstr[i] == '_')
      magic++;

  magic_str_len = len + (14 * magic) + 1;
  magic_str = XMALLOC (MTYPE_TMP, magic_str_len);
  regex = XMALLOC (MTYPE_TMP, sizeof (pal_regex_t));

  for (i = 0, j = 0; i < len; i++)
    {

      if (regstr[i] == '_')
        {
          pal_mem_cpy (magic_str + j, magic_regexp, pal_strlen (magic_regexp));
          j += pal_strlen (magic_regexp);
        }
      else
        magic_str[j++] = regstr[i];
    }
  magic_str[j] = '\0';

  ret = pal_regcomp (regex, magic_str, REG_EXTENDED);

  XFREE (MTYPE_TMP, magic_str);

  if (ret != 0)
    {
      XFREE (MTYPE_TMP, regex);
      return NULL;
    }

  return regex;
}
Пример #3
0
// --------------------------------------------------------------------------
//
//
void ExtractChallenge(tChallenge *c, char *String)
{
  char *s, *e, *Token, *Value;
  int len;

  memset(c, 0, sizeof(tChallenge));

  Token = (char*) pal_malloc( pal_strlen(String)+1 );
  Value = (char*) pal_malloc( pal_strlen(String)+1 );

  *Token=*Value=0;

  for(s=e=String; ; e++) {
    if(*e== ',' || *e == '\r' || *e == '\n' || *e==0) {
      if(s!=e) {
        if(*Token && (*Value==0)) {
          len = (int)((char *)e-(char *)s);
/* Chop the quotes */
          if((*s == '"') && len) { s++; len--; }
          if((s[len-1] == '"') && len) len--;
          if(len) memcpy(Value, s, len);
          Value[len] = 0;
        }
        if(*Token && *Value) {
          InsertInChallegeStruct(c, Token,Value);
          *Value = *Token = 0;
        }
      }

      if(*e == 0) break;
      s = ++e;
    }

    if((*e=='=' || *e== ',' || *e == '\r' || *e == '\n' || *e==0) && (*Token == 0) && (e != s)) {
      len = (int)((char *)e-(char *)s);
      memcpy(Token, s, len);
      Token[len] = 0;
      if(*e == 0) break;
      s = ++e;
    }
  }

  pal_free( Token );
  pal_free( Value );
}
Пример #4
0
ssize_t NetTCP6Printf( pal_socket_t sock, char *out, size_t pl, char *Format, ... )
{
  va_list argp;
  size_t Length;
  char Data[1024];

  va_start(argp, Format);
  pal_vsnprintf(Data, sizeof Data, Format, argp);
  va_end(argp);

  Length = pal_strlen(Data);

  if( NetTCP6Write(sock, Data, pal_strlen(Data)) != Length )
  {
    return 0;
  }

  return NetTCP6Read(sock, out, pl);
}
Пример #5
0
sint32_t NetUDPPrintf(pal_socket_t sock, char *out, sint32_t ol, char *Format, ...) 
{
	va_list argp;
	char Data[1024];

	va_start(argp, Format);
	pal_vsnprintf(Data, sizeof Data, Format, argp);
	va_end(argp);

	return NetUDPReadWrite(sock, Data, pal_strlen(Data), out, ol);
}
Пример #6
0
static HM_RET_E hm_get_hash_from_node_data (
   HM_CTXT_X *px_hm_ctxt,
   HM_NODE_DATA_X *px_node_data,
   uint32_t *pui_hash)
{
   HM_RET_E e_error = eHM_RET_FAILURE;
   uint32_t ui_key_len = 0;
   uint8_t *puc_key_buf = NULL;

   if ((NULL == px_hm_ctxt) || (NULL == px_node_data) || (NULL == pui_hash))
   {
      HM_LOG_MED("Invalid Args");
      e_error = eLIST_RET_INVALID_ARGS;
      goto CLEAN_RETURN;
   }

   if (px_hm_ctxt->x_init_params.e_hm_key_type != px_node_data->e_hm_key_type)
   {
      HM_LOG_MED("Invalid Args");
      e_error = eLIST_RET_INVALID_ARGS;
      goto CLEAN_RETURN;
   }

   switch (px_node_data->e_hm_key_type)
   {
      case eHM_KEY_TYPE_INT:
      {
         ui_key_len = sizeof(px_node_data->u_hm_key.ui_uint_key);
         puc_key_buf = (uint8_t *) &(px_node_data->u_hm_key.ui_uint_key);
         break;
      }
      case eHM_KEY_TYPE_STRING:
      {
         ui_key_len = pal_strlen (px_node_data->u_hm_key.puc_str_key);
         puc_key_buf = px_node_data->u_hm_key.puc_str_key;
         break;
      }
      default:
      {
         break;
      }
   }
   e_error = hm_gen_hash_from_buf (px_hm_ctxt, puc_key_buf, ui_key_len,
      pui_hash);
   if (eHM_RET_SUCCESS != e_error)
   {
      HM_LOG_MED("hashmap_gen_hash_from_buf failed: %d", e_error);
   }
CLEAN_RETURN:
   return e_error;
}
Пример #7
0
/****************************** LOCAL FUNCTIONS *******************************/
void ch_ir_indexer_truncate_trailing_whitespace(
   uint8_t *puc_string)
{
   uint32_t ui_len = 0;
   uint32_t ui_i = 0;

   ui_len = pal_strlen (puc_string);

   if (1 == ui_len)
   {
      if (' ' == puc_string [0] || '\t' == puc_string [0]
         || '\n' == puc_string [0] || '\r' == puc_string [0])
      {
         puc_string [0] = '\0';
      }
      return;
   }

   while (ui_i < ui_len)
   {
      if (' ' == puc_string [ui_i] || '\t' == puc_string [ui_i]
         || '\n' == puc_string [ui_i] || '\r' == puc_string [ui_i])
      {
         ui_i++;
         continue;
      }
      else
      {
         (void) pal_memmove (&(puc_string [0]), &(puc_string [ui_i]),
            (ui_len - ui_i + 1));
         break;
      }
   }

   ui_len = ui_len - ui_i - 1;
   while (ui_len >= 0)
   {
      if (' ' == puc_string [ui_len] || '\t' == puc_string [ui_len]
         || '\n' == puc_string [ui_len] || '\r' == puc_string [ui_len])
      {
         ui_len--;
         continue;
      }
      else
      {
         puc_string [ui_len + 1] = '\0';
         break;
      }
   }
}
Пример #8
0
HM_NODE_DATA_X *hm_alloc_node (
   HM_NODE_DATA_X *px_node_data)
{
   HM_NODE_DATA_X *px_new_node = NULL;
   uint32_t ui_key_len = 0;

   if (NULL == px_node_data)
   {
      HM_LOG_MED("Invalid Args");
      goto CLEAN_RETURN;
   }

   px_new_node = pal_malloc (sizeof(HM_NODE_DATA_X), NULL);
   if (NULL == px_new_node)
   {
      HM_LOG_MED("pal_malloc failed");
      goto CLEAN_RETURN;
   }

   (void) pal_memmove(px_new_node, px_node_data, sizeof (*px_new_node));

   if (eHM_KEY_TYPE_STRING == px_node_data->e_hm_key_type)
   {
      ui_key_len = pal_strlen (px_node_data->u_hm_key.puc_str_key);
      ui_key_len = ui_key_len + 1;
      px_new_node->u_hm_key.puc_str_key = pal_malloc (ui_key_len, NULL);
      if (NULL == px_new_node->u_hm_key.puc_str_key)
      {
         pal_free (px_new_node);
         px_new_node = NULL;
         goto CLEAN_RETURN;
      }

      (void) pal_strncpy (px_new_node->u_hm_key.puc_str_key,
         px_node_data->u_hm_key.puc_str_key, ui_key_len);
   }
CLEAN_RETURN:
   return px_new_node;
}
Пример #9
0
void set_tsp_env_variables( const tConf* pConfig, const tTunnel* pTunnelInfo )
{
  char buffer[8];

  // Specify log verbosity (MAXIMAL).
  pal_snprintf( buffer, sizeof buffer, "%d", LOG_LEVEL_MAX );
  tspSetEnv("TSP_VERBOSE", buffer, 1);

  // Specify Gateway6 Client installation directory.
  tspSetEnv("TSP_HOME_DIR", TspHomeDir, 1);

  // Specify the tunnel mode.
  tspSetEnv("TSP_TUNNEL_MODE", pTunnelInfo->type, 1);

  // Specify host type {router, host}
  tspSetEnv("TSP_HOST_TYPE", pConfig->host_type, 1);

  // Specify tunnel interface, for setup.
  if (pal_strcasecmp(pTunnelInfo->type, STR_XML_TUNNELMODE_V6V4) == 0 )
  {
    tspSetEnv("TSP_TUNNEL_INTERFACE", pConfig->if_tunnel_v6v4, 1);
    gTunnelInfo.eTunnelType = TUNTYPE_V6V4;
  }
  else if (pal_strcasecmp(pTunnelInfo->type, STR_XML_TUNNELMODE_V6UDPV4) == 0 )
  {
    tspSetEnv("TSP_TUNNEL_INTERFACE", pConfig->if_tunnel_v6udpv4, 1);
    gTunnelInfo.eTunnelType = TUNTYPE_V6UDPV4;
  }
#ifdef V4V6_SUPPORT
  else if (pal_strcasecmp(pTunnelInfo->type, STR_XML_TUNNELMODE_V4V6) == 0 )
  {
    tspSetEnv("TSP_TUNNEL_INTERFACE", pConfig->if_tunnel_v4v6, 1);
    gTunnelInfo.eTunnelType = TUNTYPE_V4V6;
  }
#endif /* V4V6_SUPPORT */

  // Specify what interface will be used for routing advertizement,
  // if enabled.
  tspSetEnv("TSP_HOME_INTERFACE", pConfig->if_prefix, 1);

  // Specify local endpoint IPv4 address
  tspSetEnv("TSP_CLIENT_ADDRESS_IPV4", pTunnelInfo->client_address_ipv4, 1);
  gTunnelInfo.szIPV4AddrLocalEndpoint = pTunnelInfo->client_address_ipv4;

  // Specify local endpoint IPv6 address
  tspSetEnv("TSP_CLIENT_ADDRESS_IPV6", pTunnelInfo->client_address_ipv6, 1);
  gTunnelInfo.szIPV6AddrLocalEndpoint = pTunnelInfo->client_address_ipv6;

  // Specify local endpoint domain name
  if( pTunnelInfo->client_dns_name != NULL)
  {
    tspSetEnv("TSP_CLIENT_DNS_NAME", pTunnelInfo->client_dns_name, 1);
    gTunnelInfo.szUserDomain = pTunnelInfo->client_dns_name;
  }

  // Specify remote endpoint IPv4 address.
  tspSetEnv("TSP_SERVER_ADDRESS_IPV4", pTunnelInfo->server_address_ipv4, 1);
  gTunnelInfo.szIPV4AddrRemoteEndpoint = pTunnelInfo->server_address_ipv4;

  // Specify remote endpoint IPv6 address.
  tspSetEnv("TSP_SERVER_ADDRESS_IPV6", pTunnelInfo->server_address_ipv6, 1);
  gTunnelInfo.szIPV6AddrRemoteEndpoint = pTunnelInfo->server_address_ipv6;

  // Specify prefix for tunnel endpoint.
  if ((pal_strcasecmp(pTunnelInfo->type, STR_XML_TUNNELMODE_V6V4) == 0) ||
      (pal_strcasecmp(pTunnelInfo->type, STR_XML_TUNNELMODE_V6UDPV4) == 0))
    tspSetEnv("TSP_TUNNEL_PREFIXLEN", "128", 1);
#ifdef V4V6_SUPPORT
  else
    tspSetEnv("TSP_TUNNEL_PREFIXLEN", "32", 1);
#endif /* V4V6_SUPPORT */


  // Free and clear delegated prefix from tunnel info.
  if( gTunnelInfo.szDelegatedPrefix != NULL )
  {
    pal_free( gTunnelInfo.szDelegatedPrefix );
    gTunnelInfo.szDelegatedPrefix = NULL;
  }

  // Have we been allocated a prefix for routing advertizement..?
  if( pTunnelInfo->prefix != NULL )
  {
    char chPrefix[128];
    size_t len, sep;

    /* Compute the number of characters that are significant out of the prefix. */
    /* This is meaningful only for IPv6 prefixes; no contraction is possible for IPv4. */
    if ((pal_strcasecmp(pTunnelInfo->type, STR_XML_TUNNELMODE_V6V4) == 0) ||
        (pal_strcasecmp(pTunnelInfo->type, STR_XML_TUNNELMODE_V6UDPV4) == 0))
    {
      len = (atoi(pTunnelInfo->prefix_length) % 16) ? (atoi(pTunnelInfo->prefix_length) / 16 + 1) * 4 : atoi(pTunnelInfo->prefix_length) / 16 * 4;
      sep = (atoi(pTunnelInfo->prefix_length) % 16) ? (atoi(pTunnelInfo->prefix_length) / 16) : (atoi(pTunnelInfo->prefix_length) / 16) -1;
    }
    else
    {
      len = pal_strlen( pTunnelInfo->prefix );
      sep = 0;
    }

    memset(chPrefix, 0, 128);
    memcpy(chPrefix, pTunnelInfo->prefix, len+sep);

    // Specify delegated prefix for routing advertizement, if enabled.
    tspSetEnv("TSP_PREFIX", chPrefix, 1);
    gTunnelInfo.szDelegatedPrefix = (char*) pal_malloc( pal_strlen(chPrefix) + 10/*To append prefix_length*/ );
    strcpy( gTunnelInfo.szDelegatedPrefix, chPrefix );

    // Specify prefix length for routing advertizement, if enabled.
    tspSetEnv("TSP_PREFIXLEN", pTunnelInfo->prefix_length, 1);
    strcat( gTunnelInfo.szDelegatedPrefix, "/" );
    strcat( gTunnelInfo.szDelegatedPrefix, pTunnelInfo->prefix_length );
  }
}
Пример #10
0
static
int
is_dsakey_in_keyfile(DSA *dsa_1, char *host, char *filename)
{
  FILE *fp = NULL;
  char *line_buf = NULL;
  char *str = NULL;
  char *str_base64 = NULL;
  Buffer keyfile_buf;
  BIGNUM *bn_p = NULL;
  BIGNUM *bn_q = NULL;
  BIGNUM *bn_g = NULL;
  BIGNUM *bn_pub_key = NULL;
  int ret = 1;
  size_t str_size = 0;
  int i;


  if (!dsa_1 || !host || !filename)
    return 0;

  memset(&keyfile_buf, 0, sizeof(keyfile_buf));

  /* Open the keyfile */

  if ( (fp = fopen(filename, "r")) == NULL) {
    /* no key file */
    ret = 1;
    goto is_dsakey_in_keyfile_cleanup;
  }

  /* Get memory for a line buffer */

  if ( (line_buf = pal_malloc(sizeof(char) * 4096)) == NULL) {
    ret = 0;
    goto is_dsakey_in_keyfile_cleanup;
  }

  while (freadline(line_buf, 4095, fp) != EOF) {
    int len;

    str_base64 = strtok(line_buf, " ");

    if (strcmp(host, str_base64) != 0)
      continue;

    /* We got a match on the hostname
     * Now we assemble a DSA object
     * with what we have in the buffer
     */

    str_base64 = strtok(NULL, " ");

    if (strcmp("ssh-dss", str_base64) != 0)
      continue;

    /* We got a match on the key type as
       well, going on
    */

    str_base64 = strtok(NULL, " ");

    /*
     * Get the base64 data
     * and discard ssh-dss first
     */

    str_size = pal_strlen(str_base64) * sizeof(char);

    if ( (str = pal_malloc(str_size)) == NULL) {
      ret = 0;
      goto is_dsakey_in_keyfile_cleanup;
    }

    if ( (len = base64decode(str, str_base64)) < 1) {
      ret = 0;
      goto is_dsakey_in_keyfile_cleanup;
    }

    /* Fill a buffer structure with this data
     */

    buffer_init(&keyfile_buf);
    if (keyfile_buf.buf == NULL) {
      ret = 0;
      goto is_dsakey_in_keyfile_cleanup;
    }

    buffer_append(&keyfile_buf, str, str_size);

    /* Now get some BN filled with the data
     * from the buffer and compare
     * those with what we got in the incoming
     * dsa object.
     */

    bn_p = BN_new();
    bn_q = BN_new();
    bn_g = BN_new();
    bn_pub_key = BN_new();

    if (bn_p == NULL ||
  bn_q == NULL ||
  bn_g == NULL ||
  bn_pub_key == NULL) {
      ret = 0;
      goto is_dsakey_in_keyfile_cleanup;
    }

    /* String is skipped XXX */
    buffer_get_string(&keyfile_buf, (unsigned int*)&i);  // Bogus i returns the string length, not used
    buffer_get_bignum(&keyfile_buf, bn_p);
    buffer_get_bignum(&keyfile_buf, bn_q);
    buffer_get_bignum(&keyfile_buf, bn_g);
    buffer_get_bignum(&keyfile_buf, bn_pub_key);

    if ( !BN_cmp(dsa_1->p, bn_p) &&
   !BN_cmp(dsa_1->q, bn_q) &&
   !BN_cmp(dsa_1->g, bn_g) &&
   !BN_cmp(dsa_1->pub_key, bn_pub_key) )
      ret = 2;
    else ret = 3;
  }

is_dsakey_in_keyfile_cleanup:

    if (str)
      pal_free(str);
    if (line_buf)
      pal_free(line_buf);
    if (fp)
      fclose(fp);
    if (bn_p)
      BN_clear_free(bn_p);
    if (bn_q)
      BN_clear_free(bn_q);
    if (bn_g)
      BN_clear_free(bn_g);
    if (bn_pub_key)
      BN_clear_free(bn_pub_key);
    if (keyfile_buf.buf)
      buffer_free(&keyfile_buf);

  return ret;
}
Пример #11
0
// --------------------------------------------------------------------------
// Function : tspAuthenticate
//
// Synopsys: Will authenticate a session with the broker.
//
// Description:
//   First, we'll try to find the most secure common authentication method.
//   Once the authentication method has been chosen, the authentication
//   process is initiated with the broker.
//
// Arguments: (only local-specific arguments are listed here)
//   cap: bitfield [IN], The authentication methods suported by the broker.
//   conf: tConf* [IN], The global configuration object.
//
// Return values:
//   A gogoc_status status.
//
// --------------------------------------------------------------------------
gogoc_status tspAuthenticate(pal_socket_t socket, tCapability cap, net_tools_t *nt, tConf *conf, tBrokerList **broker_list, int version_index)
{
  gogoc_status status = make_status(CTX_TSPAUTHENTICATION, ERR_NO_COMMON_AUTHENTICATION);
  tCapability Mechanism;


  // Get mechanism, depending on requested authentication method.
  if( pal_strcasecmp( conf->auth_method, "any" ) == 0 )
    Mechanism = AUTH_ANY;
  else
    Mechanism = tspSetCapability("AUTH", conf->auth_method);


  if( pal_strcasecmp( conf->auth_method, "anonymous" ) != 0 )
  {
    // Try the most secure authentication methods first:
#ifndef NO_OPENSSL
    if( Mechanism & cap & AUTH_PASSDSS_3DES_1 )
    {
      Display(LOG_LEVEL_3, ELInfo, "tspAuthenticate", GOGO_STR_USING_AUTH_PASSDSS_3DES_1);
      status = AuthPASSDSS_3DES_1(socket, nt, conf, broker_list);
      goto EndAuthenticate;
    }
#endif
    if( Mechanism & cap & AUTH_DIGEST_MD5 )
    {
      Display(LOG_LEVEL_3, ELInfo, "tspAuthenticate", GOGO_STR_USING_AUTH_DIGEST_MD5);
      status = AuthDIGEST_MD5(socket, nt, conf, broker_list, version_index);
      goto EndAuthenticate;
    }

    if( Mechanism & cap & AUTH_PLAIN )
    {
      Display(LOG_LEVEL_3, ELInfo, "tspAuthenticate", GOGO_STR_USING_AUTH_PLAIN);
      status = AuthPLAIN(socket, nt, conf, broker_list);
      goto EndAuthenticate;
    }
  }
  else
  {
    // Finally, try anonymous if possible.
    if( Mechanism & cap & AUTH_ANONYMOUS )
    {
      Display(LOG_LEVEL_3, ELInfo, "tspAuthenticate", GOGO_STR_USING_AUTH_ANONYMOUS);
      status = AuthANONYMOUS(socket, nt, conf, broker_list);
      goto EndAuthenticate;
    }
  }

EndAuthenticate:
  if( status_number(status) == ERR_NO_COMMON_AUTHENTICATION )
  {
    const char* szStrings[] = { "Server Authentication Capabilities: ",
                                "Your Configured Authentication:     " };
    size_t nWritten;
    char bufDisplay[256];

    // Display server authentication capabilities.
    pal_snprintf( bufDisplay, sizeof(bufDisplay), "%s", szStrings[0] );
    nWritten = pal_strlen( szStrings[0] );
    tspFormatCapabilities( bufDisplay + nWritten, sizeof(bufDisplay) - nWritten, cap );
    Display( LOG_LEVEL_1, ELWarning, "tspAuthenticate", bufDisplay );

    // Display user authentication choice.
    pal_snprintf( bufDisplay, sizeof(bufDisplay), "%s", szStrings[1] );
    nWritten = pal_strlen( szStrings[1] );
    tspFormatCapabilities( bufDisplay + nWritten, sizeof(bufDisplay) - nWritten, Mechanism );
    Display( LOG_LEVEL_1, ELWarning, "tspAuthenticate", bufDisplay );

    // Failed to find a common authentication method.
    Display(LOG_LEVEL_1, ELError, "tspAuthenticate", STR_TSP_NO_COMMON_AUTHENTICATION);
  }

  return status;
}
Пример #12
0
// --------------------------------------------------------------------------
// AuthDIGEST_MD5: Performs a Digest-MD5 authentication with the server.
//
gogoc_status AuthDIGEST_MD5(pal_socket_t socket, net_tools_t *nt, tConf *conf, tBrokerList **broker_list, int version_index)
{
  char Buffer[4096], Response[33], cResponse[33], *ChallengeString;
  char string[] = "AUTHENTICATE DIGEST-MD5\r\n";
  char BufferIn[REDIRECT_RECEIVE_BUFFER_SIZE];
  time_t cnonce = pal_time(NULL);
  tChallenge c;
  sint32_t tsp_status;


  // Send authentication mode.
  memset(BufferIn, 0, sizeof(BufferIn));
  if( nt->netsendrecv(socket, string, sizeof(string), BufferIn, sizeof(BufferIn)) == -1 )
  {
    Display(LOG_LEVEL_1, ELError, "AuthDIGEST_MD5", STR_NET_FAIL_RW_SOCKET);
    return make_status(CTX_TSPAUTHENTICATION, ERR_SOCKET_IO);
  }
  tsp_status = tspGetStatusCode(BufferIn);

  // Check if the reply status indicated a broker redirection.
  if( tspIsRedirectStatus(tsp_status) )
  {
    if( tspHandleRedirect(BufferIn, conf, broker_list) == TSP_REDIRECT_OK )
    {
      // Return a REDIRECT event.
      return make_status(CTX_TSPAUTHENTICATION, EVNT_BROKER_REDIRECTION);
    }
    else 
    {
      // Redirect error.
      return make_status(CTX_TSPAUTHENTICATION, ERR_BROKER_REDIRECTION);
    }
  }

  // Check for error in status.
  if( tsp_status == TSP_PROTOCOL_AUTH_FAILED )
  {
    // Failed authentication.
    Display(LOG_LEVEL_1, ELError, "AuthDIGEST_MD5", STR_TSP_AUTH_FAILED_USER, conf->userid);
    return make_status(CTX_TSPAUTHENTICATION, ERR_AUTHENTICATION_FAILURE);
  }

  // Allocate memory for challenge string.
  if( (ChallengeString = pal_malloc(pal_strlen(BufferIn) + 1)) == NULL )
  {
    Display(LOG_LEVEL_1, ELError, "AuthDIGEST_MD5", STR_GEN_MALLOC_ERROR);
    return make_status(CTX_TSPAUTHENTICATION, ERR_MEMORY_STARVATION);
  }

  base64decode(ChallengeString, BufferIn);
  ExtractChallenge(&c, ChallengeString);
  pal_free(ChallengeString);

   {
   /*-----------------------------------------------------------*/
   /*
      Extract from : RFC 2831 Digest SASL Mechanism

      Let H(s) be the 16 octet MD5 hash [RFC 1321] of the octet string s.

      Let KD(k, s) be H({k, ":", s}), i.e., the 16 octet hash of the string
      k, a colon and the string s.

      Let HEX(n) be the representation of the 16 octet MD5 hash n as a
      string of 32 hex digits (with alphabetic characters always in lower
      case, since MD5 is case sensitive).

      response-value  =
         HEX( KD ( HEX(H(A1)),
                 { nonce-value, ":" nc-value, ":",
                   cnonce-value, ":", qop-value, ":", HEX(H(A2)) }))

      If authzid is not specified, then A1 is

         A1 = { H( { username-value, ":", realm-value, ":", passwd } ),
           ":", nonce-value, ":", cnonce-value }

      If the "qop" directive's value is "auth", then A2 is:

         A2       = { "AUTHENTICATE:", digest-uri-value }

   */
    char *A1_1Fmt     = "%s:%s:%s",
#ifndef WIN32
         *A1Fmt        = ":%s:%lu",
         *ChallRespFmt = "%s:%s:00000001:%lu:%s:%s",
         *ResponseFmt  = "charset=%s,username=\"%s\",realm=\"%s\",nonce=\"%s\",nc=00000001,cnonce=\"%lu\",digest-uri=\"tsp/%s\",response=%s,qop=auth",
#else
          // 64 bit version.
         *A1Fmt        = ":%s:%I64d",
         *ChallRespFmt = "%s:%s:00000001:%I64d:%s:%s",
         *ResponseFmt  = "charset=%s,username=\"%s\",realm=\"%s\",nonce=\"%s\",nc=00000001,cnonce=\"%I64d\",digest-uri=\"tsp/%s\",response=%s,qop=auth",
#endif
         *A2Fmt        = "%s:tsp/%s",
         A1[33], A1_1[33], A2[33], cA2[33], *String;
    size_t len;

    /*-----------------------------------------------------------*/
    /* Build HEX(H(A2)) & HEX(H(cA2))                            */

    len = pal_strlen(A2Fmt) + 12 /* AUTHENTICATE */ + pal_strlen(conf->server) + 1;
    if( (String = pal_malloc(len)) == NULL ) 
    {
      Display(LOG_LEVEL_1, ELError, "AuthDIGEST_MD5", STR_GEN_MALLOC_ERROR);
      return make_status(CTX_TSPAUTHENTICATION, ERR_MEMORY_STARVATION);
    }

     pal_snprintf(String, len, A2Fmt, "AUTHENTICATE", conf->server);
#if defined(_DEBUG) || defined(DEBUG)
     printf("A2 = %s\n", String);
#endif
     strncpy(A2, md5(String, pal_strlen(String)), 33);
     pal_snprintf(String, len, A2Fmt, "", conf->server);
#if defined(_DEBUG) || defined(DEBUG)
     printf("cA2 = %s\n", String);
#endif
     strncpy(cA2, md5(String, pal_strlen(String)), 33);
     pal_free(String);

    /*-----------------------------------------------------------*/
    /* Build HEX(H(A1))                                          */
    /* A1_1 = { username-value, ":", realm-value, ":", passwd }  */
    /* A1 = { H( A1_1 ), ":", nonce-value, ":", cnonce-value }   */

    len = pal_strlen(A1_1Fmt) + pal_strlen(conf->userid) + 
          pal_strlen(c.realm) + pal_strlen(conf->passwd) +  1;
    if( (String = pal_malloc(len)) == NULL )
    {
      Display(LOG_LEVEL_1, ELError, "AuthDIGEST_MD5", STR_GEN_MALLOC_ERROR);
      return make_status(CTX_TSPAUTHENTICATION, ERR_MEMORY_STARVATION);
    }

     pal_snprintf(String, len, A1_1Fmt, conf->userid, c.realm, conf->passwd);
#if defined(_DEBUG) || defined(DEBUG)
     printf("A1_1 = %s\n", String);
#endif
     md5digest(String, pal_strlen(String), A1_1);
     pal_free(String);
     len = 16 /* A1_1 */ + 1 +
         pal_strlen(c.nonce) + 16 /* cnonce */ +  1;
    if( (String = pal_malloc(len)) == NULL )
    {
      Display(LOG_LEVEL_1, ELError, "AuthDIGEST_MD5", STR_GEN_MALLOC_ERROR);
      return make_status(CTX_TSPAUTHENTICATION, ERR_MEMORY_STARVATION);
    }

     memcpy(String, A1_1, 16);
     pal_snprintf(String + 16, len - 16, A1Fmt, c.nonce, cnonce);
#ifdef SUPPORT_MD5_BUG1455
     A1_1[16] = '\0';
     if ((pal_strlen(A1_1) < 16) &&
        !((pal_strlen(TSPProtoVerStr[version_index]) > 5) ||
    (strcmp(TSPProtoVerStr[version_index], CLIENT_VERSION_STRING_2_0_0) > 0)))
        strncpy(A1, md5(String, pal_strlen(String)), 33);
     else
#endif /* SUPPORT_MD5_BUG1455 */
         strncpy(A1, md5(String, 16 + pal_strlen(String + 16)), 33);
     pal_free(String);
#if defined(_DEBUG) || defined(DEBUG)
     printf("A1 = [%s]\n", A1);
#endif

    /*-----------------------------------------------------------*/
    /* Build server's and client's challenge responses           */
    len = pal_strlen(ChallRespFmt) + 32 /* md5(A1) */ + pal_strlen(c.nonce) +16 /* cnonce */ + pal_strlen(c.qop) + 32 /* md5(A2) */ +  1;
    if((String = pal_malloc(len)) == NULL)
    {
      Display(LOG_LEVEL_1, ELError, "AuthDIGEST_MD5", STR_GEN_MALLOC_ERROR);
      return make_status(CTX_TSPAUTHENTICATION, ERR_MEMORY_STARVATION);
    }

     pal_snprintf(String, len, ChallRespFmt, A1, c.nonce, cnonce, c.qop, A2);
#if defined(_DEBUG) || defined(DEBUG)
     printf("Response = [%s]\n", String);
#endif
     strncpy(Response, md5(String, pal_strlen(String)), 33);
#if defined(_DEBUG) || defined(DEBUG)
     printf("MD5 Response = %s\n", Response);
#endif
     pal_snprintf(String, len, ChallRespFmt, A1, c.nonce, cnonce, c.qop, cA2);
#if defined(_DEBUG) || defined(DEBUG)
     printf("cResponse = [%s]\n", String);
#endif
     strncpy(cResponse, md5(String, pal_strlen(String)), 33);
#if defined(_DEBUG) || defined(DEBUG)
     printf("MD5 cResponse = %s\n", cResponse);
#endif
     pal_free(String);

      /*-----------------------------------------------------------*/
      /* Build Response                                            */
     {
       char   userid[512];  // UserId is theorically limited to 253 chars.
       char * cc;
       size_t i;

        // Escape malicious " and \ from conf->userid.
       for(cc=conf->userid, i=0; *cc && i<512; cc++, i++)
       {
         // Prepend a backslash (\).
         if( *cc == '"'  ||  *cc == '\\' )
           userid[i++] = '\\';
          // Copy character.
          userid[i] = *cc;
       }
       userid[i] = '\0';

       len = pal_strlen(ResponseFmt) + pal_strlen(c.charset) + pal_strlen(userid) +
           pal_strlen(c.realm) + pal_strlen(c.nonce) + 16 /*cnonce*/ +
           pal_strlen(conf->server)    + 32 /* md5 response */;
       if( (String = pal_malloc(len)) == NULL )
       {
        Display(LOG_LEVEL_1, ELError, "AuthDIGEST_MD5", STR_GEN_MALLOC_ERROR);
        return make_status(CTX_TSPAUTHENTICATION, ERR_MEMORY_STARVATION);
       }

       pal_snprintf(String, len, ResponseFmt, c.charset, userid, c.realm, c.nonce, cnonce, conf->server, Response);
       memset(Buffer, 0, sizeof(Buffer));
       base64encode(Buffer, String, (int)pal_strlen(String));
       pal_free(String);
     }
   }

  // Send authentication data.
  memset(BufferIn, 0, sizeof(BufferIn));
  if( nt->netprintf(socket, BufferIn, sizeof(BufferIn), "%s\r\n", Buffer) == -1 )
  {
    Display(LOG_LEVEL_1, ELError, "AuthDIGEST_MD5", STR_NET_FAIL_W_SOCKET);
    return make_status(CTX_TSPAUTHENTICATION, ERR_SOCKET_IO);
  }
  tsp_status = tspGetStatusCode(BufferIn);

  // Check if the reply status indicated a broker redirection.
  if( tspIsRedirectStatus(tsp_status) )
  {
    if( tspHandleRedirect(BufferIn, conf, broker_list) == TSP_REDIRECT_OK )
    {
      // Return a REDIRECT event.
      return make_status(CTX_TSPAUTHENTICATION, EVNT_BROKER_REDIRECTION);
    }
    else 
    {
      // Redirect error.
      return make_status(CTX_TSPAUTHENTICATION, ERR_BROKER_REDIRECTION);
    }
  }

  /*-----------------------------------------------------------*/
  /* Verify server response                                    */
  if( tsp_status == TSP_PROTOCOL_AUTH_FAILED )
  {
    // Failed authentication.
    Display(LOG_LEVEL_1, ELError, "AuthDIGEST_MD5", STR_TSP_AUTH_FAILED_USER, conf->userid);
    return make_status(CTX_TSPAUTHENTICATION, ERR_AUTHENTICATION_FAILURE);
  }

  if( (ChallengeString = pal_malloc(pal_strlen(BufferIn) + 1)) == NULL )
  {
    Display(LOG_LEVEL_1, ELError, "AuthDIGEST_MD5", STR_GEN_MALLOC_ERROR);
    return make_status(CTX_TSPAUTHENTICATION, ERR_MEMORY_STARVATION);
  }

  base64decode(ChallengeString, BufferIn);
  ExtractChallenge(&c, ChallengeString);
  pal_free(ChallengeString);

  if( memcmp(c.rspauth, cResponse, 32) )
  {
    Display(LOG_LEVEL_1, ELError, "AuthDIGEST_MD5", STR_MISC_INVALID_MD5_RESPONSE);
    return make_status(CTX_TSPAUTHENTICATION, ERR_AUTHENTICATION_FAILURE);
  }

  // Receive reply.
  if( nt->netrecv(socket, Buffer, sizeof(Buffer) ) == -1 )
  {
    Display(LOG_LEVEL_1, ELError, "AuthDIGEST_MD5", STR_NET_FAIL_R_SOCKET);
    return make_status(CTX_TSPAUTHENTICATION, ERR_SOCKET_IO);
  }
  tsp_status = tspGetStatusCode(Buffer);

  // Check if the reply status indicated a broker redirection.
  if( tspIsRedirectStatus(tsp_status) )
  {
    if( tspHandleRedirect(Buffer, conf, broker_list) == TSP_REDIRECT_OK )
    {
      // Return a REDIRECT event.
      return make_status(CTX_TSPAUTHENTICATION, EVNT_BROKER_REDIRECTION);
    }
    else 
    {
      // Redirect error.
      return make_status(CTX_TSPAUTHENTICATION, ERR_BROKER_REDIRECTION);
    }
  }

  // Check if authentication was successful.
  switch( tsp_status )
  {
  case TSP_PROTOCOL_SUCCESS:
    break;

  case TSP_PROTOCOL_AUTH_FAILED:
    Display(LOG_LEVEL_1, ELError, "AuthDIGEST_MD5", STR_TSP_AUTH_FAILED_USER, conf->userid);
    return make_status(CTX_TSPAUTHENTICATION, ERR_AUTHENTICATION_FAILURE);

  default:
    Display(LOG_LEVEL_1, ELError, "AuthDIGEST_MD5", STR_TSP_UNKNOWN_ERR_AUTH_FAILED, tspGetTspStatusStr(tsp_status));
    return make_status(CTX_TSPAUTHENTICATION, ERR_TSP_GENERIC_ERROR);
  }

  // Successful MD5 authentication.
  return make_status(CTX_TSPAUTHENTICATION, SUCCESS);
}
Пример #13
0
/* Calculate the roundtrip time to a brokre using a TSP echo request */
tRedirectStatus timeEchoRequestReply(pal_socket_t sfd, char *address, rttengine_stat_t *engine, uint32_t *distance) {
  char data_in[ECHO_REQUEST_IN_BUF_SIZE];
  char data_out[ECHO_REQUEST_OUT_BUF_SIZE];
  sint32_t data_in_size = 0;
  size_t data_out_size = 0;
  rudp_msghdr_t *imh = NULL;
  rudp_msghdr_t *omh = NULL;
  void *om = NULL;
  void *im = NULL;
  sint32_t length_sent = 0;
  sint32_t ret = 0;
  fd_set fs;
  struct timeval tv_select;

  /* The receive buffer is empty */
  memset(data_in, 0, sizeof(data_in));
  /* The send buffer contains the "ECHO REQUEST" command */
  pal_snprintf(data_out, sizeof(data_out), ECHO_REQUEST_COMMAND);

  /* Calculate the buffer sizes */
  data_in_size = sizeof(data_in);
  data_out_size = pal_strlen(data_out);

  /* Prepare RUDP messages */
  im = internal_prepare_message(&imh, data_in_size);
  om = internal_prepare_message(&omh, data_out_size);

  /* A NULL message is an error */
  if ((im == NULL) || (om == NULL)) {
    rttengine_deinit(engine, im, om);
    *distance += ECHO_REQUEST_ERROR_ADJUST;
    Display(LOG_LEVEL_1, ELError, "timeEchoRequestReply", GOGO_STR_RDR_ERROR_PREPARING_RUDP_MSG, address);
    return TSP_REDIRECT_ECHO_REQUEST_ERROR;
  }

  /* Zero them out */
  memset(im, 0, data_in_size);
  memset(om, 0, data_out_size);

  /* Copy the outgoing data to the data part of the outgoing message */
  memcpy((char*)om + sizeof(rudp_msghdr_t), data_out, data_out_size);

  /* Set the outgoing message's sequence number */
  omh->sequence = htonl(engine->sequence++ | 0xf0000000);

send_loop:

  /* Fail if we have reached the maximum number of echo request attempts */
  if (engine->retries == ECHO_REQUEST_ATTEMPTS) {
    rttengine_deinit(engine, im, om);
    *distance += ECHO_REQUEST_TIMEOUT_ADJUST;
    Display(LOG_LEVEL_3, ELWarning, "timeEchoRequestReply", GOGO_STR_RDR_MAX_ECHO_REPLY_ATTEMPTS, ECHO_REQUEST_ATTEMPTS, address);
    return TSP_REDIRECT_ECHO_REQUEST_TIMEOUT;
  }

  /* Set the timestamp for the outgoing message */
  omh->timestamp = htonl(internal_get_timestamp(engine));

  /* Try to send the outgoing message */
  Display(LOG_LEVEL_3, ELInfo, "timeEchoRequestReply", GOGO_STR_RDR_SENDING_ECHO_REQUEST, (engine->retries + 1), address);

  if ((length_sent = send(sfd, om, (sint32_t)(data_out_size + sizeof(rudp_msghdr_t)), 0)) == -1) {
    rttengine_deinit(engine, im, om);
    *distance += ECHO_REQUEST_ERROR_ADJUST;
    Display(LOG_LEVEL_1, ELError, "timeEchoRequestReply", GOGO_STR_RDR_SEND_ECHO_REQUEST_FAILED, address);
    return TSP_REDIRECT_ECHO_REQUEST_ERROR;
  }

  /* Set the timeout for the select */
  /* This is the maximum time we will wait for an echo reply */
  tv_select.tv_sec = ECHO_REQUEST_TIMEOUT / 1000;
  tv_select.tv_usec = (ECHO_REQUEST_TIMEOUT % 1000) * 1000;

select_loop:

  FD_ZERO(&fs);
  FD_SET(sfd, &fs);

  Display(LOG_LEVEL_3, ELInfo, "timeEchoRequestReply", GOGO_STR_RDR_WAITING_ECHO_REPLY, address);

  /* Wait on the socket set */
  ret = select((sint32_t)sfd + 1, &fs, NULL, NULL, &tv_select);

  switch(ret)
  {
    /* Select timed out, try again */
    case 0:
      Display(LOG_LEVEL_3, ELWarning, "timeEchoRequestReply", GOGO_STR_RDR_WAITING_ECHO_REPLY_TIMEOUT, address);
      engine->retries++;
      goto send_loop;
    /* Ok, select got something */
    case 1:
      Display(LOG_LEVEL_3, ELWarning, "timeEchoRequestReply", GOGO_STR_RDR_RECEIVING_RUDP_MESSAGE, address);

      /* Receive the incoming data, and store it in the incoming message */
      ret = recv(sfd, im, (sizeof(rudp_msghdr_t) + data_in_size), 0);

      /* This is a fatal read error */
      if (ret == -1) {
        rttengine_deinit(engine, im, om);
        *distance += ECHO_REQUEST_ERROR_ADJUST;
        Display(LOG_LEVEL_1, ELError, "timeEchoRequestReply", GOGO_STR_RDR_ERR_RECEIVING_RUDP_FROM, address);
        return TSP_REDIRECT_ECHO_REQUEST_ERROR;
      }

      /* If we have the same sequence number, this is the message we want */
      if (imh->sequence == omh->sequence) {
        *distance += internal_get_timestamp(engine) - ntohl(omh->timestamp);
        ret = ret - sizeof(rudp_msghdr_t);
        Display(LOG_LEVEL_3, ELInfo, "timeEchoRequestReply", GOGO_STR_RDR_RECEIVED_RUDP_OK, address);
        break;
      }
      /* If the sequence numbers are different, see if we get something else */
      else {
        Display(LOG_LEVEL_3, ELWarning, "timeEchoRequestReply", GOGO_STR_RDR_RECV_RUDP_SEQ_DIFFERS, address);

        goto select_loop;
      }
    /* This is an unknown error */
    default:
      rttengine_deinit(engine, im, om);
      *distance += ECHO_REQUEST_ERROR_ADJUST;
      Display(LOG_LEVEL_1, ELError, "timeEchoRequestReply", GOGO_STR_RDR_ERR_WAITING_ECHO_REPLY, address);
      return TSP_REDIRECT_ECHO_REQUEST_ERROR;
  }

  /* Update the stat engine */
  rttengine_update(engine, (internal_get_timestamp(engine) - ntohl(imh->timestamp)));

  /* Copy the data part of the incoming message to the receiving buffer */
  memcpy(data_in, (char*)im + sizeof(rudp_msghdr_t), ret);

  /* Free the messages */
  internal_discard_message(im);
  internal_discard_message(om);

  engine->retries = 0;

  /* Validate that we got the right answer from the broker */
  if (tspGetStatusCode(data_in) != ECHO_REQUEST_SUCCESS_STATUS) {
    Display(LOG_LEVEL_1, ELError, "timeEchoRequestReply", GOGO_STR_RDR_RCV_UNEXPECTED_ECHO_REPLY, address, data_in);
    return TSP_REDIRECT_ECHO_REQUEST_ERROR;
  }

  Display(LOG_LEVEL_3, ELInfo, "timeEchoRequestReply", GOGO_STR_RDR_RCV_EXPECTED_ECHO_REPLY, address, data_in);

  return TSP_REDIRECT_OK;
}
Пример #14
0
// --------------------------------------------------------------------------
// tspGetCapabilities:
//
gogoc_status tspGetCapabilities(pal_socket_t socket, net_tools_t *nt, tCapability *capability, int version_index, tConf *conf, tBrokerList **broker_list)
{
	char dataout[256];
	char datain[REDIRECT_RECEIVE_BUFFER_SIZE];
  sint32_t tsp_status;
  gogoc_status status = make_status(CTX_TSPCAPABILITIES, SUCCESS);


	memset( datain, 0, sizeof(datain) );
	pal_snprintf(dataout, sizeof(dataout), "VERSION=%s\r\n", TSPProtoVerStr[version_index]);

  // Send TSP version to the server. Server should reply with the capabilities.
	if( nt->netsendrecv(socket, dataout, pal_strlen(dataout), datain, (sint32_t)sizeof(datain)) == -1 )
  {
    // Error reading/writing to the socket.
		return make_status(CTX_TSPCAPABILITIES, ERR_SOCKET_IO);
  }

  // Check if we received the TSP capabilities.
	if( memcmp("CAPABILITY ", datain, 11) == 0 )
  {
    // Extract the capabilities.
		*capability = tspExtractCapability(datain);
  }
	else
  {
    // Retrieve the TSP status from the reply.
    tsp_status = tspGetStatusCode(datain);

    // Check if it is a redirect TSP status.
	  if( tspIsRedirectStatus(tsp_status) )
    {
		  if( tspHandleRedirect(datain, conf, broker_list) == TSP_REDIRECT_OK )
      {
        // REDIRECT event.
        status = make_status(CTX_TSPCAPABILITIES, EVNT_BROKER_REDIRECTION);
		  }
		  else 
      {
        // Redirect error.
			  status = make_status(CTX_TSPCAPABILITIES, ERR_BROKER_REDIRECTION);
		  }
	  }
    else
    {
      switch( tsp_status )
      {
      case TSP_PROTOCOL_SERVER_TOO_BUSY:
        // Ze server iz too busy.
        Display(LOG_LEVEL_1, ELWarning, "tspGetCapabilities", STR_TSP_SERVER_TOO_BUSY);
			  status = make_status(CTX_TSPCAPABILITIES, ERR_TSP_SERVER_TOO_BUSY);
        break;

      case TSP_PROTOCOL_UNSUP_TSP_VER:
        // The status was an invalid TSP version.
        Display(LOG_LEVEL_1, ELWarning, "tspGetCapabilities", STR_TSP_INVALID_VERSION, TSPProtoVerStr[version_index]);
			  status = make_status(CTX_TSPCAPABILITIES, ERR_INVAL_TSP_VERSION);
        break;

      default:
        // Unknown / unexpected TSP error occurred.
		    Display(LOG_LEVEL_1, ELError, "tspGetCapabilities", STR_TSP_GEN_ERROR, tsp_status, tspGetTspStatusStr(tsp_status));
		    status = make_status(CTX_TSPCAPABILITIES, ERR_TSP_GENERIC_ERROR);
        break;
      }
      Display(LOG_LEVEL_1, ELError, "tspGetCapabilities", STR_TSP_GETCAPABILITIES_ERROR);
    }
	}

  // Successful operation.
	return status;
}