/*---[ addrules.c ]---------------------------------------------------
 * Copyright (C) 2000 Tomas Junnonen (majix@sci.fi)
 *
 * 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 2 of the License, or
 * (at your option) any later version.
 *
 * Functions to add custom rules to the dynamic rules page
 *--------------------------------------------------------------------*/

#include "addrules.h"
#include "firestarter.h"
#include "parse.h"

extern gboolean NETFILTER;

static void
write_to_script (gchar *path,
		 gchar *text)
{
	FILE *f = fopen (path, "a");

	if (f) {
		fprintf (f, "%s", text);

		fclose (f);

		parse_allow_and_deny_all ();
		parse_allow_service_machine ();
		parse_allow_service_all ();

		restart_firewall ();
	}
}

static void
add_rule (gchar *ip, gchar *port, gboolean *tcp_active)
{
	gint proto;
	gchar *path;
	gchar *string;

	if (tcp_active)
		proto = 6;
	else
		proto = 17;

	if (GTK_WIDGET (dynclist) == denyallclist) {
		if (NETFILTER)
			string = g_strdup_printf ("$IPT -A INPUT -s %s -d 0/0 -j DROP\n", ip);
		else
			string = g_strdup_printf ("$IPC -A input -s %s -d 0/0 -j DENY\n", ip);
		path = g_strdup (FIRESTARTER_RULES_DIR "/firestarter/deny-all");
	}

	if (GTK_WIDGET (dynclist) == allowallclist) {
		if (NETFILTER)
			string = g_strdup_printf ("$IPT -A INPUT -s %s -d 0/0 -j ACCEPT\n", ip);
		else
			string = g_strdup_printf ("$IPC -A input -s %s -d 0/0 -j ACCEPT\n", ip);
		path = g_strdup (FIRESTARTER_RULES_DIR "/firestarter/allow-all");
	}

	if (GTK_WIDGET (dynclist) == allowsaclist) {
		if (NETFILTER)
			string = g_strdup_printf ("$IPT -A INPUT -p %d -s 0/0 -d $NET --dport %s -j ACCEPT\n", proto, port);
		else
			string = g_strdup_printf ("$IPC -A input -p %d -s 0/0 -d $NET %s -j ACCEPT\n", proto, port);
		path = g_strdup (FIRESTARTER_RULES_DIR "/firestarter/allow-service-all");
	}

	if (GTK_WIDGET (dynclist) == allowsmclist) {
		if (NETFILTER)
			string = g_strdup_printf ("$IPT -A INPUT -p %d -s %s -d $NET --dport %s -j ACCEPT\n", proto, ip, port);
		else
			string = g_strdup_printf ("$IPC -A input -p %d -s %s -d $NET %s -j ACCEPT\n", proto, ip, port);
		path = g_strdup (FIRESTARTER_RULES_DIR "/firestarter/allow-service-machine");
	}

	write_to_script (path, string);
	g_free (path);
	g_free (string);
}

void
create_rule_dialog (void)
{
	GtkWidget *dialog, *label, *entry1, *entry2, *radio1, *radio2, *hbox;
	gint button;
	gchar *text;

	if (dynclist == NULL)
		return;

	dialog = gnome_dialog_new (_("Add new rule"),
			GNOME_STOCK_BUTTON_OK, GNOME_STOCK_BUTTON_CANCEL,
			NULL);

	if ((GTK_WIDGET (dynclist) == allowsaclist) || (GTK_WIDGET (dynclist) == allowsmclist)) {
		hbox = gtk_hbox_new (FALSE, 0);
		gtk_box_pack_start (GTK_BOX (GNOME_DIALOG (dialog)->vbox), hbox,
				    TRUE, TRUE, 0);

		label = gtk_label_new (_("Protocol:"));
		gtk_box_pack_start (GTK_BOX (hbox), label,
				    TRUE, TRUE, 0);

		radio1 = gtk_radio_button_new_with_label (NULL, "TCP");
		gtk_box_pack_start (GTK_BOX (hbox), radio1,
				    TRUE, TRUE, 0);

		radio2 = gtk_radio_button_new_with_label_from_widget (GTK_RADIO_BUTTON (radio1), "UDP");
		gtk_box_pack_start (GTK_BOX (hbox), radio2,
				    TRUE, TRUE, 0);
	}

	if (GTK_WIDGET (dynclist) == denyallclist)
		label = gtk_label_new (_("Enter IP range or hostname to deny all connections from:"));
	if (GTK_WIDGET (dynclist) == allowallclist)
		label = gtk_label_new (_("Enter IP range or hostname to allow all connections from:"));
	if (GTK_WIDGET (dynclist) == allowsaclist)
		label = gtk_label_new (_("Enter the port number of the service to open:"));
	if (GTK_WIDGET (dynclist) == allowsmclist) {
		label = gtk_label_new (_("Enter IP range or hostname to open service to:"));
		gtk_box_pack_start (GTK_BOX (GNOME_DIALOG (dialog)->vbox), label,
				    TRUE, TRUE, 0);
		entry2 = gtk_entry_new ();
		gtk_box_pack_start (GTK_BOX (GNOME_DIALOG (dialog)->vbox), entry2,
				    TRUE, TRUE, 0);

		label = gtk_label_new (_("Enter the port number of the service to open:"));
	}

	gtk_box_pack_start (GTK_BOX (GNOME_DIALOG (dialog)->vbox), label,
			    TRUE, TRUE, 0);

	entry1 = gtk_entry_new ();
	gtk_box_pack_start (GTK_BOX (GNOME_DIALOG (dialog)->vbox), entry1,
			    TRUE, TRUE, 0);

	gtk_widget_grab_focus (entry1);
	gnome_dialog_close_hides (GNOME_DIALOG (dialog), TRUE);
	gnome_dialog_set_default (GNOME_DIALOG (dialog), 0);
	gnome_dialog_editable_enters (GNOME_DIALOG (dialog), GTK_EDITABLE (entry1));

	gtk_widget_show_all (dialog);
	button = gnome_dialog_run_and_close (GNOME_DIALOG (dialog));

	if (button) {
		gtk_widget_destroy (dialog);
		return;
	}

/*	g_print ("%d, %s\n", button,  gtk_entry_get_text (GTK_ENTRY (entry1))); */
	text = gtk_entry_get_text (GTK_ENTRY (entry1));

	if (strlen (text)) {
		if (GTK_WIDGET (dynclist) == denyallclist)
			add_rule (text, NULL, NULL);

		if (GTK_WIDGET (dynclist) == allowallclist)
			add_rule (text, NULL, NULL);

		if (GTK_WIDGET (dynclist) == allowsaclist)
			add_rule (NULL, text, GINT_TO_POINTER (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (radio1))));

		if (GTK_WIDGET (dynclist) == allowsmclist)
			add_rule (gtk_entry_get_text (GTK_ENTRY (entry2)), text,
				GINT_TO_POINTER (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (radio1))));
	}

	gtk_widget_destroy (dialog);
}
