예제 #1
0
HM_RET_E hm_delete_resources (
   HM_CTXT_X *px_hm_ctxt)
{
   HM_RET_E e_error = eHM_RET_FAILURE;
   PAL_RET_E e_pal_ret = ePAL_RET_FAILURE;
   LIST_RET_E e_list_ret = eLIST_RET_FAILURE;

   if (NULL == px_hm_ctxt)
   {
      HM_LOG_MED("Invalid Args");
      e_error = eHM_RET_INVALID_ARGS;
      goto CLEAN_RETURN;
   }

   if (NULL != px_hm_ctxt->hl_mutex_hdl)
   {
      e_pal_ret = pal_mutex_destroy (px_hm_ctxt->hl_mutex_hdl);
      if (ePAL_RET_SUCCESS != e_pal_ret)
      {
         HM_LOG_MED("pal_mutex_destroy failed: %d", e_pal_ret);
      }
      px_hm_ctxt->hl_mutex_hdl = NULL;
   }

   if (NULL != px_hm_ctxt->ppx_hash_table)
   {
      pal_free (px_hm_ctxt->ppx_hash_table);
      px_hm_ctxt->ppx_hash_table = NULL;
   }

   if (NULL != px_hm_ctxt->px_link_list_ctxt)
   {
      if (NULL != px_hm_ctxt->px_link_list_ctxt->hl_list_hdl)
      {
         e_list_ret = list_delete (px_hm_ctxt->px_link_list_ctxt->hl_list_hdl);
         if (eLIST_RET_SUCCESS != e_list_ret)
         {
            HM_LOG_MED("list_delete failed: %d", e_list_ret);
         }
         px_hm_ctxt->px_link_list_ctxt->hl_list_hdl = NULL;
      }
      pal_free (px_hm_ctxt->px_link_list_ctxt);
      px_hm_ctxt->px_link_list_ctxt = NULL;
   }

   e_error = eHM_RET_SUCCESS;
CLEAN_RETURN:
   return e_error;
}
예제 #2
0
// --------------------------------------------------------------------------
// IEE_destroy: ICMP Echo Engine destruction routine.
//
// Parameters:
//   pp_config: Opaque double pointer to a ICMP_ECHO_ENGINE_PARMS structure.
//
// Return values:
//   IEE_SUCCESS on success.
//   IEE_INVALID_PARMS if invalid pp_config.
//
iee_ret_t IEE_destroy( void** pp_config )
{
  PICMP_ECHO_ENGINE_PARMS p_engine = NULL;


  // Verify input parameters.
  if( pp_config == NULL  || *pp_config == NULL )
  {
    // Error: invalid p_config, or already freed.
    return IEE_INVALID_PARMS;
  }

  // Cast opaque double pointer to allow manipulation.
  p_engine = (PICMP_ECHO_ENGINE_PARMS)*pp_config;

  // Close the ICMP raw socket.
  pal_closesocket( p_engine->icmp_sfd );

  // Free the engine echo event list.
  _free_echo_event_list( p_engine->event_list );

  // Deallocate the memory used by the engine structure.
  pal_free( p_engine );
  *pp_config = NULL;

  return IEE_SUCCESS;
}
예제 #3
0
PAL_RET_E pal_sem_destroy(
   PAL_SEM_HDL hl_sem_hdl)
{
   PAL_RET_E       e_error          = ePAL_RET_FAILURE;
   PAL_SEM_CTXT_X *px_sem_ctxt      = NULL;
   BOOL b_mut_ret_val = false;

   if (NULL == hl_sem_hdl)
   {
      PAL_LOG_HIGH("Invalid Handle");
      e_error = ePAL_RET_INVALID_HANDLE;
      goto LBL_CLEANUP;
   }

   px_sem_ctxt = (PAL_SEM_CTXT_X *) hl_sem_hdl;

   b_mut_ret_val = CloseHandle(px_sem_ctxt->hl_sem_hdl);
   if (false == b_mut_ret_val)
   {
      PAL_LOG_HIGH("CloseHandle failed: %d, Errno: %d", b_mut_ret_val, errno);
      e_error = ePAL_RET_SEM_DELETE_FAILED;
   }
   else
   {
      PAL_LOG_FULL("sem_destroy success");
      e_error = ePAL_RET_SUCCESS;
   }
   pal_memset (&(px_sem_ctxt->hl_sem_hdl), 0x00,
      sizeof(px_sem_ctxt->hl_sem_hdl));
   pal_free (px_sem_ctxt);
   px_sem_ctxt = NULL;
LBL_CLEANUP:
   return e_error;
}
예제 #4
0
static DIMUTEX_RET_E dimutex_node_task_handle_algo_complete (
   DIMUTEX_CTXT_X *px_dimutex_ctxt,
   DIMUTEX_MSG_HDR_X *px_msg_hdr)
{
   DIMUTEX_RET_E e_error = eDIMUTEX_RET_FAILURE;
   DIMUTEX_ALGO_COMPLETE_X *px_algo_complete = NULL;

   if ((NULL == px_dimutex_ctxt) || (NULL == px_msg_hdr))
   {
      DMUT_LOG_LOW("Invalid Args");
      e_error = eDIMUTEX_RET_INVALID_ARGS;
      goto CLEAN_RETURN;
   }

   px_algo_complete = (DIMUTEX_ALGO_COMPLETE_X *) px_msg_hdr;

   e_error = dimutex_node_algo_complete (px_dimutex_ctxt,
      &(px_algo_complete->x_stats), 0);
   if (eDIMUTEX_RET_SUCCESS != e_error)
   {
      DMUT_LOG_LOW("dimutex_node_algo_complete failed: %d", e_error);
   }

   pal_free(px_algo_complete);
   px_algo_complete = NULL;
   e_error = eDIMUTEX_RET_SUCCESS;
CLEAN_RETURN:
   return e_error;
}
예제 #5
0
void hm_dealloc_node (
   HM_NODE_DATA_X *px_node_data)
{
   if (NULL != px_node_data)
   {
      if (eHM_KEY_TYPE_STRING == px_node_data->e_hm_key_type)
      {
         if (NULL != px_node_data->u_hm_key.puc_str_key)
         {
            pal_free (px_node_data->u_hm_key.puc_str_key);
            px_node_data->u_hm_key.puc_str_key = NULL;
         }
      }
      pal_free(px_node_data);
      px_node_data = NULL;
   }
}
예제 #6
0
CH_IR_RET_E ch_ir_indexer_deinit(
   CH_IR_INDEXER_CTXT_X *px_indexer_ctxt)
{
   CH_IR_RET_E e_ret_val = eCH_IR_RET_FAILURE;
   HM_FOR_EACH_PARAMS_X x_for_each_param = {eHM_DATA_STRUCT_INVALID};
   HM_RET_E e_hm_ret = eHM_RET_FAILURE;

   if (NULL == px_indexer_ctxt)
   {
      CH_IR_LOG_MED("Invalid Args");
      e_ret_val = eCH_IR_RET_INVALID_ARGS;
      goto CLEAN_RETURN;
   }

   (void) ch_ir_indexer_delete_index (px_indexer_ctxt);
   /*
    * TODO: Cleanup stopwords hashmap.
    */

   if (NULL != px_indexer_ctxt->hl_stopword_hm)
   {
      x_for_each_param.e_data_structure = eHM_DATA_STRUCT_LINKED_LIST;
      x_for_each_param.e_direction = eHM_FOR_EACH_DIRECTION_FORWARD;
      e_hm_ret = hm_for_each_v2 (px_indexer_ctxt->hl_token_hm,
         &x_for_each_param, ch_ir_indexer_stopwords_hm_for_each_delete_cbk,
         px_indexer_ctxt);

      (void) hm_delete_all_nodes (px_indexer_ctxt->hl_stopword_hm);

      (void) hm_delete (px_indexer_ctxt->hl_stopword_hm);
      px_indexer_ctxt->hl_stopword_hm = NULL;
   }

   if (NULL != px_indexer_ctxt->px_dir_parser_ctxt)
   {
      (void) ch_ir_dir_parser_deinit(px_indexer_ctxt->px_dir_parser_ctxt);
      px_indexer_ctxt->px_dir_parser_ctxt = NULL;
   }

   if (NULL != px_indexer_ctxt->px_tokenizer_ctxt)
   {
      (void) ch_ir_tokenizer_deinit(px_indexer_ctxt->px_tokenizer_ctxt);
      px_indexer_ctxt->px_tokenizer_ctxt = NULL;
   }

   if (NULL != px_indexer_ctxt->hl_token_hm)
   {
      (void) hm_delete (px_indexer_ctxt->hl_token_hm);
      px_indexer_ctxt->hl_token_hm = NULL;
   }

   pal_free (px_indexer_ctxt);
   px_indexer_ctxt = NULL;
   e_ret_val = eCH_IR_RET_SUCCESS;

CLEAN_RETURN:
   return e_ret_val;
}
예제 #7
0
파일: tsp_auth.c 프로젝트: MOODOO-SH/gogoc
// --------------------------------------------------------------------------
//
//
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 );
}
예제 #8
0
void list_dealloc_node (
   LIST_NODE_X *px_node)
{
   if (NULL != px_node)
   {
      pal_free(px_node);
      px_node = NULL;
   }
}
예제 #9
0
PAL_RET_E pal_sem_create(
   PAL_SEM_HDL *phl_sem_hdl,
   PAL_SEM_CREATE_PARAM_X *px_create_param)
{
   PAL_RET_E       e_error          = ePAL_RET_FAILURE;
   PAL_SEM_CTXT_X *px_sem_ctxt      = NULL;
   int             i_sem_ret_val    = -1;

   if ((NULL == phl_sem_hdl) || (NULL == px_create_param))
   {
      PAL_LOG_HIGH("Invalid Args");
      e_error = ePAL_RET_INVALID_ARGS;
      goto LBL_CLEANUP;
   }

   if (px_create_param->ui_max_count > PAL_SEM_VALUE_MAX)
   {
      PAL_LOG_HIGH("Invalid Args. ui_max_count cannot be greater than %d"
         " (PAL_SEM_VALUE_MAX)", PAL_SEM_VALUE_MAX);
      e_error = ePAL_RET_INVALID_ARGS;
      goto LBL_CLEANUP;
   }

   *phl_sem_hdl = NULL;

   px_sem_ctxt = (PAL_SEM_CTXT_X *) pal_malloc (sizeof(PAL_SEM_CTXT_X), NULL);
   if(NULL == px_sem_ctxt)
   {
      PAL_LOG_HIGH("pal_malloc failed: %p", px_sem_ctxt);
      e_error = ePAL_RET_OUT_OF_MEMORY;
      goto LBL_CLEANUP;
   }

   (void) pal_memmove (&(px_sem_ctxt->x_create_param), px_create_param,
      sizeof(px_sem_ctxt->x_create_param));

   px_sem_ctxt->hl_sem_hdl = CreateSemaphore(NULL, px_create_param->ui_initial_count, 
      px_create_param->ui_max_count, NULL);
   if (NULL == px_sem_ctxt->hl_sem_hdl)
   {
      perror ("sem_init");
      PAL_LOG_HIGH("CreateSemaphore failed: %d, Errno: %d", i_sem_ret_val, errno);
      pal_free (px_sem_ctxt);
      px_sem_ctxt = NULL;
      e_error = ePAL_RET_SEM_CREATE_FAILED;
   }
   else
   {
      PAL_LOG_FULL("CreateSemaphore success. Initial: %d, Max: %d",
         px_create_param->ui_initial_count, px_create_param->ui_max_count);
      *phl_sem_hdl = (PAL_SEM_HDL) px_sem_ctxt;
      e_error = ePAL_RET_SUCCESS;
   }
LBL_CLEANUP:
   return e_error;
}
예제 #10
0
static void vxlan_fdb_free(struct vxlan_fdb *f)
{
	while (f->remote.remote_next) {
		struct vxlan_rdst *rd = f->remote.remote_next;

		f->remote.remote_next = rd->remote_next;
		pal_free(rd);
	}
	pal_slab_free(f);
}
예제 #11
0
/* Free a broker list */
tRedirectStatus tspFreeBrokerList(tBrokerList *broker_list) {
	tBrokerList *next_broker = NULL;
	
	/* Loop through the list, freeing each element */
	while (broker_list != NULL) {
		next_broker = broker_list->next;
		pal_free(broker_list);
		broker_list = next_broker;
	}

	return TSP_REDIRECT_OK;
}
예제 #12
0
/* Add a new broker element to a list of brokers */
tRedirectStatus tspAddBrokerToList(tBrokerList **broker_list, char *address, tBrokerAddressType address_type, uint32_t distance) {
	tBrokerList *new_broker = NULL;

	/* Some internal error checking */
	if (broker_list == NULL) {
		Display(LOG_LEVEL_1, ELError, "tspAddBrokerToList", GOGO_STR_RDR_ADD_BROKER_INTERNAL_ERR);
		return TSP_REDIRECT_INTERNAL_ERR;
	}

	if (address == NULL) {
		Display(LOG_LEVEL_1, ELError, "tspAddBrokerToList", GOGO_STR_RDR_ADD_BROKER_INTERNAL_ERR);
		return TSP_REDIRECT_INTERNAL_ERR;
	}

	/* Allocate a new broker element */
	if ((new_broker = (tBrokerList *)pal_malloc(sizeof(tBrokerList))) == NULL) {
		Display(LOG_LEVEL_1, ELError, "tspAddBrokerToList", GOGO_STR_RDR_ADD_BROKER_NO_MEM);
		return TSP_REDIRECT_CANT_ALLOCATE_MEM;
	}

	/* Set the broker address */
	pal_snprintf(new_broker->address, MAX_REDIRECT_ADDRESS_LENGTH, "%s", address);

	/* Validate that the address was set correctly */
	if (strlen(new_broker->address) != strlen(address)) {
		pal_free(new_broker);
		Display(LOG_LEVEL_1, ELError, "tspAddBrokerToList", GOGO_STR_RDR_ADD_BROKER_ADDRESS_TRUNC);
		return TSP_REDIRECT_ADDRESS_TRUNCATED;
	}

	/* Set the broker distance */
	new_broker->distance = distance;

	/* Set the broker address type */
	new_broker->address_type = address_type;

	/* Add the new broker element at the end of the list */
	new_broker->next = NULL;

	if (*broker_list == NULL) {
		*broker_list = new_broker;
	}
	else {
		while ((*broker_list)->next != NULL) {
			broker_list = &((*broker_list)->next);
		}

		(*broker_list)->next = new_broker;
	}

	return TSP_REDIRECT_OK;
}
예제 #13
0
파일: net_ka.c 프로젝트: keenser/Maiccu
// --------------------------------------------------------------------------
// _destroy_ka_engine: Deallocates the memory used by the Keepalive engine.
//
// Parameter:
//   pp_engine: Double pointer to the keepalive engine.
//
// Returned values:
//   KA_PRIV_SUCCESS: Operation successful.
//   KA_INVALID_PARMS: Invalid pp_engine pointer.
//
ka_priv_ret_t _destroy_ka_engine( PKA_ENGINE_PARMS* pp_engine )
{
  if( pp_engine == NULL  ||  *pp_engine == NULL )
  {
    // Bad parameter: invalid double pointer or already freed.
    return KA_INVALID_PARMS;
  }

  // Free the reources allocated for the Keepalive engine.
  pal_free( *pp_engine );
  *pp_engine = NULL;

  return KA_PRIV_SUCCESS;
}
예제 #14
0
SOCKMON_RET_E dimutex_node_sockmon_active_sock_cbk (
   SOCKMON_SOCK_ACTIVITY_STATUS_E e_status,
   PAL_SOCK_HDL hl_sock_hdl,
   void *p_app_data)
{
   SOCKMON_RET_E e_sockmon_ret = eSOCKMON_RET_FAILURE;
   DIMUTEX_RET_E e_error = eDIMUTEX_RET_FAILURE;
   DIMUTEX_CTXT_X *px_dimutex_ctxt = NULL;
   DIMUTEX_NODE_SOCK_ACT_DATA_X *px_sock_act_data = NULL;

   if ((NULL == hl_sock_hdl) || (NULL == p_app_data))
   {
      DMUT_LOG_LOW("Invalid Args");
      e_sockmon_ret = eSOCKMON_RET_INVALID_ARGS;
      goto CLEAN_RETURN;
   }

   px_dimutex_ctxt = (DIMUTEX_CTXT_X *) p_app_data;

   DMUT_LOG_LOW("dimutex_node_sockmon_active_sock_cbk called.");

   px_sock_act_data = pal_malloc (sizeof(DIMUTEX_NODE_SOCK_ACT_DATA_X),
      NULL );

   px_sock_act_data->x_hdr.ui_msg_id = eDIMUTEX_MSG_ID_LISTENER_SOCK_ACT;
   px_sock_act_data->x_hdr.ui_msg_pay_len = sizeof(*px_sock_act_data) -
         sizeof(px_sock_act_data->x_hdr);
   px_sock_act_data->hl_sock_hdl = hl_sock_hdl;
   e_error = dimutex_post_msg_to_q (
      px_dimutex_ctxt,
      (uint8_t *) px_sock_act_data,
      sizeof(*px_sock_act_data));
   if (eDIMUTEX_RET_SUCCESS != e_error)
   {
      DMUT_LOG_LOW("dimutex_post_msg_to_q failed: %d", e_error);
      pal_free(px_sock_act_data);
      px_sock_act_data = NULL;
      e_sockmon_ret = eSOCKMON_RET_RESOURCE_FAILURE;
   }
   else
   {
      e_sockmon_ret = eSOCKMON_RET_SUCCESS;
   }

CLEAN_RETURN:
   return e_sockmon_ret;
}
예제 #15
0
static HM_TABLE_ENTRY_X *hm_get_new_table_entry_from_hash (
   HM_CTXT_X *px_hm_ctxt,
   uint32_t ui_hash)
{
   HM_TABLE_ENTRY_X *px_hm_table_entry = NULL;
   LIST_RET_E e_list_ret = eLIST_RET_FAILURE;
   LIST_INIT_PARAMS_X x_init_params = {0};

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

   px_hm_table_entry = px_hm_ctxt->ppx_hash_table[ui_hash];
   if (NULL == px_hm_table_entry)
   {
      HM_LOG_HIGH("Table entry @ %d position needs to be allocated", ui_hash);
      px_hm_table_entry = pal_malloc (sizeof(HM_TABLE_ENTRY_X), NULL);
      if (NULL == px_hm_table_entry)
      {
         HM_LOG_MED("pal_malloc failed");
         goto CLEAN_RETURN;
      }
      px_hm_ctxt->ppx_hash_table[ui_hash] = px_hm_table_entry;
   }

   if (NULL == px_hm_table_entry->hl_list_hdl)
   {
      HM_LOG_HIGH("List @ %d position needs to be allocated", ui_hash);
      x_init_params.ui_list_max_elements = LIST_SIZE_UNLIMITED;
      e_list_ret = list_create (&(px_hm_table_entry->hl_list_hdl),
         &x_init_params);
      if ((eLIST_RET_SUCCESS != e_list_ret)
         || (NULL == px_hm_table_entry->hl_list_hdl))
      {
         HM_LOG_MED("list_create failed: %d",
            e_list_ret, px_hm_table_entry->hl_list_hdl);
         pal_free (px_hm_table_entry);
         px_hm_table_entry = NULL;
      }
   }

CLEAN_RETURN:
   return px_hm_table_entry;
}
static DIMUTEX_RET_E dimutex_algo_post_complete_to_main_task (
   DIMUTEX_CTXT_X *px_dimutex_ctxt)
{
   DIMUTEX_RET_E e_error = eDIMUTEX_RET_FAILURE;
   DIMUTEX_ALGO_COMPLETE_X *px_algo_complete = NULL;

   if (NULL == px_dimutex_ctxt)
   {
      DMUT_LOG_LOW("Invalid Args");
      e_error = eDIMUTEX_RET_INVALID_ARGS;
      goto CLEAN_RETURN;
   }

   px_algo_complete = pal_malloc (sizeof(DIMUTEX_ALGO_COMPLETE_X), NULL);
   if (NULL == px_algo_complete)
   {
      DMUT_LOG_LOW("pal_malloc failed");
      e_error = eDIMUTEX_RET_RESOURCE_FAILURE;
      goto CLEAN_RETURN;
   }

   DMUT_LOG_LOW("Posting eDIMUTEX_MSG_ID_ALGO_COMPLETE to myself");
   px_algo_complete->x_hdr.ui_msg_id = eDIMUTEX_MSG_ID_ALGO_COMPLETE;
   px_algo_complete->x_hdr.ui_msg_pay_len = sizeof(*px_algo_complete) -
         sizeof(px_algo_complete->x_hdr);

   (void) pal_memmove (&(px_algo_complete->x_stats),
      &(px_dimutex_ctxt->x_algo.x_algo_stats),
      sizeof(px_algo_complete->x_stats));

   e_error = dimutex_post_msg_to_q (px_dimutex_ctxt,
      (uint8_t *) px_algo_complete, sizeof(*px_algo_complete));
   if (eDIMUTEX_RET_SUCCESS != e_error)
   {
      DMUT_LOG_LOW("dimutex_post_msg_to_q failed: %d", e_error);
      pal_free (px_algo_complete);
      px_algo_complete = NULL;
   }
   else
   {
      e_error = eDIMUTEX_RET_SUCCESS;
   }
CLEAN_RETURN:
   return e_error;
}
예제 #17
0
HM_RET_E hm_delete_table_entry_from_hash (
   HM_CTXT_X *px_hm_ctxt,
   HM_NODE_DATA_X *px_node_data)
{
   HM_RET_E e_error = eHM_RET_FAILURE;
   LIST_RET_E e_list_ret = eLIST_RET_FAILURE;
   HM_TABLE_ENTRY_X *px_hm_table_entry = NULL;
   uint32_t ui_hash = 0;

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

   e_error = hm_get_hash_from_node_data (px_hm_ctxt, px_node_data, &ui_hash);
   if (eHM_RET_SUCCESS != e_error)
   {
      HM_LOG_MED("hashmap_gen_hash_from_buf failed: %d", e_error);
      goto CLEAN_RETURN;
   }
   HM_LOG_MED("Hash Value: %d", ui_hash);

   px_hm_table_entry = px_hm_ctxt->ppx_hash_table[ui_hash];
   if (NULL != px_hm_table_entry)
   {
      if (NULL != px_hm_table_entry->hl_list_hdl)
      {
         e_list_ret = list_delete (px_hm_table_entry->hl_list_hdl);
         if (eLIST_RET_SUCCESS != e_list_ret)
         {
            HM_LOG_MED("list_delete failed: %d", e_list_ret);
         }
         px_hm_table_entry->hl_list_hdl = NULL;
      }
      pal_free (px_hm_table_entry);
      px_hm_table_entry = NULL;

      px_hm_ctxt->ppx_hash_table[ui_hash] = NULL;
   }
   e_error = eLIST_RET_SUCCESS;
CLEAN_RETURN:
   return e_error;
}
예제 #18
0
/****************************** LOCAL FUNCTIONS *******************************/
LIST_RET_E list_create_private (
   LIST_CTXT_X **ppx_list_ctxt,
   LIST_INIT_PARAMS_X *px_init_params)
{
   LIST_RET_E e_error = eLIST_RET_FAILURE;
   LIST_CTXT_X *px_list_ctxt = NULL;

   if ((NULL == ppx_list_ctxt) || (NULL == px_init_params))
   {
      LIST_LOG_MED("Invalid Args");
      e_error = eLIST_RET_INVALID_ARGS;
      goto CLEAN_RETURN;
   }

   *ppx_list_ctxt = NULL;

   px_list_ctxt = pal_malloc (sizeof(LIST_CTXT_X), NULL);
   if (NULL == px_list_ctxt)
   {
      LIST_LOG_MED("pal_malloc failed: %p", px_list_ctxt);
      e_error = eLIST_RET_RESOURCE_FAILURE;
      goto CLEAN_RETURN;
   }

   (void) pal_memmove(&(px_list_ctxt->x_init_params), px_init_params,
      sizeof(px_list_ctxt->x_init_params));
   px_list_ctxt->px_head = NULL;
   px_list_ctxt->px_tail = NULL;
   px_list_ctxt->ui_node_count = 0;
   *ppx_list_ctxt = px_list_ctxt;
   LIST_LOG_HIGH("List of size %d create success",
      px_init_params->ui_list_max_elements);
   e_error = eLIST_RET_SUCCESS;
CLEAN_RETURN:
   if (eLIST_RET_SUCCESS != e_error)
   {
      if (NULL != px_list_ctxt)
      {
         pal_free (px_list_ctxt);
         px_list_ctxt = NULL;
      }
   }
   return e_error;
}
예제 #19
0
CH_IR_RET_E ch_ir_tokenizer_deinit(
   CH_IR_TOKENIZER_CTXT_X *px_tokenizer_ctxt)
{
   CH_IR_RET_E e_ret_val = eCH_IR_RET_FAILURE;

   if (NULL == px_tokenizer_ctxt)
   {
      CH_IR_LOG_MED("Invalid Args");
      e_ret_val = eCH_IR_RET_INVALID_ARGS;
      goto CLEAN_RETURN;
   }

   pal_free (px_tokenizer_ctxt);
   px_tokenizer_ctxt = NULL;
   e_ret_val = eCH_IR_RET_SUCCESS;

CLEAN_RETURN:
   return e_ret_val;
}
예제 #20
0
LIST_RET_E list_delete_private (
   LIST_CTXT_X *px_list_ctxt)
{
   LIST_RET_E e_error = eLIST_RET_FAILURE;

   if (NULL == px_list_ctxt)
   {
      LIST_LOG_MED("Invalid Handle");
      e_error = eLIST_RET_INVALID_HANDLE;
      goto CLEAN_RETURN;
   }

   pal_free(px_list_ctxt);
   px_list_ctxt = NULL;
   LIST_LOG_HIGH("List delete success");
   e_error = eLIST_RET_SUCCESS;
CLEAN_RETURN:
   return e_error;
}
예제 #21
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;
}
예제 #22
0
static CH_IR_RET_E ch_ir_tokenizer_parse_line(
   CH_IR_TOKENIZER_CTXT_X *px_tokenizer_ctxt,
   uint8_t *puc_line,
   uint8_t *puc_file_path,
   uint32_t ui_file_idx)
{
   CH_IR_RET_E e_ret_val = eCH_IR_RET_FAILURE;
   uint8_t uc_c = 0;
   uint32_t ui_i = 0;
   bool b_ignore = false;
   bool b_break = false;
   uint8_t *puc_token = NULL;
   uint32_t ui_token_len = 0;
   bool b_only_numerals = false;

   if ((NULL == px_tokenizer_ctxt) || (NULL == puc_line)
      || (NULL == puc_file_path))
   {
      CH_IR_LOG_MED("Invalid Args");
      e_ret_val = eCH_IR_RET_INVALID_ARGS;
      goto CLEAN_RETURN;
   }

   puc_token = pal_malloc (px_tokenizer_ctxt->x_init_params.ui_max_token_len,
      NULL);
   if (NULL == puc_token)
   {
      CH_IR_LOG_MED("pal_malloc failed");
      e_ret_val = eCH_IR_RET_RESOURCE_FAILURE;
      goto CLEAN_RETURN;
   }

   while (1)
   {
      uc_c = puc_line [ui_i];

      switch (uc_c)
      {
         case '\0':
         {
            if (ui_token_len > 0)
            {
               puc_token [ui_token_len] = '\0';

               if ('\'' == puc_token [0] && '\'' == puc_token [ui_token_len - 1])
               {
                  pal_memmove (puc_token, &puc_token [1], ui_token_len - 2);
                  puc_token [ui_token_len - 2] = '\0';
               }

               ch_ir_tokenizer_handle_token (px_tokenizer_ctxt, puc_token,
                  puc_file_path, ui_file_idx);

               (void) pal_memset (puc_token, 0x00,
                  px_tokenizer_ctxt->x_init_params.ui_max_token_len);
               ui_token_len = 0;
            }
            b_break = true;
            break;
         }
         case '<':
         {
            b_ignore = true;
            break;
         }
         case '>':
         {
            b_ignore = true;
            break;
         }
         case '.':
         {
            if (ui_token_len > 0)
            {
               puc_token [ui_token_len] = '\0';

               b_only_numerals = ch_ir_tokenizer_does_token_contain_only_numerals (puc_token);
               if ((true == b_only_numerals) && ('\0' != puc_line [ui_i + 1])
                  && ((puc_line [ui_i + 1] >= '0') && (puc_line [ui_i + 1] <= '9')))
               {
                  /*
                   * Handle the following case:
                   *    1. 10.901
                   */
                  puc_token [ui_token_len] = '.';
                  ui_token_len++;
               }
               else
               {

                  ch_ir_tokenizer_handle_token (px_tokenizer_ctxt, puc_token,
                     puc_file_path, ui_file_idx);

                  (void) pal_memset (puc_token, 0x00,
                     px_tokenizer_ctxt->x_init_params.ui_max_token_len);
                  ui_token_len = 0;
               }
            }
            break;
         }
         case ',':
         case '!':
         case ' ':
         case '(':
         case ')':
         case '/':
            /*
             * All these are considered as delimiters.
             */
         {
            if (ui_token_len > 0)
            {
               puc_token [ui_token_len] = '\0';

               if ('\'' == puc_token [0] && '\'' == puc_token [ui_token_len - 1])
               {
                  pal_memmove (puc_token, &puc_token [1], ui_token_len - 3);
                  puc_token [ui_token_len - 2] = '\0';
               }

               ch_ir_tokenizer_handle_token (px_tokenizer_ctxt, puc_token,
                  puc_file_path, ui_file_idx);

               (void) pal_memset (puc_token, 0x00,
                  px_tokenizer_ctxt->x_init_params.ui_max_token_len);
               ui_token_len = 0;
            }
            break;
         }
         default:
         {
            if (true == b_ignore)
            {
               break;
            }
            else
            {
               puc_token [ui_token_len] = tolower (uc_c);
               ui_token_len++;
            }
         }
      }

      if (true == b_break)
      {
         break;
      }

      ui_i++;
   }
   e_ret_val = eCH_IR_RET_SUCCESS;
CLEAN_RETURN:
   if (NULL != puc_token)
   {
      pal_free (puc_token);
      puc_token = NULL;
   }
   return e_ret_val;
}
예제 #23
0
파일: imain.c 프로젝트: jeras/iverilog
/*
 * This is the main entry point that Icarus Verilog calls to generate
 * code for a pal.
 */
