static boolean authority_synchronization_main(SSL *ssl_client, unsigned int authority_id, char *authority_name)
{
	MYSQL *db_conn = NULL;

	// Connect the database
	connect_db(&db_conn, DB_IP, DB_USERNAME, DB_PASSWD, DB_NAME);

	if(!synchronize_authority_info(ssl_client))
		goto ERROR;

	if(!synchronize_attribute(db_conn, ssl_client))
		goto ERROR;

	if(!synchronize_user(db_conn, ssl_client))
		goto ERROR;

	if(!synchronize_access_permission(db_conn, ssl_client, authority_id))
		goto ERROR;

	if(!synchronize_emergency_delegation(ssl_client, authority_name))
		goto ERROR;

	if(!synchronize_phr_transaction_log(ssl_client, authority_name))
		goto ERROR;

	disconnect_db(&db_conn);
	return true;

ERROR:

	disconnect_db(&db_conn);
	return false;
}
Beispiel #2
0
/*---------------------------------------------------------------------
 *                M A I N   P R O G R A M
 *---------------------------------------------------------------------*/
int main(int argc, char **argv)
{
  params_t     oci_params;
  
  /* Outbound connection info */
  conn_info_t  xout_params = {XOUT_USER, XOUT_USER_LEN, 
                               XOUT_PSW, XOUT_PSW_LEN,
                               XOUT_DB, XOUT_DB_LEN, 
                               XOUT_APPLY, XOUT_APPLY_LEN};
  
  /* Database connection info */
  conn_info_t  db_params = {DB_USER, DB_USER_LEN, 
                             DB_PSW, DB_PSW_LEN,
                             XOUT_DB, XOUT_DB_LEN,
                             (oratext *) 0, 0};
  
  myctx_t       ctx;
  oci_t        *ocip = (oci_t *)NULL;
  ub2           obdb_char_csid = 0;                 /* outbound db char csid */
  ub2           obdb_nchar_csid = 0;               /* outbound db nchar csid */

  memset(&ctx, 0, sizeof(ctx));
  ctx.longform = TRUE;
 
  /* parse command line arguments */
  get_inputs(&ctx, &xout_params, &db_params, argc, argv);
  
  /* Get the outbound database CHAR and NCHAR character set info */
  get_db_charsets(&xout_params, &obdb_char_csid, &obdb_nchar_csid);
  
  /* connect to the source database */
  connect_db(&xout_params, &ocip, obdb_char_csid, obdb_nchar_csid);
  /* Attach to outbound server */
  attach_session(ocip, &xout_params, TRUE);
  ctx.outbound_ocip = ocip;
  
  /* connect to source database to do query and inserts on source tables */
  ocip = (oci_t *)NULL;
  connect_db(&db_params, &ocip, obdb_char_csid, obdb_nchar_csid);
  ctx.sql_sel_ocip = ocip;

  /* Get lcrs from outbound server and send to inbound server */
  get_lcrs(&ctx);

  /* Detach from XStream servers */
  detach_session(ctx.outbound_ocip, FALSE);

  /* Disconnect from outbound database */
  disconnect_db(ctx.outbound_ocip);
  free(ctx.outbound_ocip);
  
  /* Disconnect from sql database */  
  disconnect_db(ctx.sql_sel_ocip);
  free(ctx.sql_sel_ocip);
  return 0;
}
static boolean authority_exists(char *authority_name, unsigned int *authority_id_ret)
{
	MYSQL     *db_conn = NULL;
	MYSQL_RES *result  = NULL;
  	MYSQL_ROW row;
	char      stat[SQL_STATEMENT_LENGTH + 1];
	char      err_msg[ERR_MSG_LENGTH + 1];

	// Connect the database
	connect_db(&db_conn, DB_IP, DB_USERNAME, DB_PASSWD, DB_NAME);

	// Query for authority info
	sprintf(stat, "SELECT authority_id FROM %s WHERE authority_name LIKE '%s' COLLATE latin1_general_cs", UA__AUTHORITIES, authority_name);

	if(mysql_query(db_conn, stat))
  	{
      		sprintf(err_msg, "Error %u: %s\n", mysql_errno(db_conn), mysql_error(db_conn));
      		int_error(err_msg);
  	}

  	result = mysql_store_result(db_conn);
	row    = mysql_fetch_row(result);

	if(!row)
	{
		goto ERROR;
	}

	*authority_id_ret = atoi(row[0]);

	if(result)
	{
		mysql_free_result(result);
		result = NULL;
	}

	disconnect_db(&db_conn);
	return true;

ERROR:

	if(result)
	{
		mysql_free_result(result);
		result = NULL;
	}

	disconnect_db(&db_conn);
	return false;
}
static void load_user_basic_info(char *username, boolean is_admin_flag, char *email_address_ret)
{
	MYSQL     *db_conn = NULL;
  	MYSQL_RES *result  = NULL;
  	MYSQL_ROW row;
	char      stat[SQL_STATEMENT_LENGTH + 1];
	char	  err_msg[ERR_MSG_LENGTH + 1];

	// Connect the database
	connect_db(&db_conn, DB_IP, DB_USERNAME, DB_PASSWD, DB_NAME);

	// Query the user's e-mail address
	sprintf(stat, "SELECT email_address FROM %s WHERE username LIKE '%s' COLLATE latin1_general_cs", (is_admin_flag) ? UA__ADMINS : UA__USERS, username);
	if(mysql_query(db_conn, stat))
  	{
      		sprintf(err_msg, "Error %u: %s\n", mysql_errno(db_conn), mysql_error(db_conn));
      		int_error(err_msg);
  	}

  	result = mysql_store_result(db_conn);
  	row = mysql_fetch_row(result);
	if(!row)
		int_error("Getting user basic information from the database failed");

	strcpy(email_address_ret, row[0]);

	if(result)
	{
		mysql_free_result(result);
		result = NULL;
	}

	disconnect_db(&db_conn);
}
Beispiel #5
0
/* this function free the memory allocated and exit
 * and it is called on signals */
