/* GADMIN-PROFTPD - An easy to use GTK+ frontend for the ProFTPD standalone server.
 * Copyright (C) 2001 - 2008 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 <gtk/gtk.h>
#include "gettext.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "allocate.h"
#include "widgets.h"
#include "functions.h"
#include "standard_conf.h"
#include "populate_gadmin_proftpd.h"
#include "show_info.h"
#include "commented.h"

/* Temporary for option deprecations */
extern char global_version[1024];


/* Temporary configuration alteration. Leave it until 2012. funfra, mighty darth-doom-cow ;) */
void new_tls_module_conf()
{
    FILE *fp;
    long file_size = 0;
    char *line, *new_conf;
    gchar *info, *module_conf;

    if((fp=fopen(PROFTPD_CONF, "r"))==NULL)
    {
	info = g_strdup_printf("Error adding new TLS module configuration.\n");
	show_info(info);
	g_free(info);
        return;
    }

    module_conf = g_strconcat("\n",
    "<IfModule mod_tls.c>\n",
    "TLSEngine off\n",
    "TLSRequired auth+data\n",
    "TLSVerifyClient off\n",
    "TLSProtocol SSLv23 , TLSv1\n",
    "TLSLog ", GP_VARDIR, "/log/proftpd_tls.log\n",
    "TLSRSACertificateFile ", GP_APPCONFDIR, "/certs/cert.pem\n",
    "TLSRSACertificateKeyFile ", GP_APPCONFDIR, "/certs/key.pem\n",
    "TLSCACertificateFile ", GP_APPCONFDIR, "/certs/cacert.pem\n",
    "TLSRenegotiate required off\n",
    "</IfModule>\n",
    NULL);

    fseek(fp, 0, SEEK_END);
    file_size = ftell(fp);
    rewind(fp);

    line = allocate(file_size+1);
    new_conf = allocate(file_size+16384);

    if( file_size > 1 )
    while(fgets(line, file_size, fp)!=NULL)
    {
	if( commented(line) )
	  continue;

	if( cmplowercase(line, "ifmodule")
	&&  cmplowercase(line, "mod_tls.c")
	&&  strstr(line, "<") && strstr(line, ">") )
	{
	    while(fgets(line, file_size, fp)!=NULL)
	    if( cmplowercase(line, "ifmodule")
	    &&  strstr(line, "<") && strstr(line, ">") )
	    {
		strcat(new_conf, module_conf);
	        break;
	    }
	}
	else
	  strcat(new_conf, line);
    }
    g_free(module_conf);
    free(line);
    fclose(fp);

    /* Write the new configuration */
    if((fp=fopen(PROFTPD_CONF, "w+"))==NULL)
    {
	info = g_strdup_printf("Error writing new TLS module configuration.\n");
	show_info(info);
	g_free(info);

	g_free(new_conf);
        return;
    }
    fputs(new_conf, fp);
    fclose(fp);
    free(new_conf);

    info = g_strconcat("Successfully added new TLS module configuration.\n\n",
    "GAdmin-PRoFTPd now supports explicit/total FTP encryption.\n\n",

    "New signed certificates needs to be generated.\n",
    "Press the generate button and then turn on secure communications\n\n",

    "Clients like FileZilla that supports explicit FTP encryption can be used.\n",
    NULL);
    show_info(info);
    g_free(info);

    /* "For to see is more important then to be, fine'" as KellyB so nicely puts it :P */
}



int conf_ok(gchar *file_path)
{
    FILE *fp;
    long conf_size;
    char *line;
    int retval = 0;
    int good_conf = 0;

    if((fp=fopen(file_path, "r"))==NULL)
      return retval;

    fseek(fp, 0, SEEK_END);
    conf_size = ftell(fp);
    rewind(fp);

    line = allocate(conf_size+1);

    if( conf_size > 1 )      
    while(fgets(line, conf_size, fp)!=NULL)
    {
	if( commented(line) )
	  continue;

	/* Only check the standard server */
	if( strstr(line, "<Anonymous") )
	  break;
	if( strstr(line, "<Virtual") )
	  break;
	if( strstr(line, "<IfModule") )
	  break;

	/* Very good for security so it must exist */
	if( strstr(line, "<Limit LOGIN>") )
	  good_conf++;

	/* Refuse to use inetd */
	if( strstr(line, "ServerType standalone") )
	  good_conf++;

	if( strstr(line, "TransferRate RETR") )
	  good_conf++;

	if( strstr(line, "TransferRate STOR") )
	  good_conf++;

	if( strstr(line, "TransferRate STOU") )
	  good_conf++;

	if( strstr(line, "TransferRate APPE") )
	  good_conf++;

	if( strstr(line, "PassivePorts") )
	  good_conf++;

	if( strstr(line, "DefaultTransferMode") )
	  good_conf++;
    }
    fclose(fp);
    free(line);

    if( good_conf == 7 )
      retval = 1;

    return retval;
}