int target_design(ivl_design_t des)
{
      unsigned idx;
      const char*part;
      ivl_scope_t root;

	/* Get the part type from the design, using the "part"
	   key. Given the part type, try to open the pal description
	   so that we can figure out the device. */
      part = ivl_design_flag(des, "part");
      if ((part == 0) || (*part == 0)) {
	    fprintf(stderr, "error: part must be specified. Specify a\n");
	    fprintf(stderr, "     : type with the -fpart=<type> option.\n");
	    return -1;
      }

      pal = pal_alloc(part);
      if (pal == 0) {
	    fprintf(stderr, "error: %s is not a valid part type.\n", part);
	    return -1;
      }

      assert(pal);

      pins = pal_pins(pal);
      assert(pins > 0);

	/* Allocate the pin array, ready to start assigning resources. */
      bind_pin = calloc(pins, sizeof (struct pal_bind_s));

	/* Connect all the macrocells that drive pins to the pin that
	   they drive. This doesn't yet look at the design, but is
	   initializing the bind_pin array with part information. */
      for (idx = 0 ;  idx < pal_sops(pal) ;  idx += 1) {
	    pal_sop_t sop = pal_sop(pal, idx);
	    int spin = pal_sop_pin(sop);

	    if (spin == 0)
		  continue;

	    assert(spin > 0);
	    bind_pin[spin-1].sop = sop;
      }


	/* Get pin assignments from the user. This is the first and
	   most constrained step. Everything else must work around the
	   results of these bindings. */
      root = ivl_design_root(des);
      get_pad_bindings(root, 0);

      if (pal_errors) {
	    fprintf(stderr, "PAD assignment failed.\n");
	    pal_free(pal);
	    return -1;
      }

	/* Run through the assigned output pins and absorb the output
	   enables that are connected to them. */
      absorb_pad_enables();

	/* Scan all the registers, and assign them to
	   macro-cells. */
      root = ivl_design_root(des);
      fit_registers(root, 0);
      if (pal_errors) {
	    fprintf(stderr, "Register fitting failed.\n");
	    pal_free(pal);
	    return -1;
      }

      fit_logic();
      if (pal_errors) {
	    fprintf(stderr, "Logic fitting failed.\n");
	    pal_free(pal);
	    return -1;
      }

      dump_final_design(stdout);
      emit_jedec(ivl_design_flag(des, "-o"));

      pal_free(pal);
      return 0;
}
예제 #24
0
파일: tsp_auth.c 프로젝트: MOODOO-SH/gogoc
// --------------------------------------------------------------------------
// 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);
}
예제 #25
0
int main (int argc, char **argv)
{
   APP_RET_E e_main_ret = eAPP_RET_FAILURE;
   PAL_RET_E e_pal_ret = ePAL_RET_FAILURE;
   APP_CTXT_X *px_app_ctxt = NULL;
   bool b_pal_init = false;
   int32_t i_command = -1;
   int32_t i_ret = -1;
   PAL_LOGGER_INIT_PARAMS_X x_logger_params = {false};

   e_pal_ret = pal_env_init();
   if (ePAL_RET_SUCCESS != e_pal_ret)
   {
      goto CLEAN_RETURN;
   }
   b_pal_init = true;

   px_app_ctxt = pal_malloc(sizeof(APP_CTXT_X), NULL);
   if (NULL == px_app_ctxt)
   {
      goto CLEAN_RETURN;
   }

   e_main_ret = app_parse_cmd_line (px_app_ctxt, argc, argv);
   if (eAPP_RET_SUCCESS != e_main_ret)
   {
      goto CLEAN_RETURN;
   }

   x_logger_params.b_enable_console_logging =
         (0 == px_app_ctxt->x_app_args.ui_enable_console_logging) ?
               false : true;
   x_logger_params.b_enable_file_logging = true;
   (void) pal_strncpy (x_logger_params.uca_filename_prefix,
      (uint8_t *) "dimutex_log_node_",
      sizeof(x_logger_params.uca_filename_prefix));
   x_logger_params.ui_file_name_suffix = px_app_ctxt->x_app_args.ui_node_index;
   pal_logger_env_init(&x_logger_params);

   e_main_ret = app_env_init (px_app_ctxt);
   if (eAPP_RET_SUCCESS != e_main_ret)
   {
      goto CLEAN_RETURN;
   }

   while (1)
   {
      i_ret = scanf ("%d", &i_command); (void) i_ret;
      if (1 == i_command)
      {
         break;
      }
   }

   e_main_ret = app_env_deinit (px_app_ctxt);
   if (eAPP_RET_SUCCESS != e_main_ret)
   {
   }

   pal_logger_env_deinit ();
CLEAN_RETURN:
   if (NULL != px_app_ctxt)
   {
      pal_free(px_app_ctxt);
      px_app_ctxt = NULL;
   }
   if (true == b_pal_init)
   {
      e_pal_ret = pal_env_deinit();
      if (ePAL_RET_SUCCESS != e_pal_ret)
      {
         e_main_ret = eAPP_RET_FAILURE;
      }
      b_pal_init = false;
   }
   return (int) e_main_ret;
}
예제 #26
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 );
  }
}
예제 #27
0
HM_RET_E hm_delete_all_nodes_pvt (
   HM_CTXT_X *px_hm_ctxt)
{
   HM_RET_E e_error = eHM_RET_FAILURE;
   PAL_RET_E e_pal_ret = ePAL_RET_FAILURE;
   bool b_locked = false;
   HM_TABLE_ENTRY_X *px_hm_table_entry = NULL;
   LIST_RET_E e_list_ret = eLIST_RET_FAILURE;
   uint32_t ui_list_len = 0;
   uint32_t ui_i = 0;
   LIST_NODE_DATA_X x_node_data = {NULL};
   HM_NODE_DATA_X *px_node_data = NULL;

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

   if (NULL != px_hm_ctxt->hl_mutex_hdl)
   {
      e_pal_ret = pal_mutex_lock(px_hm_ctxt->hl_mutex_hdl);
      if (ePAL_RET_SUCCESS != e_pal_ret)
      {
         HM_LOG_MED("pal_mutex_lock failed: %d", e_pal_ret);
         e_error = eHM_RET_RESOURCE_FAILURE;
         goto CLEAN_RETURN;
      }
      b_locked = true;
   }

   for (ui_i = 0; ui_i < px_hm_ctxt->x_init_params.ui_hm_table_size; ui_i++)
   {
      px_hm_table_entry = px_hm_ctxt->ppx_hash_table[ui_i];
      if (NULL == px_hm_table_entry)
      {
         continue;
      }
      if (NULL != px_hm_table_entry->hl_list_hdl)
      {
         do
         {
            (void) pal_memset(&x_node_data, 0x00, sizeof(x_node_data));
            e_list_ret = list_node_delete_at_head (
               px_hm_table_entry->hl_list_hdl, &x_node_data);
            if (NULL != x_node_data.p_data)
            {
               px_node_data = (HM_NODE_DATA_X *) x_node_data.p_data;
               hm_dealloc_node (px_node_data);
               px_node_data = NULL;
            }

            e_list_ret = list_node_peek_at_head (px_hm_table_entry->hl_list_hdl,
               &x_node_data);
         } while (eLIST_RET_LIST_EMPTY != e_list_ret);

         e_list_ret = list_delete (px_hm_table_entry->hl_list_hdl);
         if (eLIST_RET_SUCCESS != e_list_ret)
         {
            HM_LOG_MED("list_delete failed: %d", e_list_ret);
         }
         px_hm_table_entry->hl_list_hdl = NULL;
      }

      pal_free (px_hm_table_entry);
      px_hm_table_entry = NULL;

      px_hm_ctxt->ppx_hash_table[ui_i] = NULL;
   }

   if (NULL != px_hm_ctxt->px_link_list_ctxt)
   {
      if (NULL != px_hm_ctxt->px_link_list_ctxt->hl_list_hdl)
      {
         do
         {
            e_list_ret = list_node_delete_at_head (
               px_hm_ctxt->px_link_list_ctxt->hl_list_hdl, &x_node_data);
         } while (eLIST_RET_LIST_EMPTY != e_list_ret);
      }
   }
   e_error = eHM_RET_SUCCESS;
CLEAN_RETURN:
   if ((true == b_locked) && (NULL != px_hm_ctxt->hl_mutex_hdl))
   {
      e_pal_ret = pal_mutex_unlock(px_hm_ctxt->hl_mutex_hdl);
      if (ePAL_RET_SUCCESS != e_pal_ret)
      {
         HM_LOG_MED("pal_mutex_unlock failed: %d", e_pal_ret);
         e_error = eHM_RET_RESOURCE_FAILURE;
      }
   }
   return e_error;
}
예제 #28
0
// --------------------------------------------------------------------------
// IEE_init: ICMP Echo Engine initialisation routine.
//
// Parameters:
//   pp_config: Opaque double pointer to a ICMP_ECHO_ENGINE_PARMS structure.
//   eng_mode: The mode of the ICMP Echo Engine.
//   send_interval: Fixed interval, in miliseconds, at which ICMP echo
//     requests will be issued.
//   echo_num: Number of ICMP echo requests to issue(0=infinite).
//   echo_timeout: Number of miliseconds after which an unanswered ICMP
//     echo request will be marked as timed out.
//   echo_timeout_threshold: Number of consecutive timed-out ICMP echo
//     requests to declare a general echo timeout.
//   src: Source address used for sending ICMP echo requests.
//   dst: Destination address at which ICMP echo requests will be sent.
//   family: address family (INET or INET6)
//
// Return values:
//   IEE_SUCCESS on success.
//   IEE_INVALID_PARMS if invalid pp_config.
//
iee_ret_t IEE_init( void** pp_config, iee_mode_t eng_mode,
                   uint32_t send_interval, uint32_t echo_num,
                   uint32_t echo_timeout, uint8_t echo_timeout_threshold,
                   char* src, char* dst, sint32_t af,
                   iee_send_clbk send_clbk, iee_recv_clbk recv_clbk )
{
  PICMP_ECHO_ENGINE_PARMS p_engine = NULL;


  // Verify input parameters.
  if( pp_config == NULL  ||  *pp_config != NULL  ||  dst == NULL )
  {
    // Error: bad input parameters.
    return IEE_INVALID_PARMS;
  }

  // Reserve memory for the engine parameters
  *pp_config = pal_malloc( sizeof(ICMP_ECHO_ENGINE_PARMS) );
  p_engine = (PICMP_ECHO_ENGINE_PARMS)*pp_config;
  if( p_engine == NULL )
  {
    // Error: Not enough memory for structure.
    return IEE_RESOURCE_STARVATION;
  }

  // Initialize engine structure with input parameters.
  memset( p_engine, 0, sizeof(ICMP_ECHO_ENGINE_PARMS) );
  p_engine->send_interval          = send_interval;
  p_engine->echo_num               = echo_num;
  p_engine->echo_timeout           = echo_timeout;    // Not used in ACD
  p_engine->echo_timeout_threshold = echo_timeout_threshold;
  p_engine->eng_mode               = eng_mode;

  // Initialize engine variables.
  p_engine->eng_ongoing       = 1;
  p_engine->count_send        = 0;
  p_engine->count_late        = 0;
  p_engine->count_ontime      = 0;
  p_engine->count_consec_late = 0;
  p_engine->event_list = NULL;

  // Set engine callback functions.
  p_engine->clbk_send = send_clbk;
  p_engine->clbk_recv = recv_clbk;

  // Initialize engine socket variables.
  p_engine->icmp_echo_id = pal_getpid();
  p_engine->icmp_saf = af;
  switch( p_engine->icmp_saf )
  {
  case AF_INET:
    if( pal_inet_pton( AF_INET, src, &p_engine->echo_addr_src.in4.sin_addr ) <= 0 )
    {
      // Bad IPv4 address in 'src'.
      pal_free( p_engine );
      return IEE_INVALID_PARMS;
    }
    p_engine->echo_addr_src.in4.sin_family = AF_INET;

    if( pal_inet_pton( AF_INET, dst, &p_engine->echo_addr_dst.in4.sin_addr ) <= 0 )
    {
      // Bad IPv4 address in 'dst'.
      pal_free( p_engine );
      return IEE_INVALID_PARMS;
    }
    p_engine->echo_addr_dst.in4.sin_family = AF_INET;

    p_engine->icmp_sfd = pal_socket( AF_INET, SOCK_RAW, IPPROTO_ICMP );
    break;

  case AF_INET6:
    if( pal_inet_pton( AF_INET6, src, &p_engine->echo_addr_src.in6.sin6_addr ) <= 0 )
    {
      // Bad IPv6 address in 'src'.
      pal_free( p_engine );
      return IEE_INVALID_PARMS;
    }
    p_engine->echo_addr_src.in6.sin6_family = AF_INET6;

    if( pal_inet_pton( AF_INET6, dst, &p_engine->echo_addr_dst.in6.sin6_addr ) <= 0 )
    {
      // Bad IPv6 address in 'dst'.
      pal_free( p_engine );
      return IEE_INVALID_PARMS;
    }
    p_engine->echo_addr_dst.in6.sin6_family = AF_INET6;

    p_engine->icmp_sfd = pal_socket( AF_INET6, SOCK_RAW, IPPROTO_ICMPV6 );
    break;

  default:
    // ERROR! Bad address family!
    pal_free( p_engine );
    return IEE_INVALID_PARMS;
  }

  // Verify that the socket created is valid.
  if( p_engine->icmp_sfd == -1 )
  {
    // Failed to open a socket descriptor.
    pal_free( p_engine );
    return IEE_GENERAL_ECHO_ERROR;
  }

  return IEE_SUCCESS;
}
예제 #29
0
/** Add a DSA key to the tspc key file
 *
 * @param dsa        the DSA param pointer filled with our key info
 * @param host       the hostname of the corresponding broker
 * @param filename   the keyfile to use
 *
 * @return  0 if error
 *          1 if ok
 *
 */