void destroyall(int status)
{

	odbc_free();
	disconnect_db();
	close(portfd);
	free_emb_info();
	free_cfg();
	exit(-1);

}
Beispiel #6
0
/* this is the main body */
int main(int argc, char *argv[])
{

	if (cfg.verbose)
		printf("%s version %s\n", APPNAME, VERSION);

	/* fill the cfg struct with the default options */
	fill_default_options();
	/* parse options from config file */
	parse_cfgfile(cfg.cfgfile);
	/* parse the command line options */
	parse_opts(argc, argv);

	odbc_alloc();
	connect_db(cfg.dsn, cfg.dbuser, cfg.dbpass);
	get_embedded_infos();
	disconnect_db();

	/* if cfg.daemon option is set to 1 we go to background */
	if (cfg.daemon)
		daemon(0, 0);

	/* set signal hook function */
	signal(SIGHUP, &destroyall);
	signal(SIGINT, &destroyall);
	signal(SIGQUIT, &destroyall);
	signal(SIGTERM, &destroyall);
	signal(SIGABRT, &destroyall);

	/* open and configure the serial port */
	cfgport();
	/* enter the main loop */
	serial_mainloop();

	odbc_free();
	disconnect_db();
	free_cfg();
	free_emb_info();

	exit(0);
}
Beispiel #7
0
void db_close(db_con_t* _h)
{
	DLOG("db_close", "entry");
	if(! _h)
	{
		PLOG("db_close", "no handle passed, ignored");
		return;
	}

	disconnect_db(_h);
	aug_free(_h);

}
static int mod_init(void)
{
    if (bind_dbmod(db_url.s, &db )) {
	LOG(L_CRIT, "Cannot bind to database module! "
	     "Did you forget to load a database module ?\n");
	return -1;
    }
    
	 /* Check if cache needs to be loaded from domain table */
    if (db_mode) {
	if (connect_db() < 0) goto error;
	if (check_version() < 0) goto error;
	if (allocate_tables() < 0) goto error;
	if (reload_domain_list() < 0) goto error;
	disconnect_db();
    }
    
    return 0;
    
 error:
    disconnect_db();
    return -1;
}
void check_db_disconnect(void)
{
	/* first check if we're even connected */
	if( !db_connect)
		return;
	/* No we see if we have been connected for too long,
	   if we have, lets disconnect and save resources
        */
	if( db_last_action >= DB_CONNECT_TIME_LIMIT)
	{
		disconnect_db();
		return;
	}
	/* at this point we must still be connected, so lets increment our time */
	db_last_action++;
	return;
}
static void set_authority_join_flag(unsigned int authority_id)
{
	MYSQL *db_conn = NULL;
	char  stat[SQL_STATEMENT_LENGTH + 1];
	char  err_msg[ERR_MSG_LENGTH + 1];

	// Connect the database
	connect_db(&db_conn, DB_IP, DB_USERNAME, DB_PASSWD, DB_NAME);

	// Set the authority join flag
	sprintf(stat, "UPDATE %s SET authority_join_flag='1' WHERE authority_id=%u", UA__AUTHORITIES, authority_id);
	if(mysql_query(db_conn, stat))
  	{
      		sprintf(err_msg, "Error %u: %s\n", mysql_errno(db_conn), mysql_error(db_conn));
      		int_error(err_msg);
  	}

	disconnect_db(&db_conn);
}
Beispiel #11
0
static void get_necessary_info()
{
	MYSQL     *db_conn = NULL;
  	MYSQL_RES *result  = NULL;
  	MYSQL_ROW row;
	char      stat[SQL_STATEMENT_LENGTH + 1];
	char	  err_msg[ERR_MSG_LENGTH + 1];

	// Connect the database
	connect_db(&db_conn, DB_IP, DB_USERNAME, DB_PASSWD, DB_NAME);

	// Query for the authority's information
	sprintf(stat, "SELECT authority_name, mail_server_url, authority_email_address, authority_email_passwd FROM %s", ESA__BASIC_AUTHORITY_INFO);
	if(mysql_query(db_conn, stat))
  	{
      		sprintf(err_msg, "Error %u: %s\n", mysql_errno(db_conn), mysql_error(db_conn));
      		int_error(err_msg);
  	}

  	result = mysql_store_result(db_conn);
  	row = mysql_fetch_row(result);
	if(!row)
		int_error("Getting the authority's information from the database failed");

	strcpy(GLOBAL_authority_name, row[0]);
	strcpy(GLOBAL_mail_server_url, row[1]);
	strcpy(GLOBAL_authority_email_address, row[2]);
	strcpy(GLOBAL_authority_email_passwd, row[3]);

	if(result)
	{
		mysql_free_result(result);
		result = NULL;
	}

	disconnect_db(&db_conn);
}
static boolean respond_requested_restricted_phr_list_loading(SSL *ssl_client)
{
	char         emergency_unit_name[AUTHORITY_NAME_LENGTH + 1];
	char         emergency_staff_name[USER_NAME_LENGTH + 1];

	MYSQL        *db_conn = NULL;
	MYSQL_RES    *result  = NULL;
  	MYSQL_ROW    row;
	char         stat[SQL_STATEMENT_LENGTH + 1];
	char	     err_msg[ERR_MSG_LENGTH + 1];

	unsigned int phr_request_id;
	
	SSL          *ssl_PHRsv_conn = NULL;
	char         buffer[BUFFER_LENGTH + 1];
	char         token_name[TOKEN_NAME_LENGTH + 1];

	char         remote_site_phr_id_str_tmp[INT_TO_STR_DIGITS_LENGTH + 1];
	unsigned int remote_site_phr_id;

	char         restricted_phr_information_requesting_result_flag_str_tmp[FLAG_LENGTH + 1];
	boolean      restricted_phr_information_requesting_result_flag;

	char         phr_ownername[USER_NAME_LENGTH + 1];
	char         data_description[DATA_DESCRIPTION_LENGTH + 1];
	char         file_size_str_tmp[INT_TO_STR_DIGITS_LENGTH + 1];

	unsigned int no_approvals;
	char         no_approvals_str_tmp[INT_TO_STR_DIGITS_LENGTH + 1];

	unsigned int threshold_value;
	char         threshold_value_str_tmp[INT_TO_STR_DIGITS_LENGTH + 1];
	char         request_status[RESTRICTED_PHR_REQUEST_STATUS_LENGTH + 1];

	// Get the emergency staff info
	get_cert_owner_info(ssl_client, emergency_unit_name, emergency_staff_name);

	// Connect the database
	connect_db(&db_conn, DB_IP, DB_USERNAME, DB_PASSWD, DB_NAME);

	// Query for the phr_request_id and remote_site_phr_id that was requested by the emergency staff if any
	sprintf(stat, "SELECT phr_request_id, remote_site_phr_id FROM %s WHERE emergency_unit_name LIKE '%s' COLLATE latin1_general_cs AND emergency_staff_name "
		"LIKE '%s' COLLATE latin1_general_cs", EMS__RESTRICTED_LEVEL_PHR_REQUESTS, emergency_unit_name, emergency_staff_name);

	if(mysql_query(db_conn, stat))
  	{
      		sprintf(err_msg, "Error %u: %s\n", mysql_errno(db_conn), mysql_error(db_conn));
      		int_error(err_msg);
  	}

  	result = mysql_store_result(db_conn);
	row    = mysql_fetch_row(result);

	// There is no request from the emergency staff
	if(!row)
	{	
		// Send the is_end_of_requested_restricted_phr_list_flag
		write_token_into_buffer("is_end_of_requested_restricted_phr_list_flag", "1", true, buffer);

		if(!SSL_send_buffer(ssl_client, buffer, strlen(buffer)))
		{
			fprintf(stderr, "Sending the is_end_of_requested_restricted_phr_list_flag failed\n");
			goto ERROR;
		}

		goto NO_REQUEST;
	}

	// There are requests from the emergency staff, then connect to PHR Server
	if(!connect_to_emergency_phr_list_loading_service(&ssl_PHRsv_conn))
		goto ERROR;

	// Send request information
	write_token_into_buffer("request", REQUESTED_RESTRICTED_LEVEL_PHR_INFO_LOADING, true, buffer);

	if(!SSL_send_buffer(ssl_PHRsv_conn, buffer, strlen(buffer)))
	{
		fprintf(stderr, "Sending request information failed\n");
		goto ERROR;
	}

	// Requested restricted-level PHRs
	do{
		phr_request_id     = atoi(row[0]);
		remote_site_phr_id = atoi(row[1]);

		// Send the restricted-level PHR information request
		sprintf(remote_site_phr_id_str_tmp, "%u", remote_site_phr_id);
		write_token_into_buffer("is_end_of_getting_restricted_phr_information_flag", "0", true, buffer);
		write_token_into_buffer("phr_id", remote_site_phr_id_str_tmp, false, buffer);

		if(!SSL_send_buffer(ssl_PHRsv_conn, buffer, strlen(buffer)))
		{
			fprintf(stderr, "Sending the restricted-level PHR information request failed\n");
			goto ERROR;
		}

		// Receive the restricted-level PHR information
		if(SSL_recv_buffer(ssl_PHRsv_conn, buffer, NULL) == 0)
		{
			fprintf(stderr, "Receiving the restricted-level PHR information failed\n");
			goto ERROR;
		}	

		if(read_token_from_buffer(buffer, 1, token_name, restricted_phr_information_requesting_result_flag_str_tmp) 
			!= READ_TOKEN_SUCCESS || strcmp(token_name, "restricted_phr_information_requesting_result_flag") != 0)
		{
			int_error("Extracting the restricted_phr_information_requesting_result_flag failed");
		}

		restricted_phr_information_requesting_result_flag = (strcmp(restricted_phr_information_requesting_result_flag_str_tmp, "1") == 0) ? true : false;
		if(!restricted_phr_information_requesting_result_flag)
			continue;

		if(read_token_from_buffer(buffer, 2, token_name, phr_ownername) != READ_TOKEN_SUCCESS || strcmp(token_name, "phr_ownername") != 0)
		{
			int_error("Extracting the phr_ownername failed");
		}

		if(read_token_from_buffer(buffer, 3, token_name, data_description) != READ_TOKEN_SUCCESS || strcmp(token_name, "data_description") != 0)
		{
			int_error("Extracting the data_description failed");
		}

		if(read_token_from_buffer(buffer, 4, token_name, file_size_str_tmp) != READ_TOKEN_SUCCESS || strcmp(token_name, "file_size") != 0)
		{
			int_error("Extracting the file_size failed");
		}

		get_threshold_value(db_conn, remote_site_phr_id, &threshold_value);
		get_no_approvals(db_conn, phr_request_id, &no_approvals);

		// Note that, if the request was rejected, Emergency server will remove the request and then 
		// inform the emergency staff (requestor) about the rejection through his/her e-mail address
		if(no_approvals >= threshold_value)
		{
			// Request approved
			strcpy(request_status, RESTRICTED_PHR_REQUEST_APPROVED);
		}
		else
		{
			// Request pending
			strcpy(request_status, RESTRICTED_PHR_REQUEST_PENDING);
		}

		sprintf(remote_site_phr_id_str_tmp, "%u", remote_site_phr_id);
		sprintf(no_approvals_str_tmp, "%u", no_approvals);
		sprintf(threshold_value_str_tmp, "%u", threshold_value);

		// Re-pack the information
		write_token_into_buffer("is_end_of_requested_restricted_phr_list_flag", "0", true, buffer);
		write_token_into_buffer("phr_id", remote_site_phr_id_str_tmp, false, buffer);
		write_token_into_buffer("phr_ownername", phr_ownername, false, buffer);
		write_token_into_buffer("data_description", data_description, false, buffer);
		write_token_into_buffer("file_size", file_size_str_tmp, false, buffer);
		
		// Append the request info
		write_token_into_buffer("approvals", no_approvals_str_tmp, false, buffer);
		write_token_into_buffer("threshold_value", threshold_value_str_tmp, false, buffer);
		write_token_into_buffer("request_status", request_status, false, buffer);

		if(!SSL_send_buffer(ssl_client, buffer, strlen(buffer)))
		{
			fprintf(stderr, "Sending the requested restricted-level PHR information failed\n");
			goto ERROR;
		}
	}
	while((row = mysql_fetch_row(result)));

	if(result)
	{
		mysql_free_result(result);
		result = NULL;
	}

	disconnect_db(&db_conn);

	// Send the is_end_of_getting_restricted_phr_information_flag
	write_token_into_buffer("is_end_of_getting_restricted_phr_information_flag", "1", true, buffer);

	if(!SSL_send_buffer(ssl_PHRsv_conn, buffer, strlen(buffer)))
	{
		fprintf(stderr, "Sending the is_end_of_getting_restricted_phr_information_flag failed\n");
		goto ERROR;
	}

	SSL_cleanup(ssl_PHRsv_conn);
	ssl_PHRsv_conn = NULL;

	// Send the is_end_of_requested_restricted_phr_list_flag
	write_token_into_buffer("is_end_of_requested_restricted_phr_list_flag", "1", true, buffer);

	if(!SSL_send_buffer(ssl_client, buffer, strlen(buffer)))
	{
		fprintf(stderr, "Sending the is_end_of_requested_restricted_phr_list_flag failed\n");
		goto ERROR;
	}

	return true;

NO_REQUEST:

	if(result)
	{
		mysql_free_result(result);
		result = NULL;
	}

	if(db_conn)
	{
		disconnect_db(&db_conn);
		db_conn = NULL;
	}

	if(ssl_PHRsv_conn)
	{
		SSL_cleanup(ssl_PHRsv_conn);
		ssl_PHRsv_conn = NULL;
	}

	return true;

ERROR:

	if(result)
	{
		mysql_free_result(result);
		result = NULL;
	}

	if(db_conn)
	{
		disconnect_db(&db_conn);
		db_conn = NULL;
	}

	if(ssl_PHRsv_conn)
	{
		SSL_cleanup(ssl_PHRsv_conn);
		ssl_PHRsv_conn = NULL;
	}

	return false;
}
// Response the CP-ABE private key to the user if he/she is a normal user (An administrator does not have the private key)
static boolean cpabe_private_key_response(SSL *ssl_client, char *username)
{
	char          *cpabe_priv_key_data = NULL;
	unsigned int  cpabe_priv_key_data_length;
	char          cpabe_priv_key_hash[SHA1_DIGEST_LENGTH + 1];

	MYSQL         *db_conn = NULL;
  	MYSQL_RES     *result  = NULL;
  	MYSQL_ROW     row;
	char          stat[SQL_STATEMENT_LENGTH + 1];
	char	      err_msg[ERR_MSG_LENGTH + 1];
	unsigned long *lengths = NULL;

	cpabe_priv_key_data = (char *)malloc(sizeof(char)*1000*1024);
	if(!cpabe_priv_key_data)
	{
		int_error("Allocating memory for \"cpabe_priv_key_data\" failed");
	}

	// Connect the database
	connect_db(&db_conn, DB_IP, DB_USERNAME, DB_PASSWD, DB_NAME);

	// Query the user's CP-ABE private key and write it to buffer
	sprintf(stat, "SELECT enc_cpabe_priv_key, enc_cpabe_priv_key_hash FROM %s WHERE username LIKE '%s' COLLATE latin1_general_cs", UA__USERS, username);
	if(mysql_query(db_conn, stat))
  	{
      		sprintf(err_msg, "Error %u: %s\n", mysql_errno(db_conn), mysql_error(db_conn));
      		int_error(err_msg);
  	}

  	result = mysql_store_result(db_conn);
  	row    = mysql_fetch_row(result);
	if(!row)
		int_error("Getting a CP-ABE private key from the database failed");

	lengths = mysql_fetch_lengths(result);
	cpabe_priv_key_data_length = lengths[0];

	memcpy(cpabe_priv_key_data, row[0], cpabe_priv_key_data_length);
	strcpy(cpabe_priv_key_hash, row[1]);

	if(result)
	{
		mysql_free_result(result);
		result = NULL;
	}
	disconnect_db(&db_conn);

	// Send the user's CP-ABE private key and its hash value
	if(!SSL_send_buffer(ssl_client, cpabe_priv_key_data, cpabe_priv_key_data_length))
	{
		fprintf(stderr, "Sending the CP-ABE private key failed\n");
		goto ERROR;
	}

	if(!SSL_send_buffer(ssl_client, cpabe_priv_key_hash, strlen(cpabe_priv_key_hash)))
	{
		fprintf(stderr, "Sending the CP-ABE private key hash failed\n");
		goto ERROR;
	}

	if(cpabe_priv_key_data)
	{
		free(cpabe_priv_key_data);
		cpabe_priv_key_data = NULL;
	}

	return true;

ERROR:
	if(cpabe_priv_key_data)
	{
		free(cpabe_priv_key_data);
		cpabe_priv_key_data = NULL;
	}

	return false;
}
// Implementation
static boolean load_phr_authority_list(SSL *ssl_client)
{
	MYSQL     *db_conn = NULL;
	MYSQL_RES *result  = NULL;
  	MYSQL_ROW row;
	char      stat[SQL_STATEMENT_LENGTH + 1];
	char	  err_msg[ERR_MSG_LENGTH + 1];

	char      buffer[BUFFER_LENGTH + 1];

	// Connect the database
	connect_db(&db_conn, DB_IP, DB_USERNAME, DB_PASSWD, DB_NAME);

	// Query for PHR authority list
	sprintf(stat, "SELECT phr_authority_name, emergency_server_ip_addr FROM %s", ESA__PHR_AUTHORITIES);

	if(mysql_query(db_conn, stat))
  	{
      		sprintf(err_msg, "Error %u: %s\n", mysql_errno(db_conn), mysql_error(db_conn));
      		int_error(err_msg);
  	}

  	result = mysql_store_result(db_conn);
	while((row = mysql_fetch_row(result)))
	{
		// Send the PHR authority information
		write_token_into_buffer("is_end_of_phr_authority_list_flag", "0", true, buffer);
		write_token_into_buffer("phr_authority_name", row[0], false, buffer);
		write_token_into_buffer("ip_address", row[1], false, buffer);

		if(!SSL_send_buffer(ssl_client, buffer, strlen(buffer)))
		{
			fprintf(stderr, "Sending the PHR authority information failed\n");
			goto ERROR;
		}
	}

	if(result)
	{
		mysql_free_result(result);
		result = NULL;
	}

	disconnect_db(&db_conn);

	// Send the end of authority list
	write_token_into_buffer("is_end_of_phr_authority_list_flag", "1", true, buffer);

	if(!SSL_send_buffer(ssl_client, buffer, strlen(buffer)))
	{
		fprintf(stderr, "Sending the end of PHR authority list failed\n");
		goto ERROR;
	}

	return true;

ERROR:

	if(result)
	{
		mysql_free_result(result);
		result = NULL;
	}

	disconnect_db(&db_conn);
	return false;
}
// Implementation
static boolean change_mail_server_configuration(SSL *ssl_client)
{
	char  buffer[BUFFER_LENGTH + 1];
	char  token_name[TOKEN_NAME_LENGTH + 1];
	char  mail_server_url[URL_LENGTH + 1];
	char  authority_email_address[EMAIL_ADDRESS_LENGTH + 1];
	char  authority_email_passwd[PASSWD_LENGTH + 1];

	MYSQL *db_conn = NULL;
	char  stat[SQL_STATEMENT_LENGTH + 1];
	char  err_msg[ERR_MSG_LENGTH + 1];

	// Receive mail server configuration information
	if(SSL_recv_buffer(ssl_client, buffer, NULL) == 0)
	{
		fprintf(stderr, "Receiving mail server configuration information failed\n");
		goto ERROR;
	}

	// Get mail server configuration tokens from buffer
	if(read_token_from_buffer(buffer, 1, token_name, mail_server_url) != READ_TOKEN_SUCCESS || strcmp(token_name, "mail_server_url") != 0)
	{
		int_error("Extracting the mail_server_url failed");
	}

	if(read_token_from_buffer(buffer, 2, token_name, authority_email_address) != READ_TOKEN_SUCCESS || strcmp(token_name, "authority_email_address") != 0)
	{
		int_error("Extracting the authority_email_address failed");
	}

	if(read_token_from_buffer(buffer, 3, token_name, authority_email_passwd) != READ_TOKEN_SUCCESS || strcmp(token_name, "authority_email_passwd") != 0)
	{
		int_error("Extracting the authority_email_passwd failed");
	}

	// Connect the database
	connect_db(&db_conn, DB_IP, DB_USERNAME, DB_PASSWD, DB_NAME);

	// Update the mail server configuration
	sprintf(stat, "UPDATE %s SET mail_server_url = '%s', authority_email_address = '%s', authority_email_passwd = '%s'", 
		ESA__BASIC_AUTHORITY_INFO, mail_server_url, authority_email_address, authority_email_passwd);

	if(mysql_query(db_conn, stat))
  	{
      		sprintf(err_msg, "Error %u: %s\n", mysql_errno(db_conn), mysql_error(db_conn));
      		int_error(err_msg);
  	}

	disconnect_db(&db_conn);

	// Update values on memory
	strcpy(GLOBAL_mail_server_url, mail_server_url);
	strcpy(GLOBAL_authority_email_address, authority_email_address);
	strcpy(GLOBAL_authority_email_passwd, authority_email_passwd);

	// Send the mail server configuration changing result flag
	write_token_into_buffer("mail_server_configuration_changing_result_flag", "1", true, buffer);
	if(!SSL_send_buffer(ssl_client, buffer, strlen(buffer)))
	{
		fprintf(stderr, "Sending the mail server configuration changing result flag failed\n");
		goto ERROR;
	}

	return true;

ERROR:

	return false;
}
// Implementation
static boolean verify_authentication_request(BIO *bio_client, char *username_ret, boolean *is_admin_flag_ret, char *key_exchange_passwd_ret)
{
	boolean   verification_flag;

	MYSQL     *db_conn = NULL;
  	MYSQL_RES *result  = NULL;
  	MYSQL_ROW row;
	char      stat[SQL_STATEMENT_LENGTH + 1];
	char	  err_msg[ERR_MSG_LENGTH + 1];

	char      token_name[TOKEN_NAME_LENGTH + 1];
	char      is_admin_flag_str_tmp[FLAG_LENGTH + 1];   // "0" or "1"
	char      passwd[PASSWD_LENGTH + 1];
	char      salted_passwd_hash_cmp[SHA1_DIGEST_LENGTH + 1];
	char      salted_passwd_hash[SHA1_DIGEST_LENGTH + 1];
	char      salt_value[SALT_VALUE_LENGTH + 1];
	char      passwd_with_salt_value[PASSWD_LENGTH + SALT_VALUE_LENGTH + 1];

	// Receive the verification information
	if(!BIO_recv_file(bio_client, VERIFICATION_INFO_CIPHERTEXT_PATH))
	{
		fprintf(stderr, "Receiving verification information failed\n");
		goto ERROR;
	}

	// Decrypt the verification information with the User Authority's private key
	if(!smime_decrypt_with_cert(VERIFICATION_INFO_CIPHERTEXT_PATH, VERIFICATION_INFO_PLAINTEXT_PATH, UA_CERTFILE_PATH, UA_CERTFILE_PASSWD, err_msg))
	{
		fprintf(stderr, "Decrypting verification information failed\n\"%s\"\n", err_msg);
		goto ERROR;
	}

	unlink(VERIFICATION_INFO_CIPHERTEXT_PATH);

	// Get the verification information from file
	if(read_token_from_file(VERIFICATION_INFO_PLAINTEXT_PATH, 1, token_name, is_admin_flag_str_tmp) != READ_TOKEN_SUCCESS || strcmp(token_name, "is_admin_flag") != 0)
	{
		int_error("Extracting the is_admin_flag failed");
	}

	*is_admin_flag_ret = (strcmp(is_admin_flag_str_tmp, "1") == 0) ? true : false; 

	if(read_token_from_file(VERIFICATION_INFO_PLAINTEXT_PATH, 2, token_name, username_ret) != READ_TOKEN_SUCCESS || strcmp(token_name, "username") != 0)
	{
		int_error("Extracting the username failed");
	}

	if(read_token_from_file(VERIFICATION_INFO_PLAINTEXT_PATH, 3, token_name, passwd) != READ_TOKEN_SUCCESS || strcmp(token_name, "passwd") != 0)
	{
		int_error("Extracting the passwd failed");
	}

	if(read_token_from_file(VERIFICATION_INFO_PLAINTEXT_PATH, 4, token_name, key_exchange_passwd_ret) 
		!= READ_TOKEN_SUCCESS || strcmp(token_name, "key_exchange_passwd") != 0)
	{
		int_error("Extracting the key_exchange_passwd failed");
	}

	unlink(VERIFICATION_INFO_PLAINTEXT_PATH);

	// Connect the database
	connect_db(&db_conn, DB_IP, DB_USERNAME, DB_PASSWD, DB_NAME);

	// Verify the user
	sprintf(stat, "SELECT salted_passwd_hash, salt_value FROM %s WHERE username LIKE '%s' "
		"COLLATE latin1_general_cs", (*is_admin_flag_ret) ? UA__ADMINS : UA__USERS, username_ret);

	if(mysql_query(db_conn, stat))
  	{
      		sprintf(err_msg, "Error %u: %s\n", mysql_errno(db_conn), mysql_error(db_conn));
      		int_error(err_msg);
  	}

  	result = mysql_store_result(db_conn);
  	row = mysql_fetch_row(result);

	if(row)
	{
		strcpy(salted_passwd_hash_cmp, row[0]);
		strcpy(salt_value, row[1]);

		// Get the salted password hash
		sprintf(passwd_with_salt_value, "%s%s", passwd, salt_value);
		sum_sha1_from_string(passwd_with_salt_value, strlen(passwd_with_salt_value), salted_passwd_hash, SALTED_PASSWD_HASH_PATH);

		if(strcmp(salted_passwd_hash, salted_passwd_hash_cmp) == 0)   // Authentication succeed
		{
			verification_flag = true;
			if(!write_token_into_file("verification_result_flag", "1", true, VERIFICATION_RESULT_PLAINTEXT_PATH))
				int_error("Writing the verification_result_flag failed");
		}
		else   // Authentication failed
		{
			verification_flag = false;
			if(!write_token_into_file("verification_result_flag", "0", true, VERIFICATION_RESULT_PLAINTEXT_PATH))
				int_error("Writing the verification_result_flag failed");

			if(!write_token_into_file("error_msg", "Invalid username or password", false, VERIFICATION_RESULT_PLAINTEXT_PATH))
				int_error("Writing the error_msg failed");
		}
	}
	else      // Authentication failed
	{
		verification_flag = false;
		if(!write_token_into_file("verification_result_flag", "0", true, VERIFICATION_RESULT_PLAINTEXT_PATH))
			int_error("Writing the verification_result_flag failed");

		if(!write_token_into_file("error_msg", "Invalid username or password", false, VERIFICATION_RESULT_PLAINTEXT_PATH))
				int_error("Writing the error_msg failed");
	}

	if(result)
	{
		mysql_free_result(result);
		result = NULL;
	}
	disconnect_db(&db_conn);

	// Encrypt the verification result with random session password
	if(!des3_encrypt(VERIFICATION_RESULT_PLAINTEXT_PATH, VERIFICATION_RESULT_CIPHERTEXT_PATH, key_exchange_passwd_ret, err_msg))
	{
		fprintf(stderr, "Encrypting the verification result failed\n\"%s\"\n", err_msg);
		goto ERROR;
	}

	unlink(VERIFICATION_RESULT_PLAINTEXT_PATH);

	// Send the verification result
	if(!BIO_send_file(bio_client, VERIFICATION_RESULT_CIPHERTEXT_PATH))
	{
		fprintf(stderr, "Sending the verification result failed");
		goto ERROR;
	}

	unlink(VERIFICATION_RESULT_CIPHERTEXT_PATH);
	return verification_flag;

ERROR:
	unlink(VERIFICATION_INFO_CIPHERTEXT_PATH);
	unlink(VERIFICATION_INFO_PLAINTEXT_PATH);
	unlink(VERIFICATION_RESULT_PLAINTEXT_PATH);
	unlink(VERIFICATION_RESULT_CIPHERTEXT_PATH);
	return false;
}
static boolean remove_user(SSL *ssl_client, boolean is_admin_flag)
{
	char         buffer[BUFFER_LENGTH + 1];
	char         token_name[TOKEN_NAME_LENGTH + 1];
	char         username[USER_NAME_LENGTH + 1];

	MYSQL        *db_conn = NULL;
  	MYSQL_RES    *result  = NULL;
  	MYSQL_ROW    row;
	char         stat[SQL_STATEMENT_LENGTH + 1];
	char	     err_msg[ERR_MSG_LENGTH + 1];

	unsigned int user_or_admin_id;

	// Receive user/admin removal information
	if(SSL_recv_buffer(ssl_client, buffer, NULL) == 0)
	{
		fprintf(stderr, "Receiving user/admin removal information failed\n");
		goto ERROR;
	}

	// Get a user/admin removal information token from buffer
	if(read_token_from_buffer(buffer, 1, token_name, username) != READ_TOKEN_SUCCESS || strcmp(token_name, "username") != 0)
		int_error("Extracting the username failed");

	// Connect the database
	connect_db(&db_conn, DB_IP, DB_USERNAME, DB_PASSWD, DB_NAME);

	// Check for the existence of username
	if(is_admin_flag)
	{
		sprintf(stat, "SELECT admin_id FROM %s WHERE username LIKE '%s' COLLATE latin1_general_cs", ESA__ADMINS, username);
	}
	else
	{
		sprintf(stat, "SELECT user_id FROM %s WHERE username LIKE '%s' COLLATE latin1_general_cs", ESA__USERS, username);	
	}

	if(mysql_query(db_conn, stat))
  	{
      		sprintf(err_msg, "Error %u: %s\n", mysql_errno(db_conn), mysql_error(db_conn));
      		int_error(err_msg);
  	}

  	result = mysql_store_result(db_conn);
	row = mysql_fetch_row(result);

	// The user/admin does not exist
	if(!row)
	{
		// Send the user/admin removal result flag
		write_token_into_buffer("user_or_admin_removal_result_flag", "0", true, buffer);
		write_token_into_buffer("error_msg", "User does not exist", false, buffer);

		if(!SSL_send_buffer(ssl_client, buffer, strlen(buffer)))
		{
			fprintf(stderr, "Sending the user/admin removal result flag failed\n");
			goto ERROR;
		}

		goto ERROR;
	}

	user_or_admin_id = atoi(row[0]);

	if(result)
	{
		mysql_free_result(result);
		result = NULL;
	}

	// Delete the user/admin
	if(is_admin_flag)
	{
		sprintf(stat, "DELETE FROM %s WHERE admin_id = %u", ESA__ADMINS, user_or_admin_id);
	}
	else
	{
		sprintf(stat, "DELETE FROM %s WHERE user_id = %u", ESA__USERS, user_or_admin_id);
	}

	if(mysql_query(db_conn, stat))
	{
		sprintf(err_msg, "Error %u: %s\n", mysql_errno(db_conn), mysql_error(db_conn));
		int_error(err_msg);
	}

	disconnect_db(&db_conn);

	// Send the user/admin removal result flag
	write_token_into_buffer("user_or_admin_removal_result_flag", "1", true, buffer);

	if(!SSL_send_buffer(ssl_client, buffer, strlen(buffer)))
	{
		fprintf(stderr, "Sending the user/admin removal result flag failed\n");
		goto ERROR;
	}

	return true;

ERROR:

	if(result)
	{
		mysql_free_result(result);
		result = NULL;
	}

	disconnect_db(&db_conn);
	return false;
}
Beispiel #18
0
void serial_mainloop(void)
{

	unsigned char buf;
	int countbyte = 0, started = 0;
	datarecord data;	// used to collect datas from plc
	datarecord data_response;	// used to send responses to plc

	setzero(&data, sizeof(data));
	first_loop = 1;

	while (1) {

		int buflen = 0;

		buflen = read(portfd, &buf, 1);

		if (buflen == -1) {
			printFatal(strerror(errno));
		}

		if (!started && buf == SOH && !countbyte) {
			started = 1;
			countbyte++;
			data.start = buf;
			continue;
		}

		if (started) {
			switch (countbyte) {
			case 1:
				/* 0x18 == 24 */
				/* if byte 1 isn't 0x18 retry... */
				if (buf != 0x18) {
					started = 0;
					countbyte = 0;
					continue;
				}
				data.length = buf;
				break;
				/* if byte 2 isn't 0x04 retry... */
			case 2:
				if (buf != 0x04) {
					started = 0;
					countbyte = 0;
					continue;
				}
				data.cmd = buf;
				break;
			}

			/* put bytes from 3 to 27 into the struct field */
			if (countbyte >= 3 && countbyte < data.length + 3) {
				data.databytes[countbyte - 3] = buf;
			}

			/* the byte 27 is the checksum given by the plc */
			if (countbyte == 27) {
				data.checksum = buf;
				if (cfg.verbose) {
					// TODO: improve logging and printf debug behaviour
					// TODO: take the log util functions from netsukuku src
					printf
					    ("catch BCC checksum value: %#x\n",
					     data.checksum);
					printf
					    ("calculated BCC checksum value: %#x\n",
					     (unsigned char)
					     calculateBCC(data));
				}
			}

			/* the byte 28 is the last byte of the record and it must be ETX */
			if (countbyte == 28 && buf == ETX) {
				data.end = buf;
				started = 0;
				countbyte = 0;
				int tmpcurr = 0;
				float tmpvolt = 0;

				// MAX_VOLT : MAX_HEX_VALUE = x : bytes
				tmpvolt =
				    (unsigned int) FETCH2BYTES(5, 4,
							       data.databytes);
				if (tmpvolt > MAX_HEX_VALUE)
					data.voltage = 0;
				else
					data.voltage =
					    tmpvolt * (float) MAX_VOLT /
					    (float) MAX_HEX_VALUE *emb_info.k1;

				tmpcurr =
				    (unsigned int) FETCH2BYTES(7, 6,
							       data.databytes);
				if (tmpcurr > MAX_HEX_VALUE)
					data.current = 0;
				else
					data.current =
					    (int) ((float) tmpcurr *
						   (float) MAX_VOLT /
						   (float) MAX_HEX_VALUE *
						   emb_info.k2);

				data.encoder[0] =
				    (unsigned long int) FETCH4BYTES(data.
								    databytes,
								    8) /
				    emb_info.array_island_k1[0];
				data.encoder[1] =
				    (unsigned long int) FETCH4BYTES(data.
								    databytes,
								    12) /
				    emb_info.array_island_k1[1];
				data.encoder[2] =
				    (unsigned long int) FETCH4BYTES(data.
								    databytes,
								    16) /
				    emb_info.array_island_k1[2];
				data.encoder[3] =
				    (unsigned long int) FETCH4BYTES(data.
								    databytes,
								    20) /
				    emb_info.array_island_k1[3];
				if (cfg.verbose) {
					// TODO: improve logging and printf debug behaviour
					printf
					    ("contacolpi1: %f, contacolpi2: %f, ",
					     data.encoder[0], data.encoder[1]);
					printf
					    ("contacolpi3: %f, contacolpi4: %f, ",
					     data.encoder[2], data.encoder[3]);
					printf
					    ("voltage value: %f, current value: %d\n",
					     data.voltage, data.current);
				}

				if (cfg.verbose) {
					int i;
					// TODO: take the log util functions from netsukuku src
					// TODO: improve logging and printf debug behaviour
					// printf("catch start code: %#x\n", data.start);
					// printf("catch len code: %#x\n",   data.length);
					// printf("catch cmd  code: %#x\n",  data.cmd);
					for (i = 0; i < 24; i++) {
						printf("byte[%d]: %#x\n",
						       i, data.databytes[i]);
					}
				}

				/* if the checksum given by the plc is the same we have 
				 * calculated send ack */
				if ((unsigned char) calculateBCC(data) ==
				    (unsigned char) data.checksum) {
					/* compile the response data record with the ACK byte
					 * the response is the same record except for the first 
					 * data byte that is ACK
					 */
					memcpy(&data_response, &data,
					       sizeof(data));
					data_response.databytes[0] = ACK;
					connect_db(cfg.dsn, cfg.dbuser,
						   cfg.dbpass);
					if (cfg.polling)
						get_embedded_infos();
					/* TODO: do all the processing SQL things */
					do_sql_things(data);
					disconnect_db();
					if (cfg.verbose)
						printf("ok, sending ACK...\n");
					/* send response */
					send_response(portfd, data_response);
				} else {
					memcpy(&data_response, &data,
					       sizeof(data));
					data_response.databytes[0] = NACK;
					//if(cfg.polling)       get_embedded_infos();
					//do_sql_things(data);
					if (cfg.verbose)
						printf("ok, sending NACK...\n");
					/* send response */
					send_response(portfd, data_response);
				}

				setzero(&data, sizeof(data));
				setzero(&data_response, sizeof(data_response));

				continue;
			}

			countbyte++;

		}

	}

	close(portfd);

}
static boolean respond_only_restricted_phr_list_loading(SSL *ssl_client)
{
	char         buffer[BUFFER_LENGTH + 1];
	char         token_name[TOKEN_NAME_LENGTH + 1];
	char         phr_ownername[USER_NAME_LENGTH + 1];

	SSL          *ssl_PHRsv_conn = NULL;

	char         is_end_of_restricted_phr_list_flag_str_tmp[FLAG_LENGTH + 1];    // "0" or "1"
	boolean      is_end_of_restricted_phr_list_flag;

	char         phr_id_str_tmp[INT_TO_STR_DIGITS_LENGTH + 1];
	unsigned int phr_id;

	char         emergency_unit_name[AUTHORITY_NAME_LENGTH + 1];
	char         emergency_staff_name[USER_NAME_LENGTH + 1];

	MYSQL        *db_conn = NULL;

	unsigned int no_approvals;
	char         no_approvals_str_tmp[INT_TO_STR_DIGITS_LENGTH + 1];

	unsigned int threshold_value;
	char         threshold_value_str_tmp[INT_TO_STR_DIGITS_LENGTH + 1];
	char         request_status[RESTRICTED_PHR_REQUEST_STATUS_LENGTH + 1];

	// Get the emergency staff info
	get_cert_owner_info(ssl_client, emergency_unit_name, emergency_staff_name);
	
	// Receive the restricted-level PHR list loading information
	if(SSL_recv_buffer(ssl_client, buffer, NULL) == 0)
	{
		fprintf(stderr, "Receiving the restricted-level PHR list loading information failed\n");
		goto ERROR;
	}

	// Get the restricted-level PHR list loading information token from buffer
	if(read_token_from_buffer(buffer, 1, token_name, phr_ownername) != READ_TOKEN_SUCCESS || strcmp(token_name, "phr_ownername") != 0)
		int_error("Extracting the phr_ownername failed");

	// Connect to PHR Server
	if(!connect_to_emergency_phr_list_loading_service(&ssl_PHRsv_conn))
		goto ERROR;

	// Send request information
	write_token_into_buffer("request", ONLY_RESTRICTED_LEVEL_PHR_LIST_LOADING, true, buffer);

	if(!SSL_send_buffer(ssl_PHRsv_conn, buffer, strlen(buffer)))
	{
		fprintf(stderr, "Sending request information failed\n");
		goto ERROR;
	}

	// Send the restricted-level PHR list loading information
	write_token_into_buffer("phr_ownername", phr_ownername, true, buffer);
	write_token_into_buffer("phr_owner_authority_name", GLOBAL_authority_name, false, buffer);

	if(!SSL_send_buffer(ssl_PHRsv_conn, buffer, strlen(buffer)))
	{
		fprintf(stderr, "Sending the restricted-level PHR list loading information failed\n");
		goto ERROR;
	}

	// Connect the database
	connect_db(&db_conn, DB_IP, DB_USERNAME, DB_PASSWD, DB_NAME);

	// Restricted-level PHRs
	while(1)
	{
		char data_description[DATA_DESCRIPTION_LENGTH + 1];
		char file_size_str_tmp[INT_TO_STR_DIGITS_LENGTH + 1];

		// Receive restricted-level PHR information
		if(SSL_recv_buffer(ssl_PHRsv_conn, buffer, NULL) == 0)
		{
			fprintf(stderr, "Receiving the restricted-level PHR information failed\n");
			goto ERROR;
		}		

		// Get the is_end_of_restricted_phr_list_flag token from buffer
		if(read_token_from_buffer(buffer, 1, token_name, is_end_of_restricted_phr_list_flag_str_tmp) 
			!= READ_TOKEN_SUCCESS || strcmp(token_name, "is_end_of_restricted_phr_list_flag") != 0)
		{
			int_error("Extracting the is_end_of_restricted_phr_list_flag failed");
		}

		is_end_of_restricted_phr_list_flag = (strcmp(is_end_of_restricted_phr_list_flag_str_tmp, "1") == 0) ? true : false;
		if(is_end_of_restricted_phr_list_flag)
			break;

		if(read_token_from_buffer(buffer, 2, token_name, phr_id_str_tmp) != READ_TOKEN_SUCCESS || strcmp(token_name, "phr_id") != 0)
		{
			int_error("Extracting the phr_id failed");
		}

		phr_id = atoi(phr_id_str_tmp);

		if(read_token_from_buffer(buffer, 3, token_name, data_description) != READ_TOKEN_SUCCESS || strcmp(token_name, "data_description") != 0)
		{
			int_error("Extracting the data_description failed");
		}

		if(read_token_from_buffer(buffer, 4, token_name, file_size_str_tmp) != READ_TOKEN_SUCCESS || strcmp(token_name, "file_size") != 0)
		{
			int_error("Extracting the file_size failed");
		}

		// Get a restricted-level PHR request status
		get_restricted_phr_request_status(db_conn, phr_id, emergency_unit_name, emergency_staff_name, &no_approvals, &threshold_value, request_status);

		sprintf(no_approvals_str_tmp, "%u", no_approvals);
		sprintf(threshold_value_str_tmp, "%u", threshold_value);

		// Re-pack the information
		write_token_into_buffer("is_end_of_restricted_phr_list_flag", "0", true, buffer);
		write_token_into_buffer("phr_id", phr_id_str_tmp, false, buffer);
		write_token_into_buffer("data_description", data_description, false, buffer);
		write_token_into_buffer("file_size", file_size_str_tmp, false, buffer);
		
		// Append the request info
		write_token_into_buffer("approvals", no_approvals_str_tmp, false, buffer);
		write_token_into_buffer("threshold_value", threshold_value_str_tmp, false, buffer);
		write_token_into_buffer("request_status", request_status, false, buffer);

		if(!SSL_send_buffer(ssl_client, buffer, strlen(buffer)))
		{
			fprintf(stderr, "Sending the restricted-level PHR information failed\n");
			goto ERROR;
		}
	}

	// Send the is_end_of_restricted_phr_list_flag
	if(!SSL_send_buffer(ssl_client, buffer, strlen(buffer)))
	{
		fprintf(stderr, "Sending the is_end_of_restricted_phr_list_flag failed\n");
		goto ERROR;
	}

	disconnect_db(&db_conn);

	SSL_cleanup(ssl_PHRsv_conn);
	ssl_PHRsv_conn = NULL;
	return true;

ERROR:

	if(db_conn)
	{
		disconnect_db(&db_conn);
		db_conn = NULL;
	}

	if(ssl_PHRsv_conn)
	{
		SSL_cleanup(ssl_PHRsv_conn);
		ssl_PHRsv_conn = NULL;
	}

	return false;
}
static boolean remove_access_permission(SSL *ssl_client, char *desired_user_authority_name, char *desired_username)
{
	char         buffer[BUFFER_LENGTH + 1];
	char         phr_owner_name[USER_NAME_LENGTH + 1];
	unsigned int phr_owner_id;
	unsigned int desired_user_authority_id;
	unsigned int desired_user_id;
	unsigned int assigned_permission_id;	

	MYSQL        *db_conn = NULL;
  	MYSQL_RES    *result  = NULL;
	char         stat[SQL_STATEMENT_LENGTH + 1];
	char	     err_msg[ERR_MSG_LENGTH + 1];

	// Get certificate owner's name
	get_cert_ownername(ssl_client, GLOBAL_authority_name, phr_owner_name, NULL);

	// The desired user must not be the same one with the PHR owner
	if(strcmp(desired_user_authority_name, GLOBAL_authority_name) == 0 && strcmp(desired_username, phr_owner_name) == 0)
	{
		// Send the access permission removal result flag
		write_token_into_buffer("access_permission_removal_result_flag", "0", true, buffer);
		write_token_into_buffer("error_msg", "Invalid operation", false, buffer);

		if(!SSL_send_buffer(ssl_client, buffer, strlen(buffer)))
		{
			fprintf(stderr, "Sending the access permission removal result flag failed\n");
			goto ERROR;
		}

		goto ERROR;
	}

	// Connect the database
	connect_db(&db_conn, DB_IP, DB_USERNAME, DB_PASSWD, DB_NAME);

	// Check for the existence of the desired user
	if(!does_desired_user_exists(db_conn, desired_username, desired_user_authority_name, &desired_user_id, &desired_user_authority_id))
	{
		// Send the access permission removal result flag
		write_token_into_buffer("access_permission_removal_result_flag", "0", true, buffer);
		write_token_into_buffer("error_msg", "Do not found your desired user", false, buffer);

		if(!SSL_send_buffer(ssl_client, buffer, strlen(buffer)))
		{
			fprintf(stderr, "Sending the access permission removal result flag failed\n");
			goto ERROR;
		}

		goto ERROR;
	}

	// Query for the PHR owner id
	if(!get_phr_owner_id(db_conn, phr_owner_name, &phr_owner_id))
	{
		// Send the access permission removal result flag
		write_token_into_buffer("access_permission_removal_result_flag", "0", true, buffer);
		write_token_into_buffer("error_msg", "Getting the PHR owner id from a database failed", false, buffer);

		if(!SSL_send_buffer(ssl_client, buffer, strlen(buffer)))
		{
			fprintf(stderr, "Sending the access permission removal result flag failed\n");
			goto ERROR;
		}

		goto ERROR;
	}

	// Check for the existence of access permission for this desired user
	if(!does_desired_user_access_permission_exists(db_conn, phr_owner_id, desired_user_id, desired_user_authority_id, &assigned_permission_id))
	{
		// Send the access permission removal result flag
		write_token_into_buffer("access_permission_removal_result_flag", "0", true, buffer);
		write_token_into_buffer("error_msg", "Getting the assigned permission id from a database failed", false, buffer);

		if(!SSL_send_buffer(ssl_client, buffer, strlen(buffer)))
		{
			fprintf(stderr, "Sending the access permission removal result flag failed\n");
			goto ERROR;
		}

		goto ERROR;
	}

	// Delete the access permission for this desired user (permissions_assigned_to_others)
	sprintf(stat, "DELETE FROM %s WHERE assigned_permission_id = %u", UA__PERMISSIONS_ASSIGNED_TO_OTHERS, assigned_permission_id);
	if(mysql_query(db_conn, stat))
	{
		sprintf(err_msg, "Error %u: %s\n", mysql_errno(db_conn), mysql_error(db_conn));
		int_error(err_msg);
	}

	// If the desired user is in the same authority with the PHR owner then delete desired user's 
	// access permission in an access_permissions table, unless wait for synchronization mechanism
	if(desired_user_authority_id == GLOBAL_authority_id)
	{
		// Delete the access permission for this desired user (access_permissions)
		sprintf(stat, "DELETE FROM %s WHERE user_id = %u AND phr_owner_id = %u AND phr_owner_authority_id = %u", 
			UA__ACCESS_PERMISSIONS, desired_user_id, phr_owner_id, GLOBAL_authority_id);

		if(mysql_query(db_conn, stat))
	  	{
	      		sprintf(err_msg, "Error %u: %s\n", mysql_errno(db_conn), mysql_error(db_conn));
	      		int_error(err_msg);
	  	}	
	}

	disconnect_db(&db_conn);

	// Send the access permission removal result flag
	write_token_into_buffer("access_permission_removal_result_flag", "1", true, buffer);

	if(!SSL_send_buffer(ssl_client, buffer, strlen(buffer)))
	{
		fprintf(stderr, "Sending the access permission removal result flag failed\n");
		goto ERROR;
	}

	// Record a transaction log
	record_transaction_log(ssl_client, desired_username, desired_user_authority_name, NO_SPECIFIC_DATA, ACCESS_PERMISSION_REMOVAL_MSG);
	return true;

ERROR:

	if(result)
	{
		mysql_free_result(result);
		result = NULL;
	}

	disconnect_db(&db_conn);
	return false;
}
static boolean assign_access_permission(SSL *ssl_client, char *desired_user_authority_name, char *desired_username, 
	boolean upload_permission_flag, boolean download_permission_flag, boolean delete_permission_flag)
{
	char         buffer[BUFFER_LENGTH + 1];
	char         phr_owner_name[USER_NAME_LENGTH + 1];
	unsigned int phr_owner_id;
	unsigned int desired_user_authority_id;
	unsigned int desired_user_id;
	unsigned int assigned_permission_id;	

	MYSQL        *db_conn = NULL;
  	MYSQL_RES    *result  = NULL;
	char         stat[SQL_STATEMENT_LENGTH + 1];
	char	     err_msg[ERR_MSG_LENGTH + 1];

	char         object_description[DATA_DESCRIPTION_LENGTH + 1];

	// Get certificate owner's name
	get_cert_ownername(ssl_client, GLOBAL_authority_name, phr_owner_name, NULL);

	// The desired user must not be the same one with the PHR owner
	if(strcmp(desired_user_authority_name, GLOBAL_authority_name) == 0 && strcmp(desired_username, phr_owner_name) == 0)
	{
		// Send the access permission assignment result flag
		write_token_into_buffer("access_permission_assignment_result_flag", "0", true, buffer);
		write_token_into_buffer("error_msg", "You have access permissions to your own data already", false, buffer);

		if(!SSL_send_buffer(ssl_client, buffer, strlen(buffer)))
		{
			fprintf(stderr, "Sending the access permission assignment result flag failed\n");
			goto ERROR;
		}

		goto ERROR;
	}

	// Connect the database
	connect_db(&db_conn, DB_IP, DB_USERNAME, DB_PASSWD, DB_NAME);

	// Check for the existence of the desired user
	if(!does_desired_user_exists(db_conn, desired_username, desired_user_authority_name, &desired_user_id, &desired_user_authority_id))
	{
		// Send the access permission assignment result flag
		write_token_into_buffer("access_permission_assignment_result_flag", "0", true, buffer);
		write_token_into_buffer("error_msg", "Do not found the user that you're looking for", false, buffer);

		if(!SSL_send_buffer(ssl_client, buffer, strlen(buffer)))
		{
			fprintf(stderr, "Sending the access permission assignment result flag failed\n");
			goto ERROR;
		}

		goto ERROR;
	}

	// Query for the PHR owner id
	if(!get_phr_owner_id(db_conn, phr_owner_name, &phr_owner_id))
	{
		// Send the access permission assignment result flag
		write_token_into_buffer("access_permission_assignment_result_flag", "0", true, buffer);
		write_token_into_buffer("error_msg", "Getting the PHR owner id from a database failed", false, buffer);

		if(!SSL_send_buffer(ssl_client, buffer, strlen(buffer)))
		{
			fprintf(stderr, "Sending the access permission assignment result flag failed\n");
			goto ERROR;
		}

		goto ERROR;
	}

	// Check for the existence of access permission for this desired user
	if(does_desired_user_access_permission_exists(db_conn, phr_owner_id, desired_user_id, desired_user_authority_id, &assigned_permission_id))
	{
		// Send the access permission assignment result flag
		write_token_into_buffer("access_permission_assignment_result_flag", "0", true, buffer);
		write_token_into_buffer("error_msg", "You have assigned the permission to this user already", false, buffer);

		if(!SSL_send_buffer(ssl_client, buffer, strlen(buffer)))
		{
			fprintf(stderr, "Sending the access permission assignment result flag failed\n");
			goto ERROR;
		}

		goto ERROR;
	}

	// Insert the access permission for this desired user (permissions_assigned_to_others)
	sprintf(stat, "INSERT INTO %s(user_id, object_user_id, object_user_authority_id, upload_permission_flag, download_permission_flag, "
		"delete_permission_flag) VALUES(%u, %u, %u, '%s', '%s', '%s')", UA__PERMISSIONS_ASSIGNED_TO_OTHERS, phr_owner_id, desired_user_id, 
		desired_user_authority_id, (upload_permission_flag) ? "1" : "0", (download_permission_flag) ? "1" : "0", (delete_permission_flag) ? "1" : "0");

	if(mysql_query(db_conn, stat))
  	{
      		sprintf(err_msg, "Error %u: %s\n", mysql_errno(db_conn), mysql_error(db_conn));
      		int_error(err_msg);
  	}

	// If the desired user is in the same authority with the PHR owner then insert desired user's 
	// access permission in an access_permissions table, unless wait for synchronization mechanism
	if(desired_user_authority_id == GLOBAL_authority_id)
	{
		// Insert the access permission for this desired user (access_permissions)
		sprintf(stat, "INSERT INTO %s(user_id, phr_owner_id, phr_owner_authority_id, upload_permission_flag, download_permission_flag, "
			"delete_permission_flag) VALUES(%u, %u, %u, '%s', '%s', '%s')", UA__ACCESS_PERMISSIONS, desired_user_id, phr_owner_id, 
			GLOBAL_authority_id, (upload_permission_flag) ? "1" : "0", (download_permission_flag) ? "1" : "0", (delete_permission_flag) ? "1" : "0");

		if(mysql_query(db_conn, stat))
	  	{
	      		sprintf(err_msg, "Error %u: %s\n", mysql_errno(db_conn), mysql_error(db_conn));
	      		int_error(err_msg);
	  	}	
	}
	
	disconnect_db(&db_conn);

	// Send the access permission assignment result flag
	write_token_into_buffer("access_permission_assignment_result_flag", "1", true, buffer);

	if(!SSL_send_buffer(ssl_client, buffer, strlen(buffer)))
	{
		fprintf(stderr, "Sending the access permission assignment result flag failed\n");
		goto ERROR;
	}

	// Record a transaction log
	sprintf(object_description, "Access permission: <upload: %s><download: %s><delete: %s>", (upload_permission_flag) ? "true" : "false", 
		(download_permission_flag) ? "true" : "false", (delete_permission_flag) ? "true" : "false");

	record_transaction_log(ssl_client, desired_username, desired_user_authority_name, object_description, ACCESS_PERMISSION_ASSIGNMENT_MSG);
	return true;

ERROR:

	if(result)
	{
		mysql_free_result(result);
		result = NULL;
	}

	disconnect_db(&db_conn);
	return false;
}
Beispiel #22
0
static void get_db_charsets(conn_info_t *params_p, ub2 *char_csid, 
                            ub2 *nchar_csid)
{
  OCIDefine  *defnp1 = (OCIDefine *) NULL;
  OCIDefine  *defnp2 = (OCIDefine *) NULL;
  oratext     parm[PARM_BUFLEN];
  oratext     value[OCI_NLS_MAXBUFSZ];
  ub2         parm_len = 0;
  ub2         value_len = 0;
  oci_t       ocistruct; 
  oci_t      *ocip = &ocistruct;
   
  *char_csid = 0;
  *nchar_csid = 0;
  memset (ocip, 0, sizeof(ocistruct));

  if (OCIEnvCreate(&ocip->envp, OCI_OBJECT, (dvoid *)0,
                   (dvoid * (*)(dvoid *, size_t)) 0,
                   (dvoid * (*)(dvoid *, dvoid *, size_t))0,
                   (void (*)(dvoid *, dvoid *)) 0,
                   (size_t) 0, (dvoid **) 0))
  {
    ocierror(ocip, (char *)"OCIEnvCreate() failed", TRUE);
  }

  if (OCIHandleAlloc((dvoid *) ocip->envp, (dvoid **) &ocip->errp,
                     (ub4) OCI_HTYPE_ERROR, (size_t) 0, (dvoid **) 0))
  {
    ocierror(ocip, (char *)"OCIHandleAlloc(OCI_HTYPE_ERROR) failed", TRUE);
  }

  OCICALL(ocip, 
          OCILogon(ocip->envp, ocip->errp, &ocip->svcp,
                   params_p->user, params_p->userlen,
                   params_p->passw, params_p->passwlen,
                   params_p->dbname, params_p->dbnamelen));

  OCICALL(ocip, 
          OCIHandleAlloc((dvoid *) ocip->envp, (dvoid **) &ocip->stmtp,
                         (ub4) OCI_HTYPE_STMT, (size_t) 0, (dvoid **) 0));

  /* Execute stmt to select the db nls char and nchar character set */ 
  OCICALL(ocip, 
          OCIStmtPrepare(ocip->stmtp, ocip->errp,
                         (CONST text *)GET_DB_CHARSETS,
                         (ub4)strlen((char *)GET_DB_CHARSETS),
                         (ub4)OCI_NTV_SYNTAX, (ub4)OCI_DEFAULT));

  OCICALL(ocip,
          OCIDefineByPos(ocip->stmtp, &defnp1,
                         ocip->errp, (ub4) 1, parm,
                         PARM_BUFLEN, SQLT_CHR, (void*) 0,
                         &parm_len, (ub2 *)0, OCI_DEFAULT));

  OCICALL(ocip,
          OCIDefineByPos(ocip->stmtp, &defnp2,
                         ocip->errp, (ub4) 2, value,
                         OCI_NLS_MAXBUFSZ, SQLT_CHR, (void*) 0,
                         &value_len, (ub2 *)0, OCI_DEFAULT));

  OCICALL(ocip, 
          OCIStmtExecute(ocip->svcp, ocip->stmtp, 
                         ocip->errp, (ub4)0, (ub4)0, 
                         (const OCISnapshot *)0,
                         (OCISnapshot *)0, (ub4)OCI_DEFAULT));

  while (OCIStmtFetch(ocip->stmtp, ocip->errp, 1,
                      OCI_FETCH_NEXT, OCI_DEFAULT) == OCI_SUCCESS)
  {
    value[value_len] = '\0';
    if (parm_len == strlen("NLS_CHARACTERSET") &&
        !memcmp(parm, "NLS_CHARACTERSET", parm_len))
    {
      *char_csid = OCINlsCharSetNameToId(ocip->envp, value);
      printf("Outbound database NLS_CHARACTERSET = %.*s (csid = %d) \n",
             value_len, value, *char_csid);
    }
    else if (parm_len == strlen("NLS_NCHAR_CHARACTERSET") &&
             !memcmp(parm, "NLS_NCHAR_CHARACTERSET", parm_len))
    {
      *nchar_csid = OCINlsCharSetNameToId(ocip->envp, value);
      printf("Outbound database NLS_NCHAR_CHARACTERSET = %.*s (csid = %d) \n",
             value_len, value, *nchar_csid);
    }
  }

  disconnect_db(ocip);
}
// A PHR owner is assumed to be in current authority but a trusted user can be in another authority
static boolean load_emergency_trusted_user_list(SSL *ssl_client)
{
	MYSQL        *db_conn = NULL;
	MYSQL_RES    *result  = NULL;
  	MYSQL_ROW    row;
	char         stat[SQL_STATEMENT_LENGTH + 1];
	char	     err_msg[ERR_MSG_LENGTH + 1];

	char         phr_owner_name[USER_NAME_LENGTH + 1];
	unsigned int trusted_user_id;
	char         trusted_username[USER_NAME_LENGTH + 1];
	char         trusted_user_authority_name[AUTHORITY_NAME_LENGTH + 1];
	char         buffer[BUFFER_LENGTH + 1];

	// Get certificate owner's name
	get_cert_ownername(ssl_client, GLOBAL_authority_name, phr_owner_name, NULL);

	// Connect the database
	connect_db(&db_conn, DB_IP, DB_USERNAME, DB_PASSWD, DB_NAME);

	// Query the emergency trusted user list of the requestor
	sprintf(stat, "SELECT DGT.trusted_user_id FROM %s DGT, %s USR WHERE DGT.phr_owner_id = USR.user_id AND USR.username LIKE '%s' COLLATE latin1_general_cs "
		"AND USR.authority_id = %u AND DGT.rejection_by_trusted_user_flag = '0'", EMS__DELEGATIONS, EMS__USERS, phr_owner_name, GLOBAL_authority_id);

	if(mysql_query(db_conn, stat))
  	{
      		sprintf(err_msg, "Error %u: %s\n", mysql_errno(db_conn), mysql_error(db_conn));
      		int_error(err_msg);
  	}

  	result = mysql_store_result(db_conn);
	while((row = mysql_fetch_row(result)))
	{
		trusted_user_id = atoi(row[0]);
		get_user_information(db_conn, trusted_user_id, trusted_username, trusted_user_authority_name);

		// Send the emergency trusted user information
		write_token_into_buffer("is_end_of_emergency_trusted_user_list_flag", "0", true, buffer);
		write_token_into_buffer("trusted_username", trusted_username, false, buffer);
		write_token_into_buffer("trusted_user_authority_name", trusted_user_authority_name, false, buffer);

		if(!SSL_send_buffer(ssl_client, buffer, strlen(buffer)))
		{
			fprintf(stderr, "Sending the emergency trusted user information failed\n");
			goto ERROR;
		}
	}

	if(result)
	{
		mysql_free_result(result);
		result = NULL;
	}

	disconnect_db(&db_conn);

	// Send the end of emergency trusted user list
	write_token_into_buffer("is_end_of_emergency_trusted_user_list_flag", "1", true, buffer);

	if(!SSL_send_buffer(ssl_client, buffer, strlen(buffer)))
	{
		fprintf(stderr, "Sending the end of emergency trusted user list failed\n");
		goto ERROR;
	}

	return true;

ERROR:

	if(result)
	{
		mysql_free_result(result);
		result = NULL;
	}

	disconnect_db(&db_conn);
	return false;
}
Beispiel #24
0
static int connect_db(db_con_t* _h, const char* _db_url)
{
	char* user, *password, *host, *port, *database;

	if(! _h)
	{
		PLOG("connect_db", "must pass db_con_t!");
		return(-1);
	}

	if(CON_CONNECTED(_h))
	{
		DLOG("connect_db", "disconnect first!");
		disconnect_db(_h);
	}

	/*
	** CON_CONNECTED(_h) is now 0, set by disconnect_db()
	*/

	/*
	** Note :
	** Make a scratch pad copy of given SQL URL.
	** all memory allocated to this connection is rooted
	** from this.
	** This is an important concept.
	** as long as you always allocate memory using the function:
	** mem = aug_alloc(size, CON_SQLURL(_h)) or
	** str = aug_strdup(string, CON_SQLURL(_h))
	** where size is the amount of memory, then in the future
	** when CON_SQLURL(_h) is freed (in the function disconnect_db())
	** all other memory allocated in this manner is freed.
	** this will keep memory leaks from happening.
	*/
	CON_SQLURL(_h) = aug_strdup((char *) _db_url, (char *) _h);

	/*
	** get the connection parameters parsed from the db_url string
	** it looks like: postgres://username:userpass@dbhost:dbport/dbname
	** username/userpass : name and password for the database
	** dbhost :            the host name or ip address hosting the database
	** dbport :            the port to connect to database on
	** dbname :            the name of the database
	*/
	if(parse_sql_url(CON_SQLURL(_h),
		&user,&password,&host,&port,&database) < 0)
	{
		char buf[256];
		sprintf(buf, "Error while parsing %s", _db_url);
		PLOG("connect_db", buf);

		aug_free(CON_SQLURL(_h));
		return -3;
	}

	/*
	** finally, actually connect to the database
	*/
	CON_CONNECTION(_h) =
		PQsetdbLogin(host,port,NULL,NULL,database,user, password);

	if(CON_CONNECTION(_h) == 0
	    || PQstatus(CON_CONNECTION(_h)) != CONNECTION_OK)
	{
		PLOG("connect_db", PQerrorMessage(CON_CONNECTION(_h)));
		PQfinish(CON_CONNECTION(_h));
		aug_free(CON_SQLURL(_h));
		return -4;
	}

	CON_PID(_h) = getpid();

	/*
	** all is well, database was connected, we can now submit_query's
	*/
	CON_CONNECTED(_h) = 1;
	return 0;
}
static boolean reset_user_passwd(SSL *ssl_client, boolean is_admin_flag)
{
	char         buffer[BUFFER_LENGTH + 1];
	char         token_name[TOKEN_NAME_LENGTH + 1];
	char         username[USER_NAME_LENGTH + 1];

	MYSQL        *db_conn = NULL;
  	MYSQL_RES    *result  = NULL;
  	MYSQL_ROW    row;
	char         stat[SQL_STATEMENT_LENGTH + 1];
	char	     err_msg[ERR_MSG_LENGTH + 1];

	unsigned int user_or_admin_id;
	char         email_address[EMAIL_ADDRESS_LENGTH + 1];

	char         random_passwd[PASSWD_LENGTH + 1];
	char         random_salt_value[SALT_VALUE_LENGTH + 1];
	char         random_passwd_with_salt_value[PASSWD_LENGTH + SALT_VALUE_LENGTH + 1];
	char         salted_passwd_hash[SHA1_DIGEST_LENGTH + 1];

	// Receive user/admin password resetting information
	if(SSL_recv_buffer(ssl_client, buffer, NULL) == 0)
	{
		fprintf(stderr, "Receiving user/admin password resetting information failed\n");
		goto ERROR;
	}

	// Get a user/admin password resetting information token from buffer
	if(read_token_from_buffer(buffer, 1, token_name, username) != READ_TOKEN_SUCCESS || strcmp(token_name, "username") != 0)
		int_error("Extracting the username failed");

	// Connect the database
	connect_db(&db_conn, DB_IP, DB_USERNAME, DB_PASSWD, DB_NAME);

	// Check for the existence of username
	if(is_admin_flag)
	{
		sprintf(stat, "SELECT admin_id, email_address FROM %s WHERE username LIKE '%s' COLLATE latin1_general_cs", ESA__ADMINS, username);
	}
	else
	{
		sprintf(stat, "SELECT user_id, email_address FROM %s WHERE username LIKE '%s' COLLATE latin1_general_cs", ESA__USERS, username);
	}

	if(mysql_query(db_conn, stat))
  	{
      		sprintf(err_msg, "Error %u: %s\n", mysql_errno(db_conn), mysql_error(db_conn));
      		int_error(err_msg);
  	}

  	result = mysql_store_result(db_conn);
	row = mysql_fetch_row(result);

	// The user/admin does not exist
	if(!row)
	{
		// Send the user/admin password resetting result flag
		write_token_into_buffer("user_or_admin_passwd_resetting_result_flag", "0", true, buffer);
		write_token_into_buffer("error_msg", "User does not exist", false, buffer);

		if(!SSL_send_buffer(ssl_client, buffer, strlen(buffer)))
		{
			fprintf(stderr, "Sending the user/admin password resetting result flag failed\n");
			goto ERROR;
		}

		goto ERROR;
	}

	user_or_admin_id = atoi(row[0]);
	strcpy(email_address, row[1]);

	if(result)
	{
		mysql_free_result(result);
		result = NULL;
	}

	// Generate a random 8 character password
	gen_random_password(random_passwd);

	// Generate a random 8 character salt value
	gen_random_salt_value(random_salt_value);

	// Get the salted password hash
	sprintf(random_passwd_with_salt_value, "%s%s", random_passwd, random_salt_value);
	sum_sha1_from_string(random_passwd_with_salt_value, strlen(random_passwd_with_salt_value), salted_passwd_hash, SALTED_PASSWD_HASH_PATH);

	// Update the password hash information
	if(is_admin_flag)
	{
		sprintf(stat, "UPDATE %s SET salted_passwd_hash = '%s', salt_value = '%s' WHERE admin_id = %u", 
			ESA__ADMINS, salted_passwd_hash, random_salt_value, user_or_admin_id);
	}
	else
	{
		sprintf(stat, "UPDATE %s SET salted_passwd_hash = '%s', salt_value = '%s' WHERE user_id = %u", 
			ESA__USERS, salted_passwd_hash, random_salt_value, user_or_admin_id);
	}

	if(mysql_query(db_conn, stat))
	{
	      	sprintf(err_msg, "Error %u: %s\n", mysql_errno(db_conn), mysql_error(db_conn));
	      	int_error(err_msg);
	}

	// Generate an SSL certificate
	generate_ssl_cert(db_conn, user_or_admin_id, username, is_admin_flag, random_passwd, email_address, SSL_CERT_PRIV_KEY_PATH, SSL_CERT_REQ_PATH, ENC_SSL_CERT_PATH, 
		FULL_ENC_SSL_CERT_PATH, FULL_ENC_SSL_CERT_HASH_PATH);

	disconnect_db(&db_conn);

	// Lock an e-mail sending
	if(sem_wait(&email_sending_lock_mutex) != 0)
		int_error("Locking the mutex failed");

	if(!send_passwd_to_user_email_address(email_address, username, is_admin_flag, random_passwd))
	{
		// Send the user/admin password resetting result flag
		write_token_into_buffer("user_or_admin_passwd_resetting_result_flag", "0", true, buffer);
		write_token_into_buffer("error_msg", get_send_email_error_msg(), false, buffer);

		// Unlock an e-mail sending
		if(sem_post(&email_sending_lock_mutex) != 0)
			int_error("Unlocking the mutex failed");

		if(!SSL_send_buffer(ssl_client, buffer, strlen(buffer)))
		{
			fprintf(stderr, "Sending the user/admin password resetting result flag failed\n");
			goto ERROR;
		}

		goto ERROR;
	}

	// Unlock an e-mail sending
	if(sem_post(&email_sending_lock_mutex) != 0)
		int_error("Unlocking the mutex failed");

	// Send the user/admin password resetting result flag
	write_token_into_buffer("user_or_admin_passwd_resetting_result_flag", "1", true, buffer);
	if(!SSL_send_buffer(ssl_client, buffer, strlen(buffer)))
	{
		fprintf(stderr, "Sending the user/admin password resetting result flag failed\n");
		goto ERROR;
	}

	return true;

ERROR:

	if(result)
	{
		mysql_free_result(result);
		result = NULL;
	}

	disconnect_db(&db_conn);
	return false;
}
static boolean ssl_cert_response(BIO *bio_client, char *username, boolean is_admin_flag, char *key_exchange_passwd)
{
	char          *ssl_cert_data = NULL;
	unsigned long ssl_cert_data_length;
	char          ssl_cert_hash[SHA1_DIGEST_LENGTH + 1];

	MYSQL         *db_conn = NULL;
  	MYSQL_RES     *result  = NULL;
  	MYSQL_ROW     row;
	char          stat[SQL_STATEMENT_LENGTH + 1];
	char	      err_msg[ERR_MSG_LENGTH + 1];
	unsigned long *lengths = NULL;

	ssl_cert_data = (char *)malloc(sizeof(char)*1000*1024);
	if(!ssl_cert_data)
	{
		int_error("Allocating memory for \"ssl_cert_data\" failed");
	}

	// Connect the database
	connect_db(&db_conn, DB_IP, DB_USERNAME, DB_PASSWD, DB_NAME);

	// Query the user's SSL certificate and write it to buffer
	sprintf(stat, "SELECT enc_ssl_cert, enc_ssl_cert_hash FROM %s WHERE username LIKE '%s' "
		"COLLATE latin1_general_cs", (is_admin_flag) ? UA__ADMINS : UA__USERS, username);

	if(mysql_query(db_conn, stat))
  	{
      		sprintf(err_msg, "Error %u: %s\n", mysql_errno(db_conn), mysql_error(db_conn));
      		int_error(err_msg);
  	}

  	result = mysql_store_result(db_conn);
  	row = mysql_fetch_row(result);
	if(!row)
		int_error("Getting an SSL certificate from the database failed");

	lengths = mysql_fetch_lengths(result);
	ssl_cert_data_length = lengths[0];

	memcpy(ssl_cert_data, row[0], ssl_cert_data_length);
	strcpy(ssl_cert_hash, row[1]);

	if(result)
	{
		mysql_free_result(result);
		result = NULL;
	}
	disconnect_db(&db_conn);

	// Write the SSL ceertificate to file and encrypt it with random session password before sending it to the user
	if(!write_bin_file(SSL_CERT_PLAINTEXT_PATH, "wb", ssl_cert_data, ssl_cert_data_length))
	{
		fprintf(stderr, "Writing the SSL certificate hash failed");
		goto ERROR;
	}

	if(!des3_encrypt(SSL_CERT_PLAINTEXT_PATH, SSL_CERT_CIPHERTEXT_PATH, key_exchange_passwd, err_msg))
	{
		fprintf(stderr, "Decrypting the SSL certificate failed\n\"%s\"\n", err_msg);
		goto ERROR;
	}

	unlink(SSL_CERT_PLAINTEXT_PATH);

	// Send the user's SSL certificate
	if(!BIO_send_file(bio_client, SSL_CERT_CIPHERTEXT_PATH))
	{
		fprintf(stderr, "Sending the SSL certificate failed\n");
		goto ERROR;
	}

	unlink(SSL_CERT_CIPHERTEXT_PATH);

	// Write hash value to file and encrypt it with random session password before sending it to the user
	if(!write_bin_file(SSL_CERT_HASH_PLAINTEXT_PATH, "wb", ssl_cert_hash, SHA1_DIGEST_LENGTH))
	{
		fprintf(stderr, "Writing the SSL certificate hash failed");
		goto ERROR;
	}

	if(!des3_encrypt(SSL_CERT_HASH_PLAINTEXT_PATH, SSL_CERT_HASH_CIPHERTEXT_PATH, key_exchange_passwd, err_msg))
	{
		fprintf(stderr, "Decrypting the SSL certificate hash failed\n\"%s\"\n", err_msg);
		goto ERROR;
	}

	unlink(SSL_CERT_HASH_PLAINTEXT_PATH);

	// Send the user's SSL certificate hash
	if(!BIO_send_file(bio_client, SSL_CERT_HASH_CIPHERTEXT_PATH))
	{
		fprintf(stderr, "Sending the SSL certificate hash failed\n");
		goto ERROR;
	}

	unlink(SSL_CERT_HASH_CIPHERTEXT_PATH);

	if(ssl_cert_data)
	{
		free(ssl_cert_data);
		ssl_cert_data = NULL;
	}

	return true;

ERROR:
	unlink(SSL_CERT_PLAINTEXT_PATH);
	unlink(SSL_CERT_CIPHERTEXT_PATH);
	unlink(SSL_CERT_HASH_PLAINTEXT_PATH);
	unlink(SSL_CERT_HASH_CIPHERTEXT_PATH);

	if(ssl_cert_data)
	{
		free(ssl_cert_data);
		ssl_cert_data = NULL;
	}

	return false;
}