ACC SHELL

Path : /usr/share/YaST2/include/network/services/
File Upload :
Current File : //usr/share/YaST2/include/network/services/proxy.ycp

/**
 * File:	include/network/services/proxy.ycp
 * Package:	Network configuration
 * Summary:	Proxy configuration
 * Authors:	Michal Svec <msvec@suse.cz>
 *
 * $Id: proxy.ycp 61682 2010-04-13 10:42:28Z mzugec $
 */

{

textdomain "network";

import "Address";
import "Hostname";
import "Label";
import "Mode";
import "Netmask";
import "Popup";
import "Proxy";
import "String";
import "URL";
import "Wizard";

include "network/routines.ycp";

boolean enabled = false;
string http = "";
string https = "";
string ftp = "";
string no = "";
string user = "";
string pass = "";
boolean same_proxy = false;
/* String to pre-filled into the proxy server field */
string prefill = "http://";


// from OnlineUpdateDialogs.ycp
/**
 * Function opens the generic error dialog including the
 * message with the [Details >>] button. It handles pressing
 * the button itself.
 *
 * @param string message with the short error message
 * @param string details with all of the error details
 */

boolean modified() {
    return !(Proxy::http == http && Proxy::ftp == ftp && Proxy::no == no &&
		Proxy::https == https &&
		Proxy::user == user && Proxy::pass == pass &&
		Proxy::enabled == enabled);
}

define void ErrorPopupGeneric( string message, string details ) {
    // Informative label
    if ( size( details ) == 0 ) details = _("No details available.");
    
    // A push button
    string detailsStringOn = _("&Details <<");
    // A push button
    string detailsStringOff = _("&Details >>");
    
    term detailsButton = `PushButton( `id( `details ), detailsStringOff );
    
    string heading = Label::ErrorMsg ();
    
    term buttons = `HBox(
	detailsButton,
	`PushButton( `id( `ok ), Label::OKButton() )
    );

    UI::OpenDialog( `opt( `decorated ),
	`VBox(
	    `HBox( `HSpacing( 0.5 ), `Left( `Heading( heading ) ) ),
	    `VSpacing( 0.2 ),
	    `Left(`Label( message )),
	    `ReplacePoint( `id( `rp ), `Empty() ),
	    buttons
	)
    );

    any ret = nil;
    boolean showDetails = false;

     while( ret != `ok ) {
        ret = UI::UserInput();

	if ( ret == `details ) {
	    if ( showDetails ) {
		UI::ReplaceWidget( `id( `rp ), `Empty() );
		UI::ChangeWidget( `id( `details ), `Label, detailsStringOff );
	    } else {
		UI::ReplaceWidget( `id( `rp ), `HBox( `HSpacing( 0.5 ),
		    `HWeight( 1, `RichText(`opt(`plainText), details ) ),
		    `HSpacing( 0.5 ) )
		);
		UI::ChangeWidget( `id( `details ), `Label, detailsStringOn );
	    }
	    showDetails = !showDetails;
	}
     }
     
     UI::CloseDialog();
}

/* Known return codes - good proxy response */
list <string> return_codes_good = [
    "200", // OK
    "201", // Created
    "202", // Accepted
    "203", // Non-Authorative Information
    "204", // No Content
    "205", // Reset Content
    "206", // Partial Content

    "300", // Multiple Choices
    "301", // Moved Permanently
    "302", // Moved Temporarily
    "303", // See Other
    "304", // Not Modified
    "305", // Use Proxy
];

/* Known return codes - bad proxy response */
list <string> return_codes_bad = [
    // Proxy Errors
    "400", // Bad Request
    "401", // Authorization Required
    "402", // Payment Required (not used yet)
    "403", // Forbidden
    "404", // Not Found
    "405", // Method Not Allowed
    "406", // Not Acceptable (encoding)
    "407", // Proxy Authentication Required
    "408", // Request Timed Out
    "409", // Conflicting Request
    "410", // Gone
    "411", // Content Length Required
    "412", // Precondition Failed
    "413", // Request Entity Too Long
    "414", // Request URI Too Long
    "415", // Unsupported Media Type

    // Server Errors
    "500", // Internal Server Error
    "501", // Not Implemented
    "502", // Bad Gateway
    "503", // Service Unavailable
    "504", // Gateway Timeout
    "505", // HTTP Version Not Supported
];

/**
 * Function checks the proxy-return code.
 *
 * @param string test_type HTTP, HTTPS or FTP
 * @param string proxy_ret_stderr such as "HTTP/1.0 403 Forbidden"
 * @return boolean true if the proxy response is a good one
 */
define boolean TestProxyReturnCode (string test_type, string proxy_ret_stderr) {
    string proxy_retcode = "";
    // getting the return code string from the stderr
    foreach (string proxy_stderr, splitstring(proxy_ret_stderr, "\r?\n"), {
	if (regexpmatch(proxy_stderr, "HTTP/[0-9\.]+ [0-9]+")) {
	    proxy_retcode = regexpsub(proxy_stderr, ".*(HTTP.*)", "\\1");
	}
    });

    y2milestone("Proxy %1 test: %2", test_type, proxy_retcode);

    // The default error code, replaced with the current error code got from proxy if any code found
    string retcode = _("Unknown Error Code");
    foreach(string ret_code_part, splitstring(proxy_retcode, " "), {
	if (regexpmatch(ret_code_part, "^[0-9]+$") && size(ret_code_part)>=3) {
	    retcode = ret_code_part;
	}
    });

    // known good return code
    if (contains(return_codes_good, retcode)) {
	return true;
    // known bad return code
    } else if (contains(return_codes_bad, retcode)) {
	// Error message,
	//	%1 is a string "HTTP", "HTTPS" or "FTP"
	//	%2 is an error string such as "HTTP/1.0 403 Forbidden"
	ErrorPopupGeneric(sformat(_("An error occurred during the %1 proxy test.
Proxy return code: %2.
"), test_type, proxy_retcode), proxy_ret_stderr);
	return false;

    } else {
	// Unknown return code,
	//	%1 is the string HTTP, "HTTPS" or FTP,
	//	%2 is an error string such as "HTTP/1.0 403 Forbidden"
	ErrorPopupGeneric(sformat(_("An unknown error occurred during the %1 proxy test.
Proxy return code: %2.
"), test_type, proxy_retcode), proxy_ret_stderr);
    }
}

/**
 * Function test the current HTTP and FTP proxy settings.
 * It currently ignores the "No Proxy" value.
 *
 * @return boolean true if successful
 */
define boolean TestProxySettings () {
    if (enabled) {
	UI::OpenDialog(
	    // An informative popup label diring the proxy testings
	    `Left(`Label(_("Testing the current proxy settings...")))
	);
	map <string, map <string, any> > ret = Proxy::RunTestProxy (http, https, ftp, user, pass);
	UI::CloseDialog();

	// curl error
	if (ret["HTTP","tested"]:true == true) {
	    if ((integer) ret["HTTP","exit"]:1 != 0) {
		// TRANSLATORS: Error popup message
		ErrorPopupGeneric(_("An error occurred during the HTTP proxy test."), ret["HTTP","stderr"]:"");
		UI::SetFocus(`id(`http));
		return false;
	    } else {
		// curl works - proxy error
		if (! TestProxyReturnCode("HTTP", ret["HTTP","stderr"]:"")) {
		    UI::SetFocus(`id(`http));
		    return false;
		}
	    }
	}

	if (ret["HTTPS","tested"]:true == true) {
	    // curl error
	    if ((integer) ret["HTTPS","exit"]:1 != 0) {
		// TRANSLATORS: Error popup message
		ErrorPopupGeneric(_("An error occurred during the HTTPS proxy test."), ret["HTTPS","stderr"]:"");
		UI::SetFocus(`id(`https));
		return false;
	    } else {
		// curl works - proxy error
		if (! TestProxyReturnCode("HTTPS", ret["HTTPS","stderr"]:"")) {
		    UI::SetFocus(`id(`https));
		    return false;
		}
	    }
	}

	if (ret["FTP","tested"]:true == true) {
	    // curl error
	    if ((integer) ret["FTP","exit"]:1 != 0) {
		// TRANSLATORS: Error popup message
		ErrorPopupGeneric(_("An error occurred during the FTP proxy test."), ret["FTP","stderr"]:"");
		UI::SetFocus(`id(`ftp));
		return false;
	    } else {
		// curl works - proxy error
		if (! TestProxyReturnCode("FTP", ret["FTP","stderr"]:"")) {
		    UI::SetFocus(`id(`ftp));
		    return false;
		}
	    }
	}

	// Popup message
	Popup::Message(_("Proxy settings work correctly."));
    } else {
	// Actually it doesn't make sense to test the proxy settings when proxy is off
	return true;
    }
}

void InitSameProxy() {
    //We have the same (non-empty) proxy URL for all protocols
    if((http != prefill) && (http == https) && (https == ftp )){
        UI::ChangeWidget(`id(`same_proxy), `Value, true);
        UI::ChangeWidget(`id(`https), `Enabled, false);
        UI::ChangeWidget(`id(`https), `Value, prefill);
        UI::ChangeWidget(`id(`ftp), `Enabled, false);
        UI::ChangeWidget(`id(`ftp), `Value, prefill);
    }
}

void QueryWidgets() {
    same_proxy = (boolean) UI::QueryWidget(`id(`same_proxy), `Value);
    http    = (string)  UI::QueryWidget(`id(`http), `Value);
    if (same_proxy) {
	https = http;
	ftp = http;
    }
    else {
        https   = (string)  UI::QueryWidget(`id(`https), `Value);
        ftp     = (string)  UI::QueryWidget(`id(`ftp), `Value);
    }

    user    = (string)  UI::QueryWidget(`id(`user), `Value);
    pass    = (string)  UI::QueryWidget(`id(`pass), `Value);
    enabled = (boolean) UI::QueryWidget(`id(`enabled), `Value);

    no = (string) UI::QueryWidget(`id(`no), `Value);

}

boolean ValidateNoProxyDomains( string no_proxies ) {
    list <string> proxy_list = splitstring( no_proxies, ",");
    boolean validate = true;
    string hostname = "";
    string netmask = "";

    foreach( string one_proxy, proxy_list, {
	one_proxy = String::CutBlanks( one_proxy );

	// IP/netmask
	if ( findfirstof( one_proxy, "/" ) != nil ) {
	    list <string> tmp = splitstring(one_proxy,"/");
	    hostname = tmp[0]:"";
	    netmask = tmp[1]:"";

	    if (!Netmask::Check( netmask ))
		validate = false;
	}
	// hostname or domain name
	else {
	    hostname = one_proxy;
	    // .domain.name case
	    if ( findfirstof( hostname, ".") == 0)
		hostname = substring(hostname, 1);
	}
	y2milestone("hostname %1, netmask %2", hostname, netmask);

	if (!Address::Check(hostname))
	    validate = false;
    });

    return validate;
}
/**
 * Proxy dialog
 * @param standalone true if not run from another ycp client
 * @return dialog result
 */
define any ProxyMainDialog(boolean standalone) ``{

    enabled = Proxy::enabled;
    http = Proxy::http;
    https = Proxy::https;
    ftp = Proxy::ftp;
    no = Proxy::no;
    user = Proxy::user;
    pass = Proxy::pass;

    ScreenName("proxy");

    if(http == "") http = prefill;
    if(https == "") https = prefill;
    if(ftp == "") ftp = prefill;

    /* Proxy dialog caption */
    string caption = _("Proxy Configuration");

    /* Proxy dialog help 1/8 */
    string help = _("<p>Configure your Internet proxy (caching) settings here.</p>
<p><b>Note:</b> It is generally recommended to relogin for the settings to take effect, 
however in some cases the application may pick up new settings immediately. Please check 
what your application (web browser, ftp client,...) supports. </p>") +

    /* Proxy dialog help 2/8 */
    _("<p><b>HTTP Proxy URL</b> is the name of the proxy server for your access
to the World Wide Web (WWW).</p>
") +

    /* Proxy dialog help 3/8 */
    _("<p><b>HTTPS Proxy URL</b> is the name of the proxy server for your secured access
to the World Wide Web (WWW).</p>
") +

    /* Proxy dialog help 3.5/8 */
    _("<p>Example: <i>http://proxy.example.com:3128/</i></p>") +

    /* Proxy dialog help 4/8 */

    _("<p><b>FTP Proxy URL</b> is the name of the proxy server for your access
to the file transfer services (FTP).</p>") +

    /* Proxy dialog help 5/8 */

	_("<p>If you have the <b>Use the Same Proxy for All Protocols</b> option checked, it is
enough to fill in the HTTP proxy URL. It will be used for all protocols
(HTTP, HTTPS and FTP).\n") +

    /* Proxy dialog help 6/8 */

    sformat (_("<p><b>No Proxy Domains</b> is a comma-separated list of domains
for which the requests should be made directly without caching,
for example, <i>%1</i>.</p>
"),
	     "localhost, .intranet.example.com, www.example.com") +

    /* Proxy dialog help 7/8 */
    _("<p>If you are using a proxy server with authorization, enter
the <b>Proxy User Name</b> and <b>Proxy Password</b>. A valid username
consists of printable ASCII characters (except for quotation marks) only.</p>
") +

    /* Proxy dialog help 8/8 */

    (!Mode::installation() ? _("<p>Press <b>Test Proxy Settings</b> to test
the current configuration for HTTP, HTTPS, and FTP proxy.</p> 
") : "");

    map display_info =  UI::GetDisplayInfo();
    boolean textmode = display_info["TextMode"]:false;

    float s = (textmode) ? (0.2) : 0.5;

    /* Proxy dialog contents */
    term contents = `HBox(
	`HSpacing(5),
	`VBox(
	/* CheckBox entry label */
	`Left(`CheckBox(`id(`enabled), `opt(`notify), _("&Enable Proxy"), enabled)),
	`VSpacing(s),
	/* Frame label */
	`Frame(`id(`frame1), _("Proxy Settings"), `HBox(`HSpacing(2), `VBox(
	    `VSpacing(0.2),
	    /* Text entry label */
	    `TextEntry(`id(`http), _("&HTTP Proxy URL"), http),
	    `VSpacing(0.2),
            `TextEntry(`id(`https), _("HTTP&S Proxy URL"), https),
            `VSpacing(0.2),
	    /* Text entry label */
	    `TextEntry(`id(`ftp), _("F&TP Proxy URL"), ftp),
	    `VSpacing(0.2),
		`Left(`CheckBox(`id(`same_proxy), `opt(`notify), _("Us&e the Same Proxy for All Protocols"))),
	    /* Text entry label */
	    // domains without proxying
	    `TextEntry(`id(`no), _("No Proxy &Domains"), no),
	    (textmode) ? `Empty() : `VSpacing(0.4)
	    ), `HSpacing(2))),
	`VSpacing(s),
	`Frame(`id(`frame2), _("Proxy Authentication"), `HBox(`HSpacing(2), `VBox(
	    /* Text entry label */
	    `HBox (
	        `InputField(`id(`user), `opt(`hstretch), _("Proxy &User Name"), user),
	        `HSpacing(0.5),
	        /* Password entry label */
	        `Password( `id(`pass), `opt(`hstretch), _("Proxy &Password"), pass),
	    (textmode) ? `Empty() : `VSpacing(0.4)
	    )), `HSpacing(2))),
	    `VSpacing(s),
	    /* Test Proxy Settings - push button */
	    (!Mode::installation()) ?
	        `PushButton(`id("test_proxy"), _("Test Pr&oxy Settings")): `Empty()
	),
	`HSpacing(5)
    );

//    if(standalone == true)
	Wizard::SetContentsButtons(caption, contents, help,
		Label::BackButton(), Label::FinishButton());
        Wizard::SetNextButton(`next, Label::OKButton());
        Wizard::SetAbortButton(`abort, Label::CancelButton());
        Wizard::HideBackButton();
/*
    else
	Wizard::SetContentsButtons(caption, contents, help,
		Label::BackButton(), Label::OKButton());
*/

    // #103841, relaxed. now avoiding only quotes
    // #337048 allow using space as well
    // was CAlnum() + ".:_-/\\"
    string ValidCharsUsername = deletechars (String::CGraph (), "'\"") + " ";
    UI::ChangeWidget(`id(`http), `ValidChars, URL::ValidChars);
    UI::ChangeWidget(`id(`https), `ValidChars, URL::ValidChars);
    UI::ChangeWidget(`id(`ftp), `ValidChars, URL::ValidChars);
    // '/' character for subnets definition - #490661
    UI::ChangeWidget(`id(`no), `ValidChars, Hostname::ValidCharsDomain + " ,/");
    UI::ChangeWidget(`id(`user), `ValidChars, ValidCharsUsername);
    UI::ChangeWidget(`id(`frame1), `Enabled, enabled);
    UI::ChangeWidget(`id(`frame2), `Enabled, enabled);
    if ( !Mode::installation() ) 
	UI::ChangeWidget(`id("test_proxy"), `Enabled, enabled) ;
    InitSameProxy();

    if(enabled == true) UI::SetFocus(`id(`http));
    else UI::SetFocus(`id(`enabled));

    any ret = nil;
    while(true) {

	ret = UI::UserInput();
	QueryWidgets();

	/* abort? */
	if(ret == `abort || ret == `cancel || ret == `back) {
	    if(ReallyAbortCond( modified() )) break;
	    else continue;
	}
	if(ret == `enabled) {
	    UI::ChangeWidget(`id(`frame1), `Enabled, enabled);
	    UI::ChangeWidget(`id(`frame2), `Enabled,enabled);
	    UI::ChangeWidget(`id("test_proxy"), `Enabled, enabled);
	    InitSameProxy();
	    continue;
	}
	else if(ret == `same_proxy) {
	    UI::ChangeWidget(`id(`https), `Value, prefill);
	    UI::ChangeWidget(`id(`ftp), `Value, prefill);
	    UI::ChangeWidget(`id(`https), `Enabled, !same_proxy);
	    UI::ChangeWidget(`id(`ftp), `Enabled, !same_proxy);
	    continue;
	}
	/* next */
	else if (ret == `next || ret == "test_proxy") {

	    if(http == prefill) http = "";
	    if(https == prefill) https = "";
	    if(ftp == prefill) ftp = "";

	    if(enabled == false) 
		break;
	    else {
		if((http == "") && (https == "") && (ftp == "") ){
		    /* Popup error text - http, https and ftp proxy URLs are blank */
		    if(!Popup::ContinueCancel(_("Proxy is enabled, but no proxy URL has been specified.
Really use these settings?")))
			continue;
		}
	    }
	    /* check_* */
	    if(user == "" && pass != "") {
		/* Popup::Error text */
		Popup::Error(_("You cannot enter a password and leave the user name empty."));
		UI::SetFocus(`id(`user));
		continue;
	    }
	    if(http != "" && http != prefill) {
		if(!URL::Check(http)) {
		    /* Popup::Error text */
		    Popup::Error(_("HTTP proxy URL is invalid."));
		    UI::SetFocus(`id(`http));
		    continue;
		}
		map urlmap = URL::Parse(http);
		if(urlmap["scheme"]:"" == "") {
		    /* Popup::Error text */
		    Popup::Error(_("HTTP proxy URL must contain a scheme specification (http)."));
		    UI::SetFocus(`id(`http));
		    continue;
		}
	    }
            if(https != "" && https != prefill) {
                if(!URL::Check(https)) {
                    /* Popup::Error text */
                    Popup::Error(_("The HTTPS proxy URL is invalid."));
                    UI::SetFocus(`id(`https));
                    continue;
                }
                map urlmap = URL::Parse(https);
                if(urlmap["scheme"]:"" == "") {
                    /* Popup::Error text */
                    Popup::Error(_("The HTTPS proxy URL must contain a scheme specification (http)."));
                    UI::SetFocus(`id(`https));
                    continue;
                }
            }
	    if(ftp != "" && ftp != prefill) {
		if(!URL::Check(ftp)) {
		    /* Popup::Error text */
		    Popup::Error(_("FTP proxy URL is invalid."));
		    UI::SetFocus(`id(`ftp));
		    continue;
		}
		map urlmap = URL::Parse(ftp);
		if(urlmap["scheme"]:"" == "") {
		    /* Popup::Error text */
		    Popup::Error(_("FTP proxy URL must contain a scheme specification (http)."));
		    UI::SetFocus(`id(`ftp));
		    continue;
		}
	    }
	    if ( no != "" && no != nil) {
		if (!ValidateNoProxyDomains( no )) {
		    //Translators: no proxy domain is a domain that can be accessed without proxy
		    Popup::Error(_("One or more no proxy domains are invalid. 
Check if all domains match one of the following:
* IP address
* IP address/netmask
* Fully qualified hostname
* Domain name prefixed by '.'"));
		    UI::SetFocus(`id(`no));
		    continue;
		}
	    }

	    if (ret == `next) {
		break;
	    } else if (ret == "test_proxy") {
		TestProxySettings();
	    }
	}
	/* back */
	else if(ret == `back) {
	    break;
	}
	else {
	    y2error("unexpected retcode: %1", ret);
	    continue;
	}
    }

    if(ret == `next) {

	if (!modified()){

	    y2debug("not modified");
	    return ret;
	}


	Proxy::enabled = enabled;
	if(enabled) {
	    Proxy::http = http;
	    Proxy::https = https;
	    Proxy::ftp = ftp;
	    Proxy::no = no;
	    Proxy::user = user;
	    Proxy::pass = pass;
	}

	Proxy::SetModified();
    }

    return ret;
}

/* EOF */
}

ACC SHELL 2018