/* GAdmin-OpenVPN - An easy to use GTK+ frontend for the openvpn client.
 * Copyright (C) 2008 - 2010 Magnus Loef <magnus-swe@telia.com> 
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 * See the GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License along
 * with this program; if not, write to the Free Software Foundation, Inc.,
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
 *
*/


#include "../config.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <gtk/gtk.h>
#include "gettext.h"
#include "widgets.h"
#include "make_settings_entries.h"
#include "make_settings_combos.h"
#include "make_settings_buttons.h"
#include "make_settings_spinbuttons.h"
#include "make_settings_progressbars.h"
#include "make_settings_labels.h"
#include "make_settings_hseparators.h"
#include "create_client_settings.h"
#include "allocate.h"
#include "commands.h"
#include "show_info.h"
#include "file_chooser.h"


/* Adds an example mount command to the entry */
void add_mount_command(struct w *widgets)
{
    gchar *info, *utf8;
    info = g_strdup_printf("mkdir -p /media/usb-device ; mount /dev/sdb1 /media/usb-device");
    utf8 = g_locale_to_utf8(info, strlen(info), NULL, NULL, NULL);
    gtk_entry_set_text(GTK_ENTRY(widgets->client_set_entry[5]), utf8);
    if( utf8!=NULL )
      g_free(utf8);

    g_free(info);
}


char * get_import_filename(gchar *path)
{
    long i = 0;
    char *filename = allocate(strlen(path)+3);

    if( path!=NULL )
    {
	for(i=strlen(path)-1; i>0; i--)
	if( path[i]=='/' )
	{
	    snprintf(filename, strlen(path), "%s", &path[i+1]);
	    break;
	}
    }
    return filename;
}

void copy_import_file(struct w *widgets, gchar *path)
{
    gchar *connection_name, *cmd, *info;
    int i = 0;

    connection_name = g_strdup_printf("%s", gtk_entry_get_text(GTK_ENTRY(widgets->client_set_entry[0])));
    for(i=0; connection_name[i]!='\0'; i++)
      if( connection_name[i]==' ' )
        connection_name[i]='-';

    cmd = g_strdup_printf("mkdir -p %s/client/%s/certs", OPENVPN_SYSCONF_DIR, connection_name);
    if( ! run_command(cmd) )
    {
	info = g_strdup_printf(_("Could not create the clients certificate directory.\n"));
        show_info(info);
        g_free(info);
        return;
    }
    g_free(cmd);

    cmd = g_strdup_printf("cp '%s' %s/client/%s/certs", path, OPENVPN_SYSCONF_DIR, connection_name);
    if( ! run_command(cmd) )
    {
	info = g_strdup_printf(_("Error: Copying certificate or key file failed.\n"));
        show_info(info);
        g_free(info);
        return;
    }
    g_free(cmd);
}

int valid_connection_name(struct w *widgets)
{
    G_CONST_RETURN gchar *connection_name;
    gchar *info;

    connection_name = gtk_entry_get_text(GTK_ENTRY(widgets->client_set_entry[0]));
    if( connection_name == NULL || strlen(connection_name) < 3 )
    {
	info = g_strdup_printf(_("You must specify a valid connection name first.\n"));
        show_info(info);
        g_free(info);
	return 0;
    }
    return 1;
}


