

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <mysql.h>
#include "openvpn-plugin.h"


#define def_host_name  "localhost"
#define def_user_name  "root"
#define def_password   "XXXXXXXXXX"
#define def_db_name    "openvpn"

MYSQL  *conn;
MYSQL_RES *res_set;


/*
 * Our context, where we keep our state.
 */
struct plugin_context {
  const char *username;
  const char *password;
};

/*
 * Given an environmental variable name, search
 * the envp array for its value, returning it
 * if found or NULL otherwise.
 */
static const char *
get_env (const char *name, const char *envp[])
{
  if (envp)
    {
      int i;
      const int namelen = strlen (name);
      for (i = 0; envp[i]; ++i)
	{
	  if (!strncmp (envp[i], name, namelen))
	    {
	      const char *cp = envp[i] + namelen;
	      if (*cp == '=')
		return cp + 1;
	    }
	}
    }
  return NULL;
}

OPENVPN_EXPORT openvpn_plugin_handle_t
openvpn_plugin_open_v1 (unsigned int *type_mask, const char *argv[], const char *envp[])
{
 struct plugin_context *context;

  
  /// * Allocate our context
   
 context = (struct plugin_context *) calloc (1, sizeof (struct plugin_context));
  // * Set the username/password we will require.
 // context->username = "";
 // context->password = "";

  // * We are only interested in intercepting the
  // * --auth-user-pass-verify callback.
   
  *type_mask = OPENVPN_PLUGIN_MASK (OPENVPN_PLUGIN_AUTH_USER_PASS_VERIFY);

  return (openvpn_plugin_handle_t) context;
}


OPENVPN_EXPORT int
openvpn_plugin_func_v1 (openvpn_plugin_handle_t handle, const int type, const char *argv[], const char *envp[])
{
 // struct plugin_context *context = (struct plugin_context *) handle;

  /* get username/password from envp string array */
  const char *username = get_env ("username", envp);
  const char *password = get_env ("password", envp);





  
 char *query = NULL; 
   MYSQL_ROW row;
   unsigned int num_fields;
   
   //Connessione al database
   conn = mysql_init(NULL);
     if(mysql_real_connect (conn, def_host_name, def_user_name, def_password, def_db_name, 0, NULL, 0) == 0){
	       printf("Error %u (%s)\n",mysql_errno (conn), mysql_error (conn));
      }
   
 char *fmt = "SELECT user FROM utenti WHERE pass=PASSWORD('%s') AND user='%s'";
 size_t lenq = strlen(username) + strlen(password) + strlen(fmt); 
 query = alloca(lenq);
 snprintf(query, lenq,"SELECT user FROM utenti WHERE pass=PASSWORD('%s') AND user='%s'", password, username);
    
 if (mysql_query (conn, query) == 0){
  if((res_set = mysql_store_result (conn))){
   if (res_set != NULL){
    if((num_fields = mysql_num_fields(res_set))){
     if((row = mysql_fetch_row(res_set))){
      if(strcmp(username,row[0]) ==0){
              return OPENVPN_PLUGIN_FUNC_SUCCESS;
      }  
     }else{ //DATI NON VALIDI
	  return OPENVPN_PLUGIN_FUNC_ERROR;
     }
    }else{ printf("\n Error"); }
   }else{ printf("\n Error"); }
  }else{ printf("\n Error"); }
 }else{ printf("\n Error");}

 mysql_close (conn);
	                                                     

  /*
  
  if (username && !strcmp (username, "zap") && password && !strcmp (password, "z")){
    return OPENVPN_PLUGIN_FUNC_SUCCESS;
  }else{
    return OPENVPN_PLUGIN_FUNC_ERROR;
  }
*/


  return OPENVPN_PLUGIN_FUNC_ERROR;
}

OPENVPN_EXPORT void
openvpn_plugin_close_v1 (openvpn_plugin_handle_t handle)
{
  struct plugin_context *context = (struct plugin_context *) handle;
  free (context);
}