void add_standard_conf(struct w *widgets)
{
    /* Adds the default configuration */
    FILE *fp;
    gchar *info, *config;

    if((fp=fopen(PROFTPD_CONF, "w+"))==NULL)
    {
	info = g_strdup_printf(_("Cant write a new proftpd.conf here:\n%s\n"), PROFTPD_CONF);
	show_info(info);
	g_free(info);
	return;
    }

    /* Note: inetd functions would limit the servers usability */

    config = g_strconcat(
    "ServerType standalone\n",
    "DefaultServer on\n",
    "Umask 022\n",
    "ServerName \"0.0.0.0\"\n",
    "ServerIdent on \"My FTP Server\"\n",
    "ServerAdmin email@example.org\n",
    "IdentLookups off\n",
    "UseReverseDNS off\n",
    "Port 21\n",
    "PassivePorts 49152 65534\n",
    "#MasqueradeAddress None\n",
    "TimesGMT off\n",
    "MaxInstances 30\n",
    "MaxLoginAttempts 3\n",
    "TimeoutLogin 300\n",
    "TimeoutNoTransfer 120\n",
    "TimeoutIdle 120\n",
    "DisplayLogin ", WELCOME_MESSAGE, "\n",

    "DisplayChdir .message\n"

    "User ", SERVER_USER, "\n",
    "Group ", SERVER_GROUP, "\n",
    "DirFakeUser off ", SERVER_USER, "\n",
    "DirFakeGroup off ", SERVER_GROUP, "\n",
    "DefaultTransferMode binary\n",
    "AllowForeignAddress off\n",
    "AllowRetrieveRestart on\n",
    "AllowStoreRestart on\n",
    "DeleteAbortedStores off\n",
    "TransferRate RETR 220\n",
    "TransferRate STOR 250\n",
    "TransferRate STOU 250\n",
    "TransferRate APPE 250\n",
    "SystemLog ", GP_VARDIR, "/log/secure\n",
    "RequireValidShell off\n",
    "<IfModule mod_tls.c>\n",
    "TLSEngine off\n",
    "TLSRequired off\n",
    "TLSVerifyClient off\n",
    "TLSProtocol SSLv23 , TLSv1\n",
    "TLSLog ", GP_VARDIR, "/log/proftpd_tls.log\n",
    "TLSRSACertificateFile ", GP_APPCONFDIR, "/certs/cert.pem\n",
    "TLSRSACertificateKeyFile ", GP_APPCONFDIR, "/certs/key.pem\n",
    "TLSCACertificateFile ", GP_APPCONFDIR, "/certs/cacert.pem\n",
    "TLSRenegotiate required off\n",
    "</IfModule>\n\n",

    "<IfModule mod_ratio.c>\n",
    "Ratios off\n",
    "SaveRatios off\n",
    "RatioFile \"/restricted/proftpd_ratios\"\n",
    "RatioTempFile \"/restricted/proftpd_ratios_temp\"\n",
    "CwdRatioMsg \"Please upload first!\"\n",
    "FileRatioErrMsg \"FileRatio limit exceeded, upload something first...\"\n",
    "ByteRatioErrMsg \"ByteRatio limit exceeded, upload something first...\"\n",
    "LeechRatioMsg \"Your ratio is unlimited.\"\n",
    "</IfModule>\n\n",

    "<Limit LOGIN>\n",
    "  DenyALL\n",
    "</Limit>\n\n",
    NULL);

    fputs(config, fp);
    fclose(fp);
    g_free(config);

    if( GTK_IS_WINDOW(widgets->default_conf_question_window) )
      gtk_widget_destroy(widgets->default_conf_question_window);

    populate_gadmin_proftpd(widgets);
}


void dont_add_standard_conf(struct w *widgets)
{
    if( GTK_IS_WINDOW(widgets->default_conf_question_window) )
      gtk_widget_destroy(widgets->default_conf_question_window);

    populate_gadmin_proftpd(widgets);
}