int
add_dsakey_to_keyfile(DSA *dsa, char *host, char *filename, tBoolean autoaccept)
{

  FILE *fp = NULL;
  Buffer buf;
  char *str = NULL;
  int ret = 0;

  switch (is_dsakey_in_keyfile(dsa, host, filename)) {

  case 0:
    Display(LOG_LEVEL_3, ELInfo, TSP_AUTH_PASSDSS_STRING, GOGO_STR_ERR_IN_KEY_VERIF);
    Display(LOG_LEVEL_3, ELWarning, TSP_AUTH_PASSDSS_STRING, GOGO_STR_SERVER_KEY_REJECTED);
    break;
  case 1: /* not in, we add and continue */
#if defined(WIN32) && !defined(WINCE)
// When running as a service we can't ask user
// permission. Compromise and accept the key auto
//
    if (!IsService && !autoaccept)
    {
#else
    if (!autoaccept)
    {
#endif
      if (!ask(GOGO_STR_UNKNOWN_HOST_ADD_KEY, host))
      {
        Display(LOG_LEVEL_3, ELWarning, TSP_AUTH_PASSDSS_STRING, GOGO_STR_SERVER_KEY_REJECTED_USER);
        break;
      }
    }
    else
  Display(LOG_LEVEL_1, ELWarning, TSP_AUTH_PASSDSS_STRING, GOGO_STR_WARN_SERVER_KEY_AUTO_ADDED);

    Display(LOG_LEVEL_2, ELInfo, TSP_AUTH_PASSDSS_STRING, GOGO_STR_SERVER_KEY_ACCEPTED_ADDED);

    buffer_init(&buf);
    if (buf.buf == NULL)
      break;
    buffer_put_cstring(&buf, "ssh-dss");
    buffer_put_bignum(&buf, dsa->p);
    buffer_put_bignum(&buf, dsa->q);
    buffer_put_bignum(&buf, dsa->g);
    buffer_put_bignum(&buf, dsa->pub_key);

    if ( (str = pal_malloc(2 * buffer_len(&buf))) == NULL)
      break;

    if ( (base64encode(str, buffer_ptr(&buf), (int) buffer_len(&buf))) < 1)
      break;

    fp = fopen(filename, "a");
    if (fp) {
      fprintf(fp, "%s ssh-dss %s\n", host, str);
      fclose(fp);
      ret = 1;
    }
    buffer_free(&buf);
    pal_free(str);
    break;
  case 2: /* in and matching correctly, hurray */
    Display(LOG_LEVEL_2, ELInfo, TSP_AUTH_PASSDSS_STRING, GOGO_STR_MATCHING_KEY_FOUND_USED);
    ret = 1;
    break;
  case 3: /* in and NOT matching correctly */
    Display(LOG_LEVEL_1, ELError, TSP_AUTH_PASSDSS_STRING, GOGO_STR_WARN_STORED_LOCAL_KEY_NO_MATCH, filename, host);
  Display(LOG_LEVEL_3, ELWarning, TSP_AUTH_PASSDSS_STRING, GOGO_STR_SERVER_KEY_REJECTED);
    ret = 0;
    break;
  }

  return ret;
}


/**
 * Authenticate to the Migration Broker using PASSDSS-3DES-1
 *
 * Buf_H will contain the data used to validate the server
 * signature. The data is a concatenation of the following parameters,
 * in that order:
 * azname,authname,DH_public_key,pklength,"ssh-dss",p,q,g,z,Y,ssecmask,sbuflen,dh_K
 *
 * @param socket
 * @param user
 * @param passwd
 * @param host
 * @param nt
 *
 * @return
 *
 * @todo DH public key validation  (RFC2631, 2.1.5)
 * @todo Local storage for server public keys
 *
 */
gogoc_status AuthPASSDSS_3DES_1(pal_socket_t socket, net_tools_t *nt, tConf *conf, tBrokerList **broker_list)
{
  DH   *dh = NULL;        /**< client DH key used to exchange key with server */
  DSA  *dsa = NULL; /**< Remote server DSA key public information */
  DSA_SIG *sig = NULL;    /**< DSA signature */
  char authenticate[] = "AUTHENTICATE PASSDSS-3DES-1\r\n";
  char *BufferIn  = NULL;
  char *BufferOut = NULL;
  char *BufferPtr = NULL;
  Buffer BufH;    /**< Buffer to hold data used for signature. */
  Buffer BufSpace;  /**< Space to hold data before/after base64 conversion */
  Buffer *Buf_H = &BufH;
  Buffer *Buf_Space = &BufSpace;
  BIO  *bio_rw = NULL;    /**< Memory buffer bio */
  BIO  *b64= NULL;    /**< Base64 bio */
  BIO  *cipher = NULL;    /**< Symmetric crypto bio */
  BIGNUM *server_pubkey = NULL; /**< received server public DH key */
  BIGNUM *dh_K = NULL;          /**< DH computed shared secret */
  u_char hash[20];  /**< SHA1 hash */
  u_char enc_key[24]; /**< encryption key (3des) */
  u_char enc_iv[8]; /**< initialization vector (3des) */
  u_char int_key[20]; /**< cs integrity key */
  u_char tmphash[40]; /**< temporary hash storage */
  u_char hmac[EVP_MAX_MD_SIZE]; /**< HMAC for integrity of sent data (step L) */
  int  pklength = 0;  /**< length of SSH-style DSA server public key */
  int ssecmask = 0; /**< SASL security layers offered */
  int sbuflen = 0;  /**< maximum server security layer block size */
  char *s = NULL;
  u_char num[3];    /**< Array to manupulate 3 octet number (sbuflen)  */
  /* Temporary variables */
  int  buflen, readlen, keysize, siglength;
  gogoc_status status = STATUS_SUCCESS_INIT;
  sint32_t tsp_status;

/* From draft-newman-sasl-passdss-01.  "This group was taken from the
 * ISAKMP/Oakley specification, and was originally generated by
 * Richard Schroeppel at the University of Arizona.  Properties of
 * this prime are described in [Orm96]"
 */

        /* RFC2409, DH group 2 (second Oakley group) */
  static char *dh_group2=
      "FFFFFFFF" "FFFFFFFF" "C90FDAA2" "2168C234" "C4C6628B" "80DC1CD1"
      "29024E08" "8A67CC74" "020BBEA6" "3B139B22" "514A0879" "8E3404DD"
      "EF9519B3" "CD3A431B" "302B0A6D" "F25F1437" "4FE1356D" "6D51C245"
      "E485B576" "625E7EC6" "F44C42E9" "A637ED6B" "0BFF5CB6" "F406B7ED"
      "EE386BFB" "5A899FA5" "AE9F2411" "7C4B1FE6" "49286651" "ECE65381"
      "FFFFFFFF" "FFFFFFFF";
  static unsigned char dh_g[]={
    0x02,
  };


  /* Initialize Diffie Hellman variables */
  if ((dh = DH_new()) == NULL || (server_pubkey = BN_new()) == NULL)
  {
    Display(LOG_LEVEL_1, ELError, TSP_AUTH_PASSDSS_STRING, STR_GEN_MALLOC_ERROR);
    status = make_status(CTX_TSPAUTHENTICATION, ERR_MEMORY_STARVATION);
    goto error;
  }
  /* Convert dh_group2 and dh_g to BIGNUM type */
  BN_hex2bn(&dh->p, dh_group2);
  dh->g = BN_bin2bn(dh_g,sizeof(dh_g),NULL);
  if ((dh->p == NULL) || (dh->g == NULL))
  {
    Display(LOG_LEVEL_1, ELError, TSP_AUTH_PASSDSS_STRING, GOGO_STR_INITIALIZATION_ERROR);
    status = make_status(CTX_TSPAUTHENTICATION, ERR_AUTHENTICATION_FAILURE);
    goto error;
  }
  if ((dh_K = BN_new()) == NULL)
  {
    Display(LOG_LEVEL_1, ELError, TSP_AUTH_PASSDSS_STRING, STR_GEN_MALLOC_ERROR);
    status = make_status(CTX_TSPAUTHENTICATION, ERR_MEMORY_STARVATION);
    goto error;
  }

  /* Reserve storage for DSA key */
  if ((dsa = DSA_new()) == NULL || (dsa->p = BN_new()) == NULL ||
      (dsa->q = BN_new()) == NULL ||  (dsa->g = BN_new()) == NULL ||
      (dsa->pub_key = BN_new()) == NULL || (dsa->priv_key = BN_new()) == NULL)
  {
    Display(LOG_LEVEL_1, ELError, TSP_AUTH_PASSDSS_STRING, STR_GEN_MALLOC_ERROR);
    status = make_status(CTX_TSPAUTHENTICATION, ERR_MEMORY_STARVATION);
    goto error;
  }

  /* Allocate memory for DSA signature */
  if ((sig = DSA_SIG_new()) == NULL)
  {
    Display(LOG_LEVEL_1, ELError, TSP_AUTH_PASSDSS_STRING, STR_GEN_MALLOC_ERROR);
    status = make_status(CTX_TSPAUTHENTICATION, ERR_MEMORY_STARVATION);
    goto error;
  }
  /* Initialize data buffers */
  BufferIn  = calloc(1, TSP_AUTH_PASSDSS_BUFFERSIZE);
  BufferOut = calloc(1, TSP_AUTH_PASSDSS_BUFFERSIZE);

  if ((BufferIn == NULL) || (BufferOut == NULL))
  {
    Display(LOG_LEVEL_1, ELError, TSP_AUTH_PASSDSS_STRING, STR_GEN_MALLOC_ERROR);
    status = make_status(CTX_TSPAUTHENTICATION, ERR_MEMORY_STARVATION);
    goto error;
  }
  buffer_init(Buf_Space);
  buffer_init(Buf_H);
  if (Buf_Space->buf == NULL || Buf_H->buf == NULL)
  {
    Display(LOG_LEVEL_1, ELError, TSP_AUTH_PASSDSS_STRING, STR_GEN_MALLOC_ERROR);
    status = make_status(CTX_TSPAUTHENTICATION, ERR_MEMORY_STARVATION);
    goto error;
  }
  /* Create a read/write memory BIO. Memory is segment is
   * created and resized as needed. When BIO is destroyed, the
   * memory is freed. */
  bio_rw = BIO_new(BIO_s_mem());
  /* Create a base64 BIO filter */
  b64 = BIO_new(BIO_f_base64());
  if ((bio_rw == NULL) || (b64 == NULL))
  {
    Display(LOG_LEVEL_1, ELError, TSP_AUTH_PASSDSS_STRING, STR_GEN_MALLOC_ERROR);
    status = make_status(CTX_TSPAUTHENTICATION, ERR_MEMORY_STARVATION);
    goto error;
  }

  /*
    Compute the Diffie-Hellman public value "X" as follows.  If
    X has a value of 0, repeat.

         x
    X = g  mod n

    where g = dh_g = 2
          n = dh_group2
    x = DH secret key
    X = DH public key
  */
  if (DH_generate_key(dh) == 0)
  {
    Display(LOG_LEVEL_1, ELError, TSP_AUTH_PASSDSS_STRING, GOGO_STR_DH_GEN_ERROR);
    status = make_status(CTX_TSPAUTHENTICATION, ERR_AUTHENTICATION_FAILURE);
    goto error;
  }

  /* Validate DH public key (RFC2631, 2.1.5) */

  /* Send  message with SASL mechanism identifier */
  if ( nt->netsend(socket, authenticate, sizeof(authenticate)) == -1 )
  {
    Display(LOG_LEVEL_1, ELError, TSP_AUTH_PASSDSS_STRING, STR_NET_FAIL_W_SOCKET);
    status = make_status(CTX_TSPAUTHENTICATION, ERR_SOCKET_IO);
    goto error;
  }

  /* First PASSDSS  message from client to server:
     string azname       ; the user name to login as, may be empty if
                           same as authentication name
     string authname     ; the authentication name
     mpint  X            ; Diffie-Hellman parameter X
  */
  /* azname is empty. Just insert a string length zero */
  buffer_put_int(Buf_Space, 0);
  /* authname */
  buffer_put_cstring(Buf_Space, conf->userid);
  /* DH public key */
  buffer_put_bignum(Buf_Space, dh->pub_key);

  /* At this point, save the buffer into Buf_H. Used later for
   * signature verification. */
  buffer_append(Buf_H, buffer_ptr(Buf_Space), buffer_len(Buf_Space));

  /* Push base64 filter */
  BIO_push(b64, bio_rw);
  /* no newline */
  BIO_set_flags(b64, BIO_FLAGS_BASE64_NO_NL);
  /* Write Buffer content into bio_rw. Buffer will be base64
   * encoded. */
  BIO_write(b64, buffer_ptr(Buf_Space), (int) buffer_len(Buf_Space));
  BIO_flush(b64);
  /* Get pointer to the result */
  buflen = BIO_get_mem_data(bio_rw, &BufferPtr);

  // Send data to server, save response in BufferIn.
  if((readlen = nt->netsendrecv(socket,
               BufferPtr, buflen,
               BufferIn, TSP_AUTH_PASSDSS_BUFFERSIZE)) == -1)
  {
    Display(LOG_LEVEL_1, ELError, TSP_AUTH_PASSDSS_STRING, STR_NET_FAIL_RW_SOCKET);
    status = make_status(CTX_TSPAUTHENTICATION, ERR_SOCKET_IO);
    goto error;
  }
  /* remove base64 filter */
  BIO_pop(bio_rw);
  buffer_clear(Buf_Space);
  buflen = 0;

  /* Decode response (base64) and extract server response
   *
   * The response format is as follows:

       uint32   pklength   ; length of SSH-style DSA server public key
           (number of bytes up to y, inclusively)
         string "ssh-dss"  ; constant string "ssh-dss" (lower case)
         mpint  p          ; DSA public key parameters
         mpint  q
         mpint  g
         mpint  z            (y in draft)
       mpint    Y          ; Diffie-Hellman parameter Y
       OCTET    ssecmask   ; SASL security layers offered
       3 OCTET  sbuflen    ; maximum server security layer block size
       uint32   siglength  ; length of SSH-style dss signature
           (number of bytes up to s inclusively)
         string "ssh-dss"  ; constant string "ssh-dss" (lower case)
         mpint  r          ; DSA signature parameters
         mpint  s

   */

  buflen = base64decode(BufferOut, BufferIn);

  buffer_append(Buf_Space, BufferOut, buflen);
  /* Get pklength */
  pklength = buffer_get_int(Buf_Space);
  /* Assuming that
   * p, g, and y are 512 bits,
   * q is 160 bits,
   * "ssh-dss" is 7 bytes
   * pklength should be at least 240 bytes.
   */
  if (pklength < 240)
  {
    Display(LOG_LEVEL_1, ELError, TSP_AUTH_PASSDSS_STRING, GOGO_STR_RCVD_DATA_INVALID);
    status = make_status(CTX_TSPAUTHENTICATION, ERR_AUTHENTICATION_FAILURE);
    goto error;
  }

  /* Make a copy of (pklength|"ssh-dss"|p|q|g|z) in Buf_H */
  /* Add pklength */
  buffer_put_int(Buf_H, pklength);
  /* Add "ssh-dss"|p|q|g|z */
  buffer_append(Buf_H, buffer_ptr(Buf_Space), pklength);

  /* Get "ssh-dss" string */
  s = buffer_get_string(Buf_Space, (unsigned int*)&buflen);
  pal_free(s); s = NULL;
  /* Get p */
  buffer_get_bignum(Buf_Space, dsa->p);
  /* Get q */
  buffer_get_bignum(Buf_Space, dsa->q);
  /* Get g */
  buffer_get_bignum(Buf_Space, dsa->g);
  /* Get z (pub_key) */
  buffer_get_bignum(Buf_Space, dsa->pub_key);
  /* Get DH public key */
  buffer_get_bignum(Buf_Space, server_pubkey);
  /* Copy in Buf_H for signature verification later */
  buffer_put_bignum(Buf_H, server_pubkey);

  /* Buffer now points at ssecmask (1 octet), followed by
   * sbuflen (3 octets). Make a copy of these 4 octets in Buf_H
   * now, then extract these values. */
  buffer_append(Buf_H, buffer_ptr(Buf_Space), 4);

  /* Get ssecmask */
  ssecmask = buffer_get_octet(Buf_Space);
  /* Get sbuflen
   * Big endian binary unsigned integer */
  buffer_get(Buf_Space, (char *)num, 3);
  sbuflen =  (((u_long)(u_char)(num)[0] << 16) |
        ((u_long)(u_char)(num)[1] << 8) |
        ((u_long)(u_char)(num)[2]));

  /* DSS signature */
  /* Get siglength */
  siglength = buffer_get_int(Buf_Space);
  /* r and s are 20 bytes each, encoded as mpint (2*24)
   * "ssh-dss" is 7 bytes + int32 siglength should be >= 59
   * octets (mpint may have leading zero byte)
   */
  if (siglength < 59)
  {
    Display(LOG_LEVEL_1, ELError, TSP_AUTH_PASSDSS_STRING, GOGO_STR_RCVD_DATA_INVALID);
    status = make_status(CTX_TSPAUTHENTICATION, ERR_AUTHENTICATION_FAILURE);
    goto error;
  }
  /* Get "ssh-dss" string */
  s = buffer_get_string(Buf_Space, (unsigned int*)&buflen);
  pal_free(s); s = NULL;
  /* Get DSA signature r and s*/
  if ((sig->r= BN_new()) == NULL || (sig->s = BN_new()) == NULL)
  {
    Display(LOG_LEVEL_1, ELError, TSP_AUTH_PASSDSS_STRING, STR_GEN_MALLOC_ERROR);
    status = make_status(CTX_TSPAUTHENTICATION, ERR_MEMORY_STARVATION);
    goto error;
  }
  /* Get r */
  buffer_get_bignum(Buf_Space, sig->r);
  /* Get s */
  buffer_get_bignum(Buf_Space, sig->s);

  /* Validate server DH public key  (RFC2631, 2.1.5) */

  {
    if( !add_dsakey_to_keyfile(dsa, conf->server, TSPC_DSA_KEYFILE, conf->no_questions) )
    {
      Display(LOG_LEVEL_1, ELError, TSP_AUTH_PASSDSS_STRING, GOGO_STR_KEY_VERIF_ERROR);
      status = make_status(CTX_TSPAUTHENTICATION, ERR_AUTHENTICATION_FAILURE);
      goto error;
    }
  }

  /* Verify that DSA public key belongs to server */

  /* Compute DH shared secret */
  if ((s = calloc(1, DH_size(dh))) == NULL)
  {
    Display(LOG_LEVEL_1, ELError, TSP_AUTH_PASSDSS_STRING, STR_GEN_MALLOC_ERROR);
    status = make_status(CTX_TSPAUTHENTICATION, ERR_MEMORY_STARVATION);
    goto error;
  }
  if( (keysize = DH_compute_key((unsigned char*)s, server_pubkey, dh)) < 0 )
  {
    Display(LOG_LEVEL_1, ELError, TSP_AUTH_PASSDSS_STRING, GOGO_STR_DH_SHARED_COMPUTE_ERROR);
    status = make_status(CTX_TSPAUTHENTICATION, ERR_AUTHENTICATION_FAILURE);
    goto error;
  }
  BN_bin2bn((const unsigned char*)s, keysize, dh_K);
  memset(s, 0, keysize);
  pal_free(s);
  s = NULL;
  Display(LOG_LEVEL_3, ELDebug, TSP_AUTH_PASSDSS_STRING,
    GOGO_STR_DH_SHARED_KEY, BN_bn2hex(dh_K));

  /* Append dh_K in to complete the buffer. Use Buffer to hold
   * result to keep Bf_H intact, since to will be used (without
   * dh_K) to compute HMAC for packet integrity. */
  buffer_clear(Buf_Space);
  buffer_append(Buf_Space, buffer_ptr(Buf_H), buffer_len(Buf_H));
  buffer_put_bignum(Buf_Space, dh_K);

  /* Compute SHA1 hash of Buffer */
  SHA1(buffer_ptr(Buf_Space), buffer_len(Buf_Space), hash);

  /* Debug information available at level 4 */
 {
   BIGNUM *h;
   h = BN_bin2bn(hash, 20, NULL);
   Display(LOG_LEVEL_3, ELDebug, TSP_AUTH_PASSDSS_STRING,
     GOGO_STR_SIGNED_HASH, BN_bn2hex(h));
   BN_free(h);
 }
   Display(LOG_LEVEL_3, ELDebug, TSP_AUTH_PASSDSS_STRING,
     GOGO_STR_DSA_SIGN_R, BN_bn2hex(sig->r));
   Display(LOG_LEVEL_3, ELDebug, TSP_AUTH_PASSDSS_STRING,
     GOGO_STR_DSA_SIGN_S, BN_bn2hex(sig->s));

  // Verify that the DSS signature is a signature of hash.
  switch( DSA_do_verify(hash, sizeof(hash), sig, dsa) )
  {
  case 0:
    Display(LOG_LEVEL_1, ELError, TSP_AUTH_PASSDSS_STRING, GOGO_STR_BAD_SIG_FROM_SERVER);
    status = make_status(CTX_TSPAUTHENTICATION, ERR_AUTHENTICATION_FAILURE);
    goto error;
    break; /* NOTREACHED */

  case 1:  /* correct signature */
    break;

  default: /* -1 on error */
    Display(LOG_LEVEL_1, ELError, TSP_AUTH_PASSDSS_STRING, GOGO_STR_SIG_VERIF_ERROR);
    status = make_status(CTX_TSPAUTHENTICATION, ERR_AUTHENTICATION_FAILURE);
    goto error;
    break; /* NOTREACHED */
  }

  /* Step I: Compute 3DES key and iv */
  /*
    cs-encryption-iv    = SHA1( K || "A" || H )
    sc-encryption-iv    = SHA1( K || "B" || H )
    cs-encryption-key-1 = SHA1( K || "C" || H )
    cs-encryption-key-2 = SHA1( K || cs-encryption-key-1 )
    cs-encryption-key   = cs-encryption-key-1 || cs-encryption-key-2
    sc-encryption-key-1 = SHA1( K || "D" || H )
    sc-encryption-key-2 = SHA1( K || sc-encryption-key-1 )
    sc-encryption-key   = sc-encryption-key-1 || sc-encryption-key-2
    cs-integrity-key    = SHA1( K || "E" || H )
    sc-integrity-key    = SHA1( K || "F" || H )

    K is dh_k in mpint format (string)
    H is hash
  */

  /* Since we won't support SASL security layers, we need to
   * compute the following only:
   * cs-encryption-iv
   * cs-encryption-key
   * cs-integrity-key
   */
  buffer_clear(Buf_Space);
  buffer_put_bignum(Buf_Space, dh_K);
  buffer_put_octet(Buf_Space,'A');
  buffer_append(Buf_Space, hash, 20);
  SHA1(buffer_ptr(Buf_Space), buffer_len(Buf_Space), tmphash);
  /* Use first 8 octets as iv */
  memcpy(enc_iv, tmphash, 8);

  buffer_clear(Buf_Space);
  buffer_put_bignum(Buf_Space, dh_K);
  buffer_put_octet(Buf_Space,'E');
  buffer_append(Buf_Space, hash, 20);
  SHA1(buffer_ptr(Buf_Space), buffer_len(Buf_Space), int_key);

  buffer_clear(Buf_Space);
  buffer_put_bignum(Buf_Space, dh_K);
  buffer_put_octet(Buf_Space,'C');
  buffer_append(Buf_Space, hash, 20);
  SHA1(buffer_ptr(Buf_Space), buffer_len(Buf_Space), tmphash);
  buffer_clear(Buf_Space);
  buffer_put_bignum(Buf_Space, dh_K);
  buffer_append(Buf_Space, tmphash, 20);
  SHA1(buffer_ptr(Buf_Space), buffer_len(Buf_Space), tmphash+20);
  /* Use first 24 octets as key */
  memcpy(enc_key, tmphash, 24);
 {
   BIGNUM *enc, *i, *iv;
   enc = BN_bin2bn(enc_key, 24, NULL);
   iv = BN_bin2bn(enc_iv, 8, NULL);
   i = BN_bin2bn(int_key, 20, NULL);

   Display(LOG_LEVEL_3, ELDebug, TSP_AUTH_PASSDSS_STRING,
     GOGO_STR_PASSDS_ENC_KEY, BN_bn2hex(enc));
   Display(LOG_LEVEL_3, ELDebug, TSP_AUTH_PASSDSS_STRING,
     GOGO_STR_PASSDS_IV, BN_bn2hex(iv));
   Display(LOG_LEVEL_3, ELDebug, TSP_AUTH_PASSDSS_STRING,
     GOGO_STR_PASSDS_INTEG_KEY, BN_bn2hex(i));
   BN_free(enc);
   BN_free(i);
   BN_free(iv);
 }
  /*
    (J) Create a buffer beginning with a bit mask for the
    selected security layer (it MUST be one offered from server)
    followed by three octets representing the maximum
    cipher-text buffer size (at least 32) the client can accept
    in network byte order.  This is followed by a string
    containing the passphrase.
  */
  buffer_clear(Buf_Space);
  buffer_put_octet(Buf_Space, ssecmask);
  buffer_put_octet(Buf_Space, 0);
  buffer_put_octet(Buf_Space, 0);
  buffer_put_octet(Buf_Space, 0); /**< @bug must be at least 32 */
  buffer_put_cstring(Buf_Space, conf->passwd);

  /*
    (K) Create a buffer containing items (1) through (7)
    immediately followed by the first four octets of (J).
  */
  buffer_append(Buf_H, buffer_ptr(Buf_Space), 4);

  /*
    (L) Compute HMAC-SHA-1 with (K) as the data and the
    cs-integrity- key from step (I) as the key.  This produces a
    20 octet result.
  */
  HMAC(EVP_sha1(), int_key, sizeof(int_key),
       buffer_ptr(Buf_H), buffer_len(Buf_H), hmac, (unsigned int*)&keysize);
  /*
    (M) Create a buffer containing (J) followed by (L) followed
    by an arbitrary number of zero octets as necessary to reach
    the block size of DES and conceal the passphrase length from
    an eavesdropper.
  */
  buffer_append(Buf_Space, hmac, keysize);

  /*
    (N) Apply the triple-DES algorithm to (M) with the first 8
    octets of cs-encryption-iv from step (I) as the
    initialization vector and the first 24 octets of
    cs-encryption-key as the key.
  */
  /*
    Padding is automatically done. From OpenSSL EVP_EncryptInit(3):
    EVP_CIPHER_CTX_set_padding() enables or disables padding. By default
    encryption operations are padded using standard block padding and the
    padding is checked and removed when decrypting.
  */

  /*
    Create BIO filter to encrypt using 3des + convert to
    base64. Result is written in memory BIO.
  */
  /* Erase BIO and buffer memory */
  BIO_reset(bio_rw);
  memset(BufferOut, 0, TSP_AUTH_PASSDSS_BUFFERSIZE);
  memset(BufferIn, 0, TSP_AUTH_PASSDSS_BUFFERSIZE);
  buflen = 0;

  /* Create cipher BIO */
  cipher = BIO_new(BIO_f_cipher());
  BIO_set_cipher(cipher, EVP_des_ede3_cbc(), enc_key, enc_iv, 1);
  /* Assemble filters as cipher->b64->bio_rw */
  BIO_push(cipher, b64);
  BIO_push(b64, bio_rw);

  /* Write Buffer content into bio_rw */
  BIO_write(cipher, buffer_ptr(Buf_Space), (int) buffer_len(Buf_Space));
  BIO_flush(cipher);
  /* Get pointer to the result. */
  buflen = BIO_get_mem_data(bio_rw, &BufferPtr);

  /* wipe encryption material */
  memset(enc_key, 0, sizeof(enc_key));
  memset(enc_iv, 0, sizeof(enc_iv));

  /* Send data to server, save response in BufferIn */
  if( (readlen = nt->netsendrecv(socket, BufferPtr, buflen,
       BufferIn, TSP_AUTH_PASSDSS_BUFFERSIZE)) == -1)
  {
    Display(LOG_LEVEL_1, ELError, TSP_AUTH_PASSDSS_STRING, STR_NET_FAIL_RW_SOCKET);
    status = make_status(CTX_TSPAUTHENTICATION, ERR_SOCKET_IO);
    goto error;
  }
  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 )
    {
      status = make_status(CTX_TSPAUTHENTICATION, EVNT_BROKER_REDIRECTION);
    }
    else
    {
      // Redirect error.
      status = make_status(CTX_TSPAUTHENTICATION, ERR_BROKER_REDIRECTION);
    }
    goto error;
  }

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

  case TSP_PROTOCOL_AUTH_FAILED:
    Display(LOG_LEVEL_1, ELError, "AuthPASSDSS_3DES_1", STR_TSP_AUTH_FAILED_USER, conf->userid);
    status = make_status(CTX_TSPAUTHENTICATION, ERR_AUTHENTICATION_FAILURE);
    goto error;

  default:
    Display(LOG_LEVEL_1, ELError, "AuthPASSDSS_3DES_1", STR_TSP_UNKNOWN_ERR_AUTH_FAILED, tspGetTspStatusStr(tsp_status));
    status = make_status(CTX_TSPAUTHENTICATION, ERR_TSP_GENERIC_ERROR);
    goto error;
  }

  status = STATUS_SUCCESS_INIT;

 error:

  /* Free storage for DSA key */
  if (dsa != NULL) DSA_free(dsa); /* Also frees BIGNUMs inside struct */
  /* DSA signature */
  if (sig != NULL) DSA_SIG_free(sig);
  /* Free Diffie Hellman variables */
  if (dh != NULL) DH_free(dh); /* Also frees BIGNUMs inside struct */
  if (server_pubkey != NULL) BN_free(server_pubkey);
  if (dh_K != NULL) BN_free(dh_K);
  /* Buffers */
  if (Buf_Space->buf != NULL) buffer_free(Buf_Space);
  if (Buf_H->buf != NULL)  buffer_free(Buf_H);
  /* malloc'ed space*/
  if (BufferIn != NULL) pal_free(BufferIn);
  if (BufferOut != NULL) pal_free(BufferOut);
  /* BIOs */
  if (cipher != NULL) BIO_vfree(cipher);
  if (b64 != NULL) BIO_vfree(b64);
  if (bio_rw != NULL) BIO_vfree(bio_rw);
  /* strings buffers */
  if (s != NULL) pal_free(s);

  return status;
}
예제 #30
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;
}