void import_cacert(struct w *widgets)
{
    char *filename;
    gchar *path = NULL;

    if( ! valid_connection_name(widgets) )
      return;

    path = get_dialog_path_selection("FILE", "/home", "None");
    if( path!=NULL )
    {
	filename = get_import_filename(path);
	gtk_entry_set_text(GTK_ENTRY(widgets->client_set_entry[7]), filename);
	if( filename!=NULL )
	  free(filename);

	/* Copy the file to the correct location */
	copy_import_file(widgets, path);

        g_free(path);
    }
}
void import_cert(struct w *widgets)
{
    char *filename;
    gchar *path = NULL;

    if( ! valid_connection_name(widgets) )
      return;

    path = get_dialog_path_selection("FILE", "/home", "None");
    if( path!=NULL )
    {
	filename = get_import_filename(path);
	gtk_entry_set_text(GTK_ENTRY(widgets->client_set_entry[8]), filename);
	if( filename!=NULL )
	  free(filename);

	/* Copy the file to the correct location */
	copy_import_file(widgets, path);

        g_free(path);
    }
}
void import_key(struct w *widgets)
{
    char *filename;
    gchar *path = NULL;

    if( ! valid_connection_name(widgets) )
      return;

    path = get_dialog_path_selection("FILE", "/home", "None");
    if( path!=NULL )
    {
	filename = get_import_filename(path);
	gtk_entry_set_text(GTK_ENTRY(widgets->client_set_entry[9]), filename);
	if( filename!=NULL )
	  free(filename);

	/* Copy the file to the correct location */
	copy_import_file(widgets, path);

        g_free(path);
    }
}
void import_dhkey(struct w *widgets)
{
    char *filename;
    gchar *path = NULL;

    if( ! valid_connection_name(widgets) )
      return;

    path = get_dialog_path_selection("FILE", "/home", "None");
    if( path!=NULL )
    {
	filename = get_import_filename(path);
	gtk_entry_set_text(GTK_ENTRY(widgets->client_set_entry[10]), filename);
	if( filename!=NULL )
	  free(filename);

	/* Copy the file to the correct location */
	copy_import_file(widgets, path);

        g_free(path);
    }
}
void import_takey(struct w *widgets)
{
    char *filename;
    gchar *path = NULL;

    if( ! valid_connection_name(widgets) )
      return;

    path = get_dialog_path_selection("FILE", "/home", "None");
    if( path!=NULL )
    {
	filename = get_import_filename(path);
	gtk_entry_set_text(GTK_ENTRY(widgets->client_set_entry[11]), filename);
	if( filename!=NULL )
	  free(filename);

	/* Copy the file to the correct location */
	copy_import_file(widgets, path);

        g_free(path);
    }
}