void create_standard_conf_question(struct w *widgets)
{
  GtkWidget *vbox18, *label182;
  GtkWidget *scrolledwindow18;
  GtkWidget *default_question_textview;
  GtkWidget *hbuttonbox11;
  GtkWidget *yes_default_question_button;
  GtkWidget *alignment44, *hbox98;
  GtkWidget *image44, *label184;
  GtkWidget *no_default_question_button;
  GtkWidget *alignment45, *hbox99;
  GtkWidget *image45, *label185;

  widgets->default_conf_question_window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
  gtk_widget_set_size_request(widgets->default_conf_question_window, 370, 340);
  gtk_window_set_title(GTK_WINDOW(widgets->default_conf_question_window), _("GADMIN-PROFTPD Question"));
  gtk_window_set_position(GTK_WINDOW(widgets->default_conf_question_window), GTK_WIN_POS_CENTER);

  vbox18 = gtk_vbox_new(FALSE, 0);
  gtk_container_add(GTK_CONTAINER(widgets->default_conf_question_window), vbox18);

  label182 = gtk_label_new ("");
  gtk_box_pack_start(GTK_BOX(vbox18), label182, FALSE, FALSE, 0);
  gtk_widget_set_size_request(label182, -1, 20);
  gtk_label_set_justify(GTK_LABEL(label182), GTK_JUSTIFY_LEFT);

  scrolledwindow18 = gtk_scrolled_window_new(NULL, NULL);
  gtk_box_pack_start(GTK_BOX(vbox18), scrolledwindow18, TRUE, TRUE, 0);
  gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrolledwindow18), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);

  default_question_textview = gtk_text_view_new();
  gtk_container_add(GTK_CONTAINER(scrolledwindow18), default_question_textview);
  gtk_widget_set_size_request(default_question_textview, 156, 260);
  gtk_text_view_set_editable(GTK_TEXT_VIEW(default_question_textview), FALSE);
  gtk_text_view_set_cursor_visible(GTK_TEXT_VIEW(default_question_textview), FALSE);
  gtk_text_view_set_pixels_above_lines(GTK_TEXT_VIEW(default_question_textview), 3);
  gtk_text_view_set_left_margin(GTK_TEXT_VIEW(default_question_textview), 30);
  gtk_text_buffer_set_text(gtk_text_view_get_buffer(GTK_TEXT_VIEW (default_question_textview)),
  _("GADMIN-PROFTPD could not find proftpd.conf or you are using\nthe basic configuration that doesnt have all features\nthat gadmin-proftpd requires.\n\nIf you use proftpd's default configuration and dont\nwant to see this question again then delete the line:\n\"# Port 21 is the standard ftp port\"\nin the configuration tab.\nDo you want to overwrite proftpd.conf with GADMIN-PROFTPD's\ndefault configuration ?\n\n              (If you dont know then press yes)\n"), -1);

  hbuttonbox11 = gtk_hbutton_box_new();
  gtk_box_pack_start(GTK_BOX(vbox18), hbuttonbox11, FALSE, FALSE, 0);
  gtk_widget_set_size_request(hbuttonbox11, -1, 40);
  gtk_button_box_set_layout(GTK_BUTTON_BOX(hbuttonbox11), GTK_BUTTONBOX_SPREAD);

  yes_default_question_button = gtk_button_new();
  gtk_container_add(GTK_CONTAINER(hbuttonbox11), yes_default_question_button);
  GTK_WIDGET_SET_FLAGS(yes_default_question_button, GTK_CAN_DEFAULT);

  alignment44 = gtk_alignment_new(0.5, 0.5, 0, 0);
  gtk_container_add(GTK_CONTAINER(yes_default_question_button), alignment44);

  hbox98 = gtk_hbox_new(FALSE, 2);
  gtk_container_add(GTK_CONTAINER(alignment44), hbox98);

  image44 = gtk_image_new_from_stock("gtk-yes", GTK_ICON_SIZE_BUTTON);
  gtk_box_pack_start(GTK_BOX(hbox98), image44, FALSE, FALSE, 0);

  label184 = gtk_label_new_with_mnemonic(_("Yes"));
  gtk_box_pack_start(GTK_BOX(hbox98), label184, FALSE, FALSE, 0);
  gtk_label_set_justify(GTK_LABEL(label184), GTK_JUSTIFY_LEFT);

  no_default_question_button = gtk_button_new();
  gtk_container_add(GTK_CONTAINER(hbuttonbox11), no_default_question_button);
  GTK_WIDGET_SET_FLAGS(no_default_question_button, GTK_CAN_DEFAULT);

  alignment45 = gtk_alignment_new(0.5, 0.5, 0, 0);
  gtk_container_add(GTK_CONTAINER(no_default_question_button), alignment45);

  hbox99 = gtk_hbox_new(FALSE, 2);
  gtk_container_add(GTK_CONTAINER(alignment45), hbox99);

  image45 = gtk_image_new_from_stock("gtk-no", GTK_ICON_SIZE_BUTTON);
  gtk_box_pack_start(GTK_BOX(hbox99), image45, FALSE, FALSE, 0);

  label185 = gtk_label_new_with_mnemonic(_("No"));
  gtk_box_pack_start(GTK_BOX(hbox99), label185, FALSE, FALSE, 0);
  gtk_label_set_justify(GTK_LABEL(label185), GTK_JUSTIFY_LEFT);


  g_signal_connect_swapped(G_OBJECT(yes_default_question_button), "clicked",
                           G_CALLBACK(add_standard_conf), widgets);

  g_signal_connect_swapped(G_OBJECT(no_default_question_button), "clicked",
                           G_CALLBACK(dont_add_standard_conf), widgets);

  gtk_widget_show_all(widgets->default_conf_question_window);
}
