/**
 * File:	include/kerberos-client/dialogs.ycp
 * Package:	Configuration of kerberos-client
 * Summary:	Dialogs definitions
 * Authors:	Jiri Suchomel <jsuchome@suse.cz>
 *
 * $Id: dialogs.ycp 20772 2005-01-17 09:34:29Z jsuchome $
 */

{

textdomain "kerberos";

import "Address";
import "IP";
import "Kerberos";
import "Label";
import "Mode";
import "Package";
import "Popup";
import "Report";
import "Stage";
import "Wizard";

/**
 * The dialog that appears when the [Abort] button is pressed.
 * @return `abort if user really wants to abort, `back otherwise
 */
define symbol ReallyAbort () {

    boolean ret = true;
    if (!Stage::cont () || contains (WFM::Args (), "from_users"))
    {
	ret = Popup::ReallyAbort (Kerberos::Modified());;
    }
    else
    {
	ret = Popup::ConfirmAbort (`incomplete);
    }

    if ( ret )	return `abort;
    else	return `back;
}

/**
 * Read settings dialog
 * @return `abort if aborted and `next otherwise
 */
define symbol ReadDialog() ``{
    boolean ret = Kerberos::Read();
    return ret ? `next : `abort;
}

/**
 * Write settings dialog
 * @return `abort if aborted and `next otherwise
 */
define symbol WriteDialog() ``{
    // help text
    Wizard::RestoreHelp(_("Writing Kerberos Client Settings"));
    boolean ret = Kerberos::Write();
    return ret ? `next : `abort;
}

/**
 * Dialog for configuring Kerberos client (values in /etc/krb5.conf)
 * @return dialog result
 */
define symbol ConfigureDialog() {

    // help text 1/5
    string help_text = _("<p>
<b>Authentication with Kerberos</b><br>
You can update your PAM settings to enable Kerberos authentication for your users.
</p>
") +
    // help text 2/5
    _("<p>
<b>Basic Client Settings</b><br>
Enter your <b>domain</b>, <b>default realm</b>, and the <b>host name</b> or <b>address</b> of your Key Distribution Center (KDC).</p>
") +

    // help text 3/5
    _("<p>
It is common practice to use the domain name in uppercase as your default realm name. You can select freely, however.</p>
") +

    // help text 5/5
    _("<p>To configure more settings, click <b>Advanced Settings</b>.</p>");

    help_text = help_text +
    // help text 4/5
    _("<p>If you are using Kerberos authentication together with the AFS file
system, check <b>Kerberos Support for AFS</b>. Enter an IP
address for the <b>AFS Server</b>. As the name of <b>AFS Cell</b>, the DNS
domain name is usually used.</p>
");

    string default_realm = Kerberos::default_realm;
    string kdc = Kerberos::kdc;
    string default_domain = Kerberos::default_domain;

    string cell		= Kerberos::afs_cell;
    string afs_serverip	= Kerberos::afs_serverip;
    boolean use_afs	= Kerberos::use_afs;
    boolean use_pam_krb = Kerberos::use_pam_krb;
    boolean afs_available = true;

    list<string> packages = Kerberos::packages;

    term con = `HBox (`HSpacing (3), `VBox (
        `VSpacing (0.5),
        `RadioButtonGroup(`id(`rd),
	    `Left(`HVSquash(`VBox (
		// radio button label
                `Left (`RadioButton(`id(`pamno), `opt (`notify), _("Do No&t Use Kerberos"), !use_pam_krb)),
		// radio button label
                `Left(`RadioButton(`id(`pamyes), `opt (`notify), _("&Use Kerberos"), use_pam_krb)))))
	),
        `VSpacing (),
	// frame label
	`Frame (_("Basic Kerberos Settings"), `HBox(`HSpacing (0.5), `VBox(
	    `VSpacing (0.5),
	    `HBox(
		// textentry label
		`TextEntry (`id (`domain), _("Default &Domain"),default_domain),
		// textentry label
		`TextEntry (`id (`realm), _("Default Real&m"), default_realm)
	    ),
	    // textentry label
	    `TextEntry (`id (`kdc), _("&KDC Server Address"), kdc),
            // infield label
	    `VSpacing (0.5)), `HSpacing (0.5)
	)),
        `VSpacing (0.2),
	afs_available ?
	// frame label
	`Frame (_("AFS Settings"), `HBox(`HSpacing (0.5), `VBox(
	    `VSpacing (0.5),
	    `Left(`CheckBox (`id(`afs),`opt(`notify),
		// chekbox label
		_("Kerberos Support for &AFS"), use_afs)),
	    `VSpacing (0.5),
	    `HBox (
		// textentry label
		`TextEntry (`id(`cell), _("AFS &Cell Name"), cell),
		// textentry label
		`TextEntry (`id(`afs_serverip), _("&IP Address of AFS Server"),
		    afs_serverip)
	    ),
	    `VSpacing (0.5)), `HSpacing (0.5)
	))
	: `Empty (),
        `VSpacing (),
	`Right(`PushButton (`id(`advanced), _("Ad&vanced Settings..."))),
        `VSpacing (0.2)
    ), `HSpacing(3));

    Wizard::SetContentsButtons (
        // dialog title
        _("Kerberos Client Configuration"), con, help_text,
        Label::BackButton (), Label::FinishButton ());
    Wizard::RestoreAbortButton ();

    if (afs_available)
    {
	UI::ChangeWidget (`id (`cell), `Enabled, use_afs);
	UI::ChangeWidget (`id (`afs_serverip), `Enabled, use_afs);
    }

    foreach (symbol widget, [`realm, `domain, `kdc, `afs, `advanced], ``{
	UI::ChangeWidget (`id (widget), `Enabled, use_pam_krb);
    });

    symbol result = nil;
    do
    {
        result	= (symbol) UI::UserInput ();
	use_afs = (boolean)UI::QueryWidget (`id(`afs), `Value) && afs_available;

	if (result == `afs) {
	    UI::ChangeWidget (`id (`cell), `Enabled, use_afs);
	    UI::ChangeWidget (`id (`afs_serverip), `Enabled, use_afs);
	}

        if (result == `pamyes || result == `pamno)
	{
            use_pam_krb = (result == `pamyes);
	    foreach (symbol widget, [`realm, `domain, `kdc, `advanced],``{
		UI::ChangeWidget (`id (widget), `Enabled, use_pam_krb);
	    });
	    UI::ChangeWidget (`id (`afs),`Enabled,use_pam_krb && afs_available);
	    if (result == `pamno)
	    {
		UI::ChangeWidget (`id (`cell), `Enabled, false);
		UI::ChangeWidget (`id (`afs_serverip), `Enabled, false);
	    }
	    else
	    {
		UI::ChangeWidget (`id (`cell), `Enabled, use_afs);
		UI::ChangeWidget (`id (`afs_serverip), `Enabled, use_afs);
	    }
	    use_afs = use_afs && use_pam_krb;
	}

        if (result == `next || result == `advanced) {

            default_realm = (string) UI::QueryWidget (`id(`realm), `Value);
            default_domain = (string) UI::QueryWidget (`id(`domain), `Value);
            kdc = (string) UI::QueryWidget (`id(`kdc), `Value);
            afs_serverip = (string) UI::QueryWidget (`id(`afs_serverip), `Value);
            cell = (string) UI::QueryWidget (`id(`cell), `Value);
	    use_afs = use_afs && use_pam_krb;

            if (use_pam_krb && default_realm == "")
            {
		// error popup label
		Report::Error(_("Enter the default realm name."));
		UI::SetFocus (`id(`realm));
		result = `not_next;
		continue;
            }

	    if (use_pam_krb && kdc == "")
            {
                // error popup label
                Report::Error(_("Enter the address of the KDC server."));
		UI::SetFocus (`id(`kdc));
		result = `not_next;
                continue;
            }
	    if (use_pam_krb && !Address::Check (kdc))
	    {
		// error popup label
		Report::Error (_("The KDC server address is incorrect.") +
		    "\n\n" + Address::Valid4 ());
		UI::SetFocus (`id(`kdc));
		result = `not_next;
		continue;
	    }
	    if (use_afs && afs_serverip == "")
            {
                // error popup label
                Report::Error(_("Enter the address of the AFS server."));
		UI::SetFocus (`id(`afs_serverip));
		result = `not_next;
                continue;
            }
	    if (use_afs && !IP::Check (afs_serverip))
	    {
		// Popup text
		Report::Error (_("The IP address is incorrect") +
		    "\n\n" + IP::Valid4 ());
		UI::SetFocus(`id(`afs_serverip));
		result = `not_next;
		continue;
	    }
	    if (use_afs && cell == "")
            {
                // error popup label
                Report::Error(_("Enter the AFS cell name."));
		UI::SetFocus (`id(`cell));
		result = `not_next;
                continue;
            }
	    // check for openafs* packages
	    if (use_afs)
	    {
		if (!Package::InstalledAll (["openafs", "openafs-client"]) &&
		     !contains (packages, "openafs"))
		{
		    if (!Mode::config () && !Package::Available ("openafs"))
		    {
			// error message, %1 is package name
			Popup::Error (sformat (_("Package \"%1\" is not available for installation.
AFS cannot be enabled.
"), "openafs"));
			afs_available = false;
			UI::ChangeWidget (`id (`afs), `Value, false);
			UI::ChangeWidget (`id (`afs), `Enabled, false);
			UI::ChangeWidget (`id (`cell), `Enabled, false);
			UI::ChangeWidget (`id (`afs_serverip), `Enabled, false);
			result = `not_next;
			continue;
		    }
		    if (!Mode::config () && !Package::Available ("openafs-client"))
		    {
			// error message, %1 is package name
			Popup::Error (sformat (_("Package \"%1\" is not available for installation.
AFS cannot be enabled.
"), "openafs-client"));
			afs_available = false;
			UI::ChangeWidget (`id (`afs), `Value, false);
			UI::ChangeWidget (`id (`afs), `Enabled, false);
			UI::ChangeWidget (`id (`cell), `Enabled, false);
			UI::ChangeWidget (`id (`afs_serverip), `Enabled, false);
			result = `not_next;
			continue;
		    }
		    // yes/no pupup
		    if (Popup::YesNo (_("Packages \"openafs\" and \"openafs-client\"
are necessary for using AFS.
Install them?
")))
			packages = (list<string>) union(packages,["openafs","openafs-client"]);
		    else
		    {
			result = `not_next;
			continue;
		    }
		}
	    }
	    else
	    {
		packages = filter (string p, packages, ``( !contains (
		    ["openafs", "openafs-client"], p)));
	    }
        }
	if ((result == `abort || result == `cancel) &&
	    ReallyAbort () != `abort)
	{
	    result = `not_next;
	}
    } while (!contains ([`back, `cancel, `abort, `next, `advanced], result));

    if (result == `next || result == `advanced)
    {
        Kerberos::modified = true;
        Kerberos::default_domain = default_domain;
	Kerberos::default_realm = default_realm;
	Kerberos::kdc = kdc;

        if (use_pam_krb != Kerberos::use_pam_krb)
        {
            Kerberos::pam_modified = true;
            Kerberos::use_pam_krb = use_pam_krb;
        }

	if (cell != Kerberos::afs_cell || use_afs != Kerberos::use_afs ||
	    afs_serverip != Kerberos::afs_serverip)
	{
	    Kerberos::use_afs		= use_afs;
	    Kerberos::afs_cell		= cell;
	    Kerberos::afs_serverip	= afs_serverip;
	    Kerberos::afs_modified	= true;
	    Kerberos::pam_modified	= true;
	}
	Kerberos::packages = (list<string>) union (Kerberos::packages, packages);
    }
    return result;
}

/**
 * Kerberos advanced configuration
 * @return dialog result
 */
define symbol AdvancedDialog() {

    string help_text =

    // help text (do not transl. values "m","h", "d")
    _("<p>Values of <b>Ticket Lifetime</b>, <b>Renewable Lifetime</b>, and
<b>Clock Skew</b> are in seconds by default. Alternatively, specify the time
unit (<i>m</i> for minutes, <i>h</i> for hours, or <i>d</i> for days) and use
it as a value suffix (e.g., <i>1d</i> or <i>24h</i> for one day).</p>
") +

    // help text
    _("<p><b>Forwardable tickets</b> let you transfer your complete identity
(TGT) to another machine. <b>Proxiable tickets</b> only let you transfer
particular tickets.</p>
") +

    // help text
    _("<p>If <b>Retain Tickets</b> is true, a PAM module retains the tickets
after closing the session.</p>
") +

    // help text
    _("<p>To enable Kerberos support for your <b>openssh client</b>, check the
appropriate check box. In such a case, Kerberos tickets are used for user
authentication on the ssh server.</p>
") +

    // help text
    _("<p>When <b>Minimum UID</b> is greater than 0, authentication attempts by
users with UIDs below the specified number are ignored. This is useful for
disabling Kerberos authentication for the system administrator (<i>root</i>).</p>
")+

    // help text
    _("<p>
The <b>Clock Skew</b> is the tolerance for the time stamps not exactly matching the host's system clock. The value is in seconds.</p>") +

    //helptext
    _("<p>
To synchronize your time with an NTP server, configure your computer
as an NTP client. Access the configuration with <b>NTP Configuration</b>.
</p>
");

    string uid		= Kerberos::minimum_uid;
    string ticket	= Kerberos::ticket_lifetime;
    string renew	= Kerberos::renew_lifetime;
    boolean forw	= Kerberos::forwardable == "true";
    boolean prox	= Kerberos::proxiable == "true";
    boolean retain	= Kerberos::retain_after_close == "true";
    boolean ssh		= Kerberos::ssh_support;

    string clockskew	= Kerberos::clockskew;

    term con = `HBox (`HSpacing (3), `VBox (
        `VSpacing (1),
	// frame label
	`Frame (_("Ticket Attributes"), `HBox(`HSpacing (0.5), `VBox(
	    `VSpacing (0.5),
	    // textentry label
	    `TextEntry (`id (`ticket), _("&Default Ticket Lifetime"), ticket),
	    // textentry label
	    `TextEntry (`id (`renew), _("De&fault Renewable Ticket Lifetime"),
		renew),
	    // checkbox label
	    `Left(`CheckBox (`id (`forw), _("Tickets are For&wardable"), forw)),
	    // checkbox label
	    `Left(`CheckBox (`id (`prox), _("Tickets are &Proxiable"), prox)),
	    // checkbox label
	    `Left(`CheckBox (`id (`retain), _("R&etain Tickets"), retain)),
	    `VSpacing (0.5)), `HSpacing (0.5)
	)),
        `VSpacing (1),
	`Left(`CheckBox (`id (`ssh),
	    // checkbox label (leave 'openssh')
	    _("Kerberos Support for open&ssh Client"), ssh)),
        `VSpacing (0.5),
        // infield label
        `IntField (`id (`uid), _("Minimum &UID"), 0, 60000,
	    tointeger (uid)),
	`HBox (
	    // textentry label
	    `TextEntry (`id (`skew), _("C&lock Skew"), clockskew),

	    `VBox (
		`Label (""),
		// button label (run YaST client for NTP)
		`PushButton (`id(`ntp), _("&NTP Configuration..."))
	    )
	),
        `VSpacing (1)
    ), `HSpacing(3));

    Wizard::SetContentsButtons (
        // dialog title
        _("Advanced Kerberos Client Configuration"), con, help_text,
        Label::CancelButton (), Label::AcceptButton ());
    Wizard::HideAbortButton ();

    if (Mode::config ())
    {
        UI::ChangeWidget(`id(`ntp), `Enabled, false);
    }

    symbol result = nil;
    do
    {
        result = (symbol) UI::UserInput ();

	if (result == `ntp) {

	    if (Package::InstallAll ( ["yast2-ntp-client"]))
	    {
		WFM::CallFunction ("ntp-client", []);
	    }
	}

        if (result == `next) {
	    // check the values (lifetimes: d/m/h)
            ticket = (string) UI::QueryWidget (`id(`ticket), `Value);
	    if (!regexpmatch (ticket, "^([0-9]+)[dmh]$") &&
		!regexpmatch (ticket, "^([0-9]+)$"))
	    {
		// error popup (wrong format of entered value)
		Popup::Error (_("Invalid format of Ticket Lifetime entry.
Try again."));
		UI::SetFocus (`id(`ticket));
		result = `not_next;
		continue;
	    }
            renew = (string) UI::QueryWidget (`id(`renew), `Value);
	    if (!regexpmatch (renew, "^([0-9]+)[dmh]$") &&
		!regexpmatch (renew, "^([0-9]+)$"))
	    {
		Popup::Error (_("Invalid format of Ticket Lifetime entry.
Try again."));
		UI::SetFocus (`id(`renew));
		result = `not_next;
		continue;
	    }
            clockskew = (string) UI::QueryWidget (`id(`skew), `Value);
	    if (!regexpmatch (clockskew, "^([0-9]+)[dmh]$") &&
		!regexpmatch (clockskew, "^([0-9]+)$"))
	    {
		Popup::Error (_("Invalid format of clock skew entry.
Try again.
"));
		UI::SetFocus (`id(`skew));
		result = `not_next;
		continue;
	    }

	    ssh = (boolean) UI::QueryWidget (`id(`ssh), `Value);

        }
	if ((result == `abort || result == `cancel) &&
	    ReallyAbort () != `abort)
	{
	    result = `not_next;
	}

    } while (!contains ([`back, `next, `cancel, `abort], result));

    if (result == `next)
    {
        Kerberos::minimum_uid = sformat("%1",UI::QueryWidget(`id(`uid),`Value));
	Kerberos::ticket_lifetime = ticket;
	Kerberos::renew_lifetime = renew;
        Kerberos::clockskew = clockskew;
	Kerberos::forwardable = (boolean)UI::QueryWidget (`id(`forw), `Value) ?
	    "true" : "false";
	Kerberos::proxiable = (boolean) UI::QueryWidget (`id(`prox), `Value) ?
	    "true" : "false";
	Kerberos::retain_after_close =
	    (boolean) UI::QueryWidget (`id(`retain), `Value) ? "true" : "false";

	if (ssh != Kerberos::ssh_support)
	{
	    Kerberos::ssh_modified = true;
	    Kerberos::ssh_support = ssh;
	}
    }
    return result;
}


/* EOF */
}