void create_client_settings(struct w *widgets)
{
    GtkTooltips *tooltips;
    gchar *utf8 = NULL;
    gchar *combo_text;

    /* Counters for the widgets and positions in the table */
    int a = 0;
    int b = 1;
    int ent  = 0;
    int spin = 0;
    int comb = 0;

    /* Max lengths and input */
    int entry_size = 100;

    tooltips = gtk_tooltips_new();

    /* Connection name */
    widgets->client_set_entry[ent] = make_long_entry_with_label(GTK_TABLE(widgets->srv_set_table), _(" Connection name: "), 0,1,a,b,entry_size);
    gtk_tooltips_set_tip(tooltips, widgets->client_set_entry[ent], 
    _("A name for this VPN connection"), NULL);
    a++; b++; ent++;

    /* Server address */
    widgets->client_set_entry[ent] = make_long_entry_with_label(GTK_TABLE(widgets->srv_set_table), _(" Server address: "), 0,1,a,b,entry_size);
    gtk_tooltips_set_tip(tooltips, widgets->client_set_entry[ent], 
    _("Remote VPN server address"), NULL);
    a++; b++; ent++;

    /* Server port */
    widgets->client_set_spinbutton[spin] = make_short_spinbutton_with_label(GTK_TABLE(widgets->srv_set_table), _(" Server port: "), 0,1,a,b,50);
    gtk_tooltips_set_tip(tooltips, widgets->client_set_spinbutton[spin], _("Remote VPN server port"), NULL);
    a++; b++; spin++;

    /* Server Protocol UDP/TCP */
    widgets->client_set_combo[comb] = make_short_combo_with_label(GTK_TABLE(widgets->srv_set_table), _(" Server protocol: "), 0,1,a,b,50);
    combo_text = g_strdup_printf(_("TCP"));
    utf8 = g_locale_to_utf8(combo_text, strlen(combo_text), NULL, NULL, NULL);
    gtk_combo_box_append_text(GTK_COMBO_BOX(widgets->client_set_combo[comb]), utf8);
    g_free(combo_text); g_free(utf8);
    combo_text = g_strdup_printf(_("UDP"));
    utf8 = g_locale_to_utf8(combo_text, strlen(combo_text), NULL, NULL, NULL);
    gtk_combo_box_append_text(GTK_COMBO_BOX(widgets->client_set_combo[comb]), utf8);
    g_free(combo_text); g_free(utf8);
    a++; b++; comb++;

    /* The TAP interface to create and use */
    widgets->client_set_combo[comb] = make_short_combo_with_label(GTK_TABLE(widgets->srv_set_table), _(" TAP device: "), 0,1,a,b,50);
    combo_text = g_strdup_printf("Tap0");
    utf8 = g_locale_to_utf8(combo_text, strlen(combo_text), NULL, NULL, NULL);
    gtk_combo_box_append_text(GTK_COMBO_BOX(widgets->client_set_combo[comb]), utf8);
    g_free(combo_text); g_free(utf8);
    combo_text = g_strdup_printf("Tap1");
    utf8 = g_locale_to_utf8(combo_text, strlen(combo_text), NULL, NULL, NULL);
    gtk_combo_box_append_text(GTK_COMBO_BOX(widgets->client_set_combo[comb]), utf8);
    g_free(combo_text); g_free(utf8);
    combo_text = g_strdup_printf("Tap2");
    utf8 = g_locale_to_utf8(combo_text, strlen(combo_text), NULL, NULL, NULL);
    gtk_combo_box_append_text(GTK_COMBO_BOX(widgets->client_set_combo[comb]), utf8);
    g_free(combo_text); g_free(utf8);
    combo_text = g_strdup_printf("Tap3");
    utf8 = g_locale_to_utf8(combo_text, strlen(combo_text), NULL, NULL, NULL);
    gtk_combo_box_append_text(GTK_COMBO_BOX(widgets->client_set_combo[comb]), utf8);
    g_free(combo_text); g_free(utf8);
    a++; b++; comb++;

    /* Username */
    widgets->client_set_entry[ent] = make_long_entry_with_label(GTK_TABLE(widgets->srv_set_table), _(" Username: "), 0,1,a,b,200);
    gtk_tooltips_set_tip(tooltips, widgets->client_set_entry[ent], _("A username for the server if required"), NULL);
    a++; b++; ent++;

    /* Password */
    widgets->client_set_entry[ent] = make_long_entry_with_label(GTK_TABLE(widgets->srv_set_table), _(" Password: "), 0,1,a,b,200);
    gtk_tooltips_set_tip(tooltips, widgets->client_set_entry[ent], _("A password for the server if required"), NULL);
    a++; b++; ent++;

    /* Passfile location */
    widgets->client_set_entry[ent] = make_long_entry_with_label(GTK_TABLE(widgets->srv_set_table), _(" Passfile: "), 0,1,a,b,200);
    gtk_tooltips_set_tip(tooltips, widgets->client_set_entry[ent],
    _("Location of the passfile.\nIE: /etc/gadmin-openvpn/client/connection-name/passfile\nor /media/usb-device/passfile3"), NULL);
    a++; b++; ent++;

    /* Mount button and entry */
    GtkWidget *mount_button;
    widgets->client_set_entry[ent] = gtk_entry_new();
    mount_button = make_button_with_entry(GTK_TABLE(widgets->srv_set_table),
                            	             widgets->client_set_entry[ent],
                    	                                      "gtk-refresh",
            	        		                           "Mount:",
	        		          _("Add an example mount command"),
	        		        		         0,1,a,b,-1);
    a++; b++; ent++;
    g_signal_connect_swapped(G_OBJECT(mount_button), "clicked",
    	                   G_CALLBACK(add_mount_command), widgets);

    /* Encryption type: BlowFish, AES or Triple-DES */
    widgets->client_set_combo[comb] = make_short_combo_with_label(GTK_TABLE(widgets->srv_set_table), _(" Encryption type: "), 0,1,a,b,50);
    combo_text = g_strdup_printf(_("BlowFish"));
    utf8 = g_locale_to_utf8(combo_text, strlen(combo_text), NULL, NULL, NULL);
    gtk_combo_box_append_text(GTK_COMBO_BOX(widgets->client_set_combo[comb]), utf8);
    g_free(combo_text); g_free(utf8);
    combo_text = g_strdup_printf(_("AES-128"));
    utf8 = g_locale_to_utf8(combo_text, strlen(combo_text), NULL, NULL, NULL);
    gtk_combo_box_append_text(GTK_COMBO_BOX(widgets->client_set_combo[comb]), utf8);
    g_free(combo_text); g_free(utf8);
    combo_text = g_strdup_printf(_("AES-256"));
    utf8 = g_locale_to_utf8(combo_text, strlen(combo_text), NULL, NULL, NULL);
    gtk_combo_box_append_text(GTK_COMBO_BOX(widgets->client_set_combo[comb]), utf8);
    g_free(combo_text); g_free(utf8);
    combo_text = g_strdup_printf(_("Triple-DES"));
    utf8 = g_locale_to_utf8(combo_text, strlen(combo_text), NULL, NULL, NULL);
    gtk_combo_box_append_text(GTK_COMBO_BOX(widgets->client_set_combo[comb]), utf8);
    g_free(combo_text); g_free(utf8);
    a++; b++; comb++;

    /* Use compression */
    widgets->client_set_combo[comb] = make_short_combo_with_label(GTK_TABLE(widgets->srv_set_table), _(" Use compression: "), 0,1,a,b,50);
    combo_text = g_strdup_printf(_("No"));
    utf8 = g_locale_to_utf8(combo_text, strlen(combo_text), NULL, NULL, NULL);
    gtk_combo_box_append_text(GTK_COMBO_BOX(widgets->client_set_combo[comb]), utf8);
    g_free(combo_text); g_free(utf8);
    combo_text = g_strdup_printf(_("Yes"));
    utf8 = g_locale_to_utf8(combo_text, strlen(combo_text), NULL, NULL, NULL);
    gtk_combo_box_append_text(GTK_COMBO_BOX(widgets->client_set_combo[comb]), utf8);
    g_free(combo_text); g_free(utf8);
    a++; b++; comb++;

    /* Share connection */
    widgets->client_set_combo[comb] = make_short_combo_with_label(GTK_TABLE(widgets->srv_set_table), _(" Share connection: "), 0,1,a,b,50);
    combo_text = g_strdup_printf(_("No"));
    utf8 = g_locale_to_utf8(combo_text, strlen(combo_text), NULL, NULL, NULL);
    gtk_combo_box_append_text(GTK_COMBO_BOX(widgets->client_set_combo[comb]), utf8);
    g_free(combo_text); g_free(utf8);
    combo_text = g_strdup_printf(_("Yes"));
    utf8 = g_locale_to_utf8(combo_text, strlen(combo_text), NULL, NULL, NULL);
    gtk_combo_box_append_text(GTK_COMBO_BOX(widgets->client_set_combo[comb]), utf8);
    g_free(combo_text); g_free(utf8);
    a++; b++; comb++;

    /* Using Firestarter */
    widgets->client_set_combo[comb] = make_short_combo_with_label(GTK_TABLE(widgets->srv_set_table), _(" Using Firestarter: "), 0,1,a,b,50);
    combo_text = g_strdup_printf(_("No"));
    utf8 = g_locale_to_utf8(combo_text, strlen(combo_text), NULL, NULL, NULL);
    gtk_combo_box_append_text(GTK_COMBO_BOX(widgets->client_set_combo[comb]), utf8);
    g_free(combo_text); g_free(utf8);
    combo_text = g_strdup_printf(_("Yes"));
    utf8 = g_locale_to_utf8(combo_text, strlen(combo_text), NULL, NULL, NULL);
    gtk_combo_box_append_text(GTK_COMBO_BOX(widgets->client_set_combo[comb]), utf8);
    g_free(combo_text); g_free(utf8);
    a++; b++; comb++;

    /* Start at boot */
    widgets->client_set_combo[comb] = make_short_combo_with_label(GTK_TABLE(widgets->srv_set_table), _(" Start at boot: "), 0,1,a,b,50);
    combo_text = g_strdup_printf(_("No"));
    utf8 = g_locale_to_utf8(combo_text, strlen(combo_text), NULL, NULL, NULL);
    gtk_combo_box_append_text(GTK_COMBO_BOX(widgets->client_set_combo[comb]), utf8);
    g_free(combo_text); g_free(utf8);
    combo_text = g_strdup_printf(_("Yes"));
    utf8 = g_locale_to_utf8(combo_text, strlen(combo_text), NULL, NULL, NULL);
    gtk_combo_box_append_text(GTK_COMBO_BOX(widgets->client_set_combo[comb]), utf8);
    g_free(combo_text); g_free(utf8);
    a++; b++; comb++;


    /* LAN interface name */
/*
    widgets->server_set_entry[ent] = make_long_entry_with_label(GTK_TABLE(widgets->srv_set_table), _(" LAN interface name: "), 0,1,a,b,entry_size);
    gtk_tooltips_set_tip(tooltips, widgets->server_set_entry[ent], 
    _("The name of the LAN network interface, IE: eth1"), NULL);
    a++; b++; ent++;
*/
    /* LAN interface address */
/*
    widgets->server_set_entry[ent] = make_long_entry_with_label(GTK_TABLE(widgets->srv_set_table), _(" LAN interface address: "), 0,1,a,b,entry_size);
    gtk_tooltips_set_tip(tooltips, widgets->server_set_entry[ent], 
    _("IE: 192.168.10.100\nYour LAN should not have the same network address as connecting clients commonly have, IE: 192.168.0 or 10.0.0. Also change this setting in your DHCP server and firewall."), NULL);
    a++; b++; ent++;
*/
    /* LAN Subnet mask */
/*
    widgets->server_set_entry[ent] = make_long_entry_with_label(GTK_TABLE(widgets->srv_set_table), _(" LAN subnet mask: "), 0,1,a,b,entry_size);
    gtk_tooltips_set_tip(tooltips, widgets->server_set_entry[ent], 
    _("IE: 255.255.255.0"), NULL);
    a++; b++; ent++;
*/
    /* LAN Broadcast address */
/*
    widgets->server_set_entry[ent] = make_long_entry_with_label(GTK_TABLE(widgets->srv_set_table), _(" LAN broadcast address: "), 0,1,a,b,entry_size);
    gtk_tooltips_set_tip(tooltips, widgets->server_set_entry[ent], 
    _("IE: 192.168.10.255"), NULL);
    a++; b++; ent++;
*/



    /* Log level (verb 3) */
    widgets->client_set_spinbutton[spin] = make_short_spinbutton_with_label(GTK_TABLE(widgets->srv_set_table),_(" Log level: "), 0,1,a,b,50);
    gtk_tooltips_set_tip(tooltips, widgets->client_set_spinbutton[spin], _("Log verbosity level."), NULL);
    a++; b++; spin++;

    /* HTTP Proxy server address */
    widgets->client_set_entry[ent] = make_long_entry_with_label(GTK_TABLE(widgets->srv_set_table), _(" Proxy server: "), 0,1,a,b,entry_size);
    gtk_tooltips_set_tip(tooltips, widgets->client_set_entry[ent], 
    _("Local HTTP Proxy server address if any"), NULL);
    a++; b++; ent++;

    /* HTTP proxy server port */
    widgets->client_set_spinbutton[spin] = make_short_spinbutton_with_label(GTK_TABLE(widgets->srv_set_table),_(" Proxy port: "), 0,1,a,b,50);
    gtk_tooltips_set_tip(tooltips, widgets->client_set_spinbutton[spin], _("Local HTTP proxy server port if any"), NULL);
    a++; b++; spin++;


    /* CA Cert button and entry */
    GtkWidget *cacert_button;
    widgets->client_set_entry[ent] = gtk_entry_new();
    cacert_button = make_button_with_entry(GTK_TABLE(widgets->srv_set_table),
                            	             widgets->client_set_entry[ent],
                    	                                      "gtk-refresh",
            	        		                           "CA cert:",
						_("Import a CA certificate"),
	        		        		         0,1,a,b,-1);
    a++; b++; ent++;
    g_signal_connect_swapped(G_OBJECT(cacert_button), "clicked",
				G_CALLBACK(import_cacert), widgets);

    /* Cert */
    GtkWidget *cert_button;
    widgets->client_set_entry[ent] = gtk_entry_new();
    cert_button = make_button_with_entry(GTK_TABLE(widgets->srv_set_table),
                            	             widgets->client_set_entry[ent],
                    	                                      "gtk-refresh",
            	        		                           "Cert:",
						_("Import a certificate"),
	        		        		         0,1,a,b,-1);
    a++; b++; ent++;
    g_signal_connect_swapped(G_OBJECT(cert_button), "clicked",
				G_CALLBACK(import_cert), widgets);

    /* Key */
    GtkWidget *key_button;
    widgets->client_set_entry[ent] = gtk_entry_new();
    key_button = make_button_with_entry(GTK_TABLE(widgets->srv_set_table),
                            	             widgets->client_set_entry[ent],
                    	                                      "gtk-refresh",
            	        		                           "Key:",
						_("Import a key"),
	        		        		         0,1,a,b,-1);
    a++; b++; ent++;
    g_signal_connect_swapped(G_OBJECT(key_button), "clicked",
				G_CALLBACK(import_key), widgets);

    /* DH key */
    GtkWidget *dhkey_button;
    widgets->client_set_entry[ent] = gtk_entry_new();
    dhkey_button = make_button_with_entry(GTK_TABLE(widgets->srv_set_table),
                            	             widgets->client_set_entry[ent],
                    	                                      "gtk-refresh",
            	        		                           "DH key:",
						_("Import a Diffie Hellman key"),
	        		        		         0,1,a,b,-1);
    a++; b++; ent++;
    g_signal_connect_swapped(G_OBJECT(dhkey_button), "clicked",
				G_CALLBACK(import_dhkey), widgets);

    /* TA key */
    GtkWidget *takey_button;
    widgets->client_set_entry[ent] = gtk_entry_new();
    takey_button = make_button_with_entry(GTK_TABLE(widgets->srv_set_table),
                            	             widgets->client_set_entry[ent],
                    	                                      "gtk-refresh",
            	        		                           "TA key:",
						_("Import a TLS-Auth key"),
	        		        		         0,1,a,b,-1);
    a++; b++; ent++;
    g_signal_connect_swapped(G_OBJECT(takey_button), "clicked",
				G_CALLBACK(import_takey), widgets);


    gtk_widget_show_all(widgets->main_window);
}
