home *** CD-ROM | disk | FTP | other *** search
/ Chip 2007 January, February, March & April / Chip-Cover-CD-2007-02.iso / boot / i386 / root / usr / share / YaST2 / modules / SignatureCheckDialogs.ycp < prev    next >
Text File  |  2006-11-29  |  28KB  |  873 lines

  1. /**
  2.  * Module:        SignatureCheckDialogs.ycp
  3.  * Authors:        Lukas Ocilka <locilka@suse.cz>
  4.  *
  5.  * Dialogs handling for RPM/Source GPM signatures.
  6.  *
  7.  * $Id: SignatureCheckDialogs.ycp 28363 2006-02-24 12:27:15Z locilka $
  8.  */
  9.  
  10. {
  11.     textdomain "packager";
  12.     
  13.     module "SignatureCheckDialogs";
  14.  
  15.     import "Label";
  16.     import "Popup";
  17.     import "Message";
  18.     import "DontShowAgain";
  19.     import "Stage";
  20.     import "Linuxrc";
  21.  
  22.     /* --------------------------- Don't show this dialog again Magic --------------------------- */
  23.  
  24.     /**
  25.      * Functions sets whether user want's to show the dialog again
  26.      *
  27.      * @param string popup_type dialog type
  28.      * @param boolean show again
  29.      * @param string popup_url
  30.      */
  31.     global void SetShowThisPopup (string popup_type, boolean show_it, string popup_url) {
  32.     if (popup_type == nil || show_it == nil) {
  33.         y2error("Neither popup_type %1 nor show_it %2 can be nil!", popup_type, show_it);
  34.         return;
  35.     }
  36.  
  37.     // it's the default
  38.     if (show_it) {
  39.         y2debug("User decision to show dialog '%1' again is '%2'", popup_type, show_it);
  40.     // store only "don't show"
  41.     } else {
  42.         y2milestone("User decision to show dialog '%1' for '%2' again is '%3'", popup_type, popup_url, show_it);
  43.         // Show again -> false, so, store it
  44.         DontShowAgain::SetShowQuestionAgain($[
  45.         "q_type" : "inst-source", "q_ident" : popup_type, "q_url" : popup_url
  46.         ], show_it);
  47.     }
  48.     }
  49.     
  50.     /**
  51.      * Function returns whether user want's to show the dialog (again).
  52.      * true is the default if nothing is set.
  53.      *
  54.      * @param string popup_type dialog type
  55.      * @param string popup_url if any
  56.      * @return boolean show the dialog
  57.      */
  58.     global boolean GetShowThisPopup (string popup_type, string popup_url) {
  59.     if (popup_type == nil) {
  60.         y2error("popup_type %1 mustn't be nil!", popup_type);
  61.         return true;
  62.     }
  63.  
  64.     // Read the current configuration from system configuration
  65.     boolean stored = DontShowAgain::GetShowQuestionAgain($[
  66.         "q_type" : "inst-source", "q_ident" : popup_type, "q_url" : popup_url
  67.     ]);
  68.     
  69.     // Stored in the configuration
  70.     if (stored != nil)
  71.         return stored;
  72.     // Unknown status, return default
  73.     else
  74.         return true;
  75.     }
  76.  
  77.     /**
  78.      * Function sets the default dialog return value
  79.      * for case when user selected "don't show again"
  80.      *
  81.      * @param string popup_type dialog type
  82.      * @param boolean default_return
  83.      */
  84.     global void SetDefaultDialogReturn (string popup_type, boolean default_return, string popup_url) {
  85.     if (popup_type == nil || default_return == nil) {
  86.         y2error("Neither popup_type %1 nor default_return %2 can be nil!", popup_type, default_return);
  87.         return;
  88.     }
  89.     y2milestone("User decision in default return for '%1' for '%2' is '%3'",
  90.         popup_type, popup_url, default_return);
  91.     DontShowAgain::SetDefaultReturn($[
  92.         "q_type" : "inst-source", "q_ident" : popup_type, "q_url" : popup_url,
  93.     ], default_return);
  94.     }
  95.  
  96.     /**
  97.      * Function returns the default popup return value
  98.      * for case when user selected "don't show again"
  99.      *
  100.      * @param string popup_type dialog type
  101.      * @boolean boolean default dialog return
  102.      */
  103.     global boolean GetDefaultDialogReturn (string popup_type, string popup_url) {
  104.     if (popup_type == nil) {
  105.         y2error("popup_type %1 mustn't be nil!", popup_type);
  106.         return false;
  107.     }
  108.  
  109.     boolean stored_return = (boolean) DontShowAgain::GetDefaultReturn($[
  110.         "q_type" : "inst-source", "q_ident" : popup_type, "q_url" : popup_url,
  111.     ]);
  112.     
  113.     y2milestone("User decided not to show popup for '%1' again, returning user-decision '%2'",
  114.         popup_type, stored_return);
  115.     return stored_return;
  116.     }
  117.  
  118.     void HandleDoNotShowDialogAgain (boolean default_return, string dont_show_dialog_ident, symbol dont_show_dialog_checkboxid, string dont_show_url) {
  119.     boolean dont_show_status = (boolean) UI::QueryWidget(`id(dont_show_dialog_checkboxid), `Value);
  120.     // Widget doesn't exist
  121.     if (dont_show_status == nil) {
  122.         y2warning("No such UI widget with ID: %1", dont_show_dialog_checkboxid);
  123.     // Checkbox selected -> Don't show again
  124.     } else if (dont_show_status == true) {
  125.         y2debug("User decision -- don't show the dialog %1 again, setting default return %2",
  126.         dont_show_dialog_ident, default_return);
  127.         SetShowThisPopup(dont_show_dialog_ident, false, dont_show_url);
  128.         SetDefaultDialogReturn(dont_show_dialog_ident, default_return, dont_show_url);
  129.     // Checkbox not selected -> Show again
  130.     } else {
  131.         SetShowThisPopup(dont_show_dialog_ident, true, dont_show_url);
  132.     }
  133.     }
  134.     
  135.     /* --------------------------- Don't show this dialog again Magic --------------------------- */
  136.  
  137.     // /etc/sysconfig/security:CHECK_SIGNATURES
  138.  
  139.     boolean check_signatures = nil; // lazy
  140.  
  141.     /**
  142.      * A semi-public helper. Convert the kernel parameter
  143.      * to the sysconfig string
  144.      * @return sysconfig value: yes, yast, no
  145.      */
  146.     global string CheckSignatures () {
  147.     string cmdline = Linuxrc::InstallInf ("Cmdline");
  148.     y2milestone ("Cmdline: %1", cmdline);
  149.  
  150.     string val = regexpsub (cmdline, "CHECK_SIGNATURES=([[:alpha:]]+)", "\\1");
  151.     if (val == nil)
  152.     {
  153.         val = regexpsub (cmdline, "no_sig_check=([^[:digit:]]+)", "\\1");
  154.         if (val != nil)
  155.         {
  156.         map<string, string> trans = $[
  157.             "0": "yes",
  158.             "1": "yast",
  159.             "2": "no",
  160.             ];
  161.         val = trans[val]:nil;
  162.         }
  163.     }
  164.     if (val == nil)
  165.     {
  166.         val = "yes";
  167.     }
  168.     return val;
  169.     }
  170.  
  171.     /**
  172.      * Should signatures be checked at all? Check a sysconfig variable
  173.      * (or a kernel parameter for the 1st installation stage).
  174.      * @return do checking?
  175.      */
  176.     global boolean CheckSignaturesInYaST () {
  177.     if (check_signatures == nil)
  178.     {
  179.         string chs = nil;
  180.         if (Stage::initial ())
  181.         {
  182.         chs = CheckSignatures ();
  183.         }
  184.         else
  185.         {
  186.         // default is "yes"
  187.         chs = (string) SCR::Read (.sysconfig.security.CHECK_SIGNATURES);
  188.         }
  189.         y2milestone ("CHECK_SIGNATURES: %1", chs);
  190.         check_signatures = chs != "no";
  191.     }
  192.     return check_signatures;
  193.     }
  194.  
  195.     /**
  196.      * Function adds delimiter between after_chars characters in the string
  197.      *
  198.      * @param string to be splitted
  199.      * @param string delimiter
  200.      * @param integer after characters
  201.      * @return string with delimiters
  202.      */
  203.     string StringSplitter(string whattosplit, string delimiter, integer after_chars) {
  204.     string splittedstring       = "";
  205.     integer after_chars_counter = 0;
  206.     integer max_size            = size(whattosplit);
  207.     
  208.     while (true) {
  209.         if ((after_chars_counter + after_chars) >= max_size) {
  210.         splittedstring = splittedstring +
  211.             (splittedstring == "" ? "":delimiter) +
  212.             substring(whattosplit, after_chars_counter);
  213.         break;
  214.         } else {
  215.         splittedstring = splittedstring +
  216.             (splittedstring == "" ? "":delimiter) +
  217.             substring(whattosplit, after_chars_counter, after_chars);
  218.         after_chars_counter = after_chars_counter + after_chars;
  219.         }
  220.     }
  221.     
  222.     return splittedstring;
  223.     }
  224.  
  225.     /* Standard text strings */
  226.  
  227.     // GnuPG fingerprint used as "Fingerprint: AAA BBB CCC"
  228.     string s_fingerprint = _("Fingerprint");
  229.     // GnuPG key ID used as "Key ID: 1144AAAA444"
  230.     string s_keyid = _("Key ID");
  231.  
  232.     // Defining icons for dialogs
  233.     map <string, string> msg_icons = $[
  234.     "error"    : "/usr/share/YaST2/theme/current/icons/32x32/apps/msg_error.png",
  235.     "warning"  : "/usr/share/YaST2/theme/current/icons/32x32/apps/msg_warning.png",
  236.     "question" : "/usr/share/YaST2/theme/current/icons/32x32/apps/msg_warning.png",
  237.     ];
  238.  
  239.     // UI can show images
  240.     boolean has_local_image_support = nil;
  241.  
  242.     /**
  243.      * Returns term with message icon
  244.      *
  245.      * @param string message type "error", "warning" or "question"
  246.      * @return term `Image(...) with margins
  247.      */
  248.     term MessageIcon (string msg_type) {
  249.     // lazy loading
  250.     if (has_local_image_support == nil) {
  251.         map ui_capabilities = UI::GetDisplayInfo();
  252.         has_local_image_support = ui_capabilities["HasLocalImageSupport"]:false;
  253.     }
  254.  
  255.     // UI can show images
  256.     if (has_local_image_support) {
  257.         if (msg_icons[msg_type]:nil == nil) {
  258.         y2warning("Message type %1 not defined", msg_type);
  259.         return `Empty();
  260.         }
  261.         return `MarginBox(1, 0.5, `Image(msg_icons[msg_type]:"", "[!]"));
  262.     } else {
  263.         return `Empty();
  264.     }
  265.     }
  266.  
  267.     /**
  268.      * Returns term of yes/no buttons
  269.      *
  270.      * @param symbol default button `yes or `no
  271.      * @return term with buttons
  272.      */
  273.     term YesNoButtons (symbol default_button) {
  274.     term yes_button = `PushButton(`id(`yes), Label::YesButton());
  275.     term no_button  = `PushButton(`id(`no), Label::NoButton());
  276.  
  277.     if (default_button == `yes) {
  278.         yes_button = `PushButton(`id(`yes), `opt(`default), Label::YesButton());
  279.     } else {
  280.         no_button  = `PushButton(`id(`no), `opt(`default), Label::NoButton());
  281.     }
  282.     
  283.     return `HBox (
  284.         yes_button,
  285.         `HSpacing(2),
  286.         no_button
  287.     );
  288.     }
  289.  
  290.     /**
  291.      * Returns 'true' (yes), 'false' (no) or 'nil' (cancel)
  292.      *
  293.      * @return boolean user input yes==true
  294.      */
  295.     boolean WaitForYesNoCancelUserInput() {
  296.     any user_input = nil;
  297.     boolean ret = nil;
  298.  
  299.     while (true) {
  300.         user_input = UI::UserInput();
  301.         // yes button
  302.         if (user_input == `yes) {
  303.         ret = true;
  304.         break;
  305.         // no button
  306.         } else if (user_input == `no) {
  307.         ret = false;
  308.         break;
  309.         // closing window uisng [x]
  310.         } else if (user_input == `cancel) {
  311.         ret = nil;
  312.         break;
  313.         } else {
  314.         y2error("Unknown user input: '%1'", user_input);
  315.         continue;
  316.         }
  317.     }
  318.  
  319.     return ret;
  320.     }
  321.  
  322.     /**
  323.      * Waits for user input and checks it agains accepted symbols.
  324.      * Returns the default symbol in case of `cancel (user closes the dialog).
  325.      *
  326.      * @param list <symbol> of accepted symbol by UserInput
  327.      * @param symbol default return for case of `cancel
  328.      */
  329.     symbol WaitForSymbolUserInput (list <symbol> list_of_accepted, symbol default_symb) {
  330.     symbol user_input = nil;
  331.     symbol ret = nil;
  332.     
  333.     while (true) {
  334.         user_input = (symbol) UI::UserInput();
  335.         if (contains(list_of_accepted, user_input)) {
  336.         ret = user_input;
  337.         break;
  338.         } else if (user_input == `cancel) {
  339.         ret = default_symb;
  340.         break;
  341.         } else {
  342.         y2error("Unknown user input: '%1'", user_input);
  343.         continue;
  344.         }
  345.     }
  346.     
  347.     return ret;
  348.     }
  349.  
  350.     /**
  351.      * Used for unsiged file or package. Opens dialog asking whether user wants
  352.      * to use this unsigned item.
  353.      *
  354.      * @param symbol item_type `file or `package
  355.      * @param string item_name file name or package name
  356.      * @param string dont_show_dialog_ident for the identification in magic "don't show" functions
  357.      * @return boolean use or don't use ('true' if 'yes')
  358.      */
  359.     global boolean UseUnsignedItem (symbol item_type, string item_name, string dont_show_dialog_ident) {
  360.     string description_text = sformat((item_type == `package ?
  361.         // popup question, %1 stands for the package name
  362.         _("The package %1 is not digitally signed. This means that the origin
  363. and integrity of the package cannot be verified. Installing the package
  364. may put the integrity of your system at risk.
  365.  
  366. Install it anyway?")
  367.         :
  368.         // popup question, %1 stands for the filename
  369.         _("The file %1
  370. is not digitally signed. This means that the origin and integrity of the file
  371. cannot be verified. Using the file may put the integrity of your system at risk.
  372.  
  373. Use it anyway?")
  374.     ), item_name);
  375.  
  376.     UI::OpenDialog(
  377.         `opt(`decorated),
  378.         `VBox(
  379.         `HBox (
  380.             `VCenter(MessageIcon("warning")),
  381.             // popup heading
  382.             `VCenter(`Heading( _("Signature Check Failed"))),
  383.             `HStretch()
  384.         ),
  385.         `MarginBox(0.5, 0.5, `Label(description_text)),
  386.         `Left(`MarginBox(0, 1.2, `CheckBox(`id(`dont_show_again),
  387.             Message::DoNotShowMessageAgain(),
  388.             (GetShowThisPopup(dont_show_dialog_ident, item_name) ? false:true)
  389.         ))),
  390.         YesNoButtons(`no)
  391.         )
  392.     );
  393.  
  394.     boolean ret = WaitForYesNoCancelUserInput();
  395.     // default value
  396.     if (ret == nil) ret = false;
  397.     
  398.     // Store the don't show value, store the default return value
  399.     HandleDoNotShowDialogAgain(ret, dont_show_dialog_ident, `dont_show_again, item_name);
  400.  
  401.     UI::CloseDialog();
  402.     return ret;
  403.     }
  404.  
  405.     /**
  406.      * Used for file or package on signed source but without any checksum.
  407.      * Opens dialog asking whether user wants to use this item.
  408.      *
  409.      * @param symbol item_type `file or `package
  410.      * @param string item_name file name or package name
  411.      * @param string dont_show_dialog_ident for the identification in magic "don't show" functions
  412.      * @return boolean use or don't use ('true' if 'yes')
  413.      */
  414.     global boolean UseItemWithNoChecksum (symbol item_type, string item_name, string dont_show_dialog_ident) {
  415.     string description_text = sformat((item_type == `package ?
  416.         // popup question, %1 stands for the package name
  417.         _("No checksum for package %1 was found in the source.
  418. This means that the package is part of the signed source, but the list of checksums
  419. on this source does not mention this package. Installing the package may put
  420. the integrity of your system at risk.
  421.  
  422. Install it anyway?")
  423.         :
  424.         // popup question, %1 stands for the filename
  425.         _("No checksum for file %1
  426. was found in the source. This means that the file is part of the signed source,
  427. but the list of checksums on this source does not mention this file. Using the file
  428. may put the integrity of your system at risk.
  429.  
  430. Use it anyway?")
  431.     ), item_name);
  432.  
  433.     UI::OpenDialog(
  434.         `opt(`decorated),
  435.         `VBox(
  436.         `HBox (
  437.             `VCenter(MessageIcon("warning")),
  438.             // popup heading
  439.             `VCenter(`Heading( _("No Checksum Found"))),
  440.             `HStretch()
  441.         ),
  442.         `MarginBox(0.5, 0.5, `Label(description_text)),
  443.         `Left(`MarginBox(0, 1.2, `CheckBox(`id(`dont_show_again),
  444.             Message::DoNotShowMessageAgain(),
  445.             (GetShowThisPopup(dont_show_dialog_ident, item_name) ? false:true)
  446.         ))),
  447.         YesNoButtons(`no)
  448.         )
  449.     );
  450.  
  451.     boolean ret = WaitForYesNoCancelUserInput();
  452.     // default value
  453.     if (ret == nil) ret = false;
  454.     
  455.     // Store the don't show value, store the default return value
  456.     HandleDoNotShowDialogAgain(ret, dont_show_dialog_ident, `dont_show_again, item_name);
  457.  
  458.     UI::CloseDialog();
  459.     return ret;
  460.     }
  461.  
  462.     /**
  463.      * Used for corrupted file or package. Opens dialog asking whether user wants
  464.      * to use this corrupted item.
  465.      *
  466.      * @param symbol item_type `file or `package
  467.      * @param string item_name file name or package name
  468.      * @param string key_id
  469.      * @param string key_name
  470.      * @param string fingerprint
  471.      * @return boolean use or don't use ('true' if 'yes')
  472.      */
  473.     global boolean UseCorruptedItem (symbol item_type, string item_name, string key_id, string key_name, string fingerprint) {
  474.     string description_text = sformat((item_type == `package ?
  475.         // popup question, %1 stands for the package name, %2 for the complete description of the GnuPG key (multiline)
  476.         _("Package %1 is signed with the following GnuPG key, but the integrity check failed: %2
  477.  
  478. This means that the package has been changed by accident or by an attacker
  479. since the repository creator signed it. Installing it is a big risk
  480. for the integrity and security of your system.
  481.  
  482. Install it anyway?")
  483.         :
  484.         // popup question, %1 stands for the filename, %2 for the complete description of the GnuPG key (multiline)
  485.         _("File %1
  486. is signed with the following GnuPG key, but the integrity check failed: %2
  487.  
  488. This means that the file has been changed by accident or by an attacker
  489. since the repository creator signed it. Using it is a big risk
  490. for the integrity and security of your system.
  491.  
  492. Use it anyway?")
  493.         ),
  494.         item_name,
  495.         "\n\n" +
  496.         // Part of the GnuPG key description in popup, %1 is a GnuPG key ID
  497.         sformat(_("ID: %1"), key_id) + "\n" +
  498.         ((fingerprint == nil || fingerprint == "") ?
  499.             // Part of the GnuPG key description in popup, %1 is a GnuPG key fingerprint
  500.             "" : sformat(_("Fingerprint: %1") + "\n", StringSplitter(fingerprint, " ", 4))) +
  501.         // Part of the GnuPG key description in popup, %1 is a GnuPG key name
  502.         sformat(_("Name: %1"), key_name)
  503.     );
  504.  
  505.     UI::OpenDialog(
  506.         `opt(`decorated),
  507.         `VBox(
  508.         // popup heading
  509.         `HBox (
  510.             `VCenter(MessageIcon("error")),
  511.             `VCenter(`Heading( _("Validation Check Failed"))),
  512.             `HStretch()
  513.         ),
  514.         `MarginBox(0.5, 0.5, `Label(description_text)),
  515.         YesNoButtons(`no)
  516.         )
  517.     );
  518.  
  519.     boolean ret = WaitForYesNoCancelUserInput();
  520.     // default value
  521.     if (ret == nil) ret = false;
  522.  
  523.     UI::CloseDialog();
  524.     return ret;
  525.     }
  526.  
  527.     /**
  528.      * Used for file or package signed by unknown key.
  529.      *
  530.      * @param symbol item_type `file or `package
  531.      * @param string item_name file name or package name
  532.      * @param string key_id
  533.      * @param string fingerprint
  534.      * @param string dont_show_dialog_ident for the identification in magic "don't show" functions
  535.      * @return boolean true if 'yes, use file'
  536.      */
  537.     global boolean ItemSignedWithUnknownSignature (symbol item_type, string item_name, string key_id, string fingerprint, string key_name, string dont_show_dialog_ident) {
  538.     string description_text = sformat((item_type == `package ?
  539.         // popup question, %1 stands for the package name, %2 for the complex multiline description of the GnuPG key
  540.         _("The package %1 is digitally signed
  541. with the following unknown GnuPG key: %2.
  542.  
  543. This means that a trust relationship to the creator of the package
  544. cannot be established. Installing the package may put the integrity
  545. of your system at risk.
  546.  
  547. Install it anyway?")
  548.         :
  549.         // popup question, %1 stands for the filename, %2 for the complex multiline description of the GnuPG key
  550.         _("The file %1
  551. is digitally signed with the following unknown GnuPG key: %2.
  552.  
  553. This means that a trust relationship to the creator of the file
  554. cannot be established. Using the file may put the integrity
  555. of your system at risk.
  556.  
  557. Use it anyway?")
  558.         ),
  559.         item_name,
  560.         "\n" +
  561.         // Part of the GnuPG key description in popup, %1 is a GnuPG key ID
  562.         sformat(_("ID: %1"), key_id) +
  563.         ((fingerprint == nil || fingerprint == "") ?
  564.             // Part of the GnuPG key description in popup, %1 is a GnuPG key fingerprint
  565.             "" : sformat("\n" + _("Fingerprint: %1"), StringSplitter(fingerprint, " ", 4)))
  566.  
  567.         // Part of the GnuPG key description in popup, %1 is a GnuPG key name
  568.         + ((key_name != nil && key_name != "") ? sformat("\n" + _("Name: %1"), key_name) : "")
  569.     );
  570.  
  571.     UI::OpenDialog(
  572.         `opt(`decorated),
  573.         `VBox(
  574.         `HBox (
  575.             `VCenter(MessageIcon("warning")),
  576.             // popup heading
  577.             `VCenter(`Heading( _("Unknown GnuPG Key"))),
  578.             `HStretch()
  579.         ),
  580.         `MarginBox(0.5, 0.5, `Label(description_text)),
  581.         `Left(`MarginBox(0, 1.2, `CheckBox(`id(`dont_show_again),
  582.             Message::DoNotShowMessageAgain(),
  583.             (GetShowThisPopup(dont_show_dialog_ident, item_name) ? false:true)
  584.         ))),
  585.         YesNoButtons(`no)
  586.         )
  587.     );
  588.  
  589.     // This will optionally offer to retrieve the key from gpg keyservers
  590.     // That's why it will return 'symbol' instead of 'boolean'
  591.     // But by now it only handles yes/no/cancel
  592.     boolean ret = WaitForYesNoCancelUserInput();
  593.     // default value
  594.     if (ret == nil) ret = false;
  595.     
  596.     // Store the don't show value, store the default return value
  597.     HandleDoNotShowDialogAgain(ret, dont_show_dialog_ident, `dont_show_again, item_name);
  598.  
  599.     UI::CloseDialog();
  600.     return ret;
  601.     }
  602.  
  603.     /**
  604.      * Used for file or package signed by a public key. This key is still
  605.      * not listed in trusted keys.
  606.      *
  607.      * @param symbol item_type `file or `package
  608.      * @param string item_name file name or package name
  609.      * @param string key_id
  610.      * @param string key_name
  611.      * @return symbol `key_import, `install, `skip
  612.      */
  613.     global symbol ItemSignedWithPublicSignature (symbol item_type, string item_name, string key_id, string key_name) {
  614.     string description_text = sformat((item_type == `package ?
  615.         // popup question, %1 stands for the package name, %2 for the key ID, %3 for the key name
  616.         _("The package %1 is digitally signed
  617. with key '%2 (%3)'.
  618.  
  619. There is no trust relationship to the owner of the key.
  620. If you trust the owner, import the key into your set of
  621. trusted keys with Import Key then proceed
  622. with the installation.
  623.  
  624. Installing a package from an unknown source can put
  625. the integrity of your system at risk. It is safest
  626. to skip the package.")
  627.         :
  628.         // popup question, %1 stands for the filename, %2 for the key ID, %3 for the key name
  629.         _("The file %1 is digitally signed
  630. with key '%2 (%3)'.
  631.  
  632. There is no trust relationship to the owner of the key.
  633. If you trust the owner, import the key into your set of
  634. trusted keys with Import Key then proceed with
  635. the installation.
  636.  
  637. Installing a file from an unknown source can put
  638. the integrity of your system at risk. It is safest
  639. to skip it.")
  640.     ), item_name, key_id, key_name);
  641.  
  642.     UI::OpenDialog(
  643.         `opt(`decorated),
  644.         `VBox(
  645.         `HBox (
  646.             `VCenter(MessageIcon("warning")),
  647.             // popup heading
  648.             `VCenter(`Heading( _("Signed with Untrusted Public Key"))),
  649.             `HStretch()
  650.         ),
  651.         `MarginBox(0.5, 0.5, `Label(description_text)),
  652.         `HBox (
  653.             // push button
  654.             `PushButton(`id(`key_import), _("&Import Key...")),
  655.             `HSpacing(1),
  656.             // push button
  657.             `PushButton(`id(`install), _("Install &Anyway")),
  658.             `HSpacing(1),
  659.             // push button
  660.             `PushButton(`id(`skip), _("&Skip Package"))
  661.         )
  662.         )
  663.     );
  664.     UI::SetFocus(`skip);
  665.  
  666.     // wait for one of listed ID's, return the default value in case of `cancel
  667.     symbol ret = WaitForSymbolUserInput([`key_import, `install, `skip], `skip);
  668.  
  669.     UI::CloseDialog();
  670.     return ret;
  671.     }
  672.  
  673.     /**
  674.      * ImportGPGKeyDialog
  675.      *
  676.      * @param string key_id
  677.      * @param string key_name
  678.      * @param string key_location
  679.      * @param string key_fingerprint
  680.      * @return symbol
  681.      */
  682.     global symbol ImportGPGKeyDialog (string key_id, string key_name, string key_location, string fingerprint) {
  683.     // additional Richtext (HTML) warning text (kind of help), 1/2
  684.     string warning_text = _("<p>The owner of the key may distribute updates,
  685. packages, and package repositories that your system will trust and offer
  686. for installation and update without any further warning. In this way,
  687. importing the key into your keyring of trusted keys allows the key owner
  688. to have a certain amount of control over the software on your system.</p>") +
  689.  
  690.     // additional Richtext (HTML) warning text (kind of help), 2/2, %1 stands for the GnuPG key ID
  691.     sformat(_("<p>A warning dialog opens for every package that
  692. is not signed by a trusted (imported) key. If you do not import the key,
  693. packages created by the owner of key <tt>%1</tt> show this warning.</p>"), key_id);
  694.  
  695.     // popup message, %1 stands for GPG key complete multiline description, %2 for key location (URL or ...)
  696.     string dialog_text = sformat(_("The GnuPG key %1
  697. has been found at %2.
  698.  
  699. You can choose to import it into your keyring of trusted
  700. public keys, meaning that you trust the owner of the key.
  701. You should be sure that you can trust the owner and that
  702. the key really belongs to that owner before importing it."),
  703.         "\n" +
  704.         // Part of the GnuPG key description in popup, %1 is a GnuPG key ID
  705.         sformat(_("ID: %1"), key_id) + "\n" +
  706.         ((fingerprint == nil || fingerprint == "") ?
  707.             // Part of the GnuPG key description in popup, %1 is a GnuPG key fingerprint
  708.             "" : sformat(_("Fingerprint: %1") + "\n", StringSplitter(fingerprint, " ", 4))) +
  709.         // Part of the GnuPG key description in popup, %1 is a GnuPG key name
  710.         sformat(_("Name: %1"), key_name),
  711.         key_location
  712.     );
  713.  
  714.     UI::OpenDialog(
  715.         `opt(`decorated),
  716.         `HBox (
  717.             `VSpacing(19),
  718.             // left-side help
  719.             `HWeight(3,
  720.             `VBox (
  721.                 `RichText(warning_text)
  722.             )
  723.             ),
  724.             `HSpacing(1.5),
  725.             // dialog
  726.             `HWeight(5,
  727.             `VBox(
  728.                 `Top (
  729.                 `VBox (
  730.                     `HBox (
  731.                     `VCenter(MessageIcon("question")),
  732.                     // popup heading
  733.                     `VCenter(`Heading(_("Import Public GnuPG Key"))),
  734.                     `HStretch()
  735.                     ),
  736.                     // dialog message
  737.                     `MarginBox(0.5, 0.5, `Label(dialog_text))
  738.                 )
  739.                 ),
  740.             // dialog buttons
  741.             `Bottom(
  742.                 `HBox (
  743.                 // push button
  744.                 `PushButton(`id(`import), _("&Import")),
  745.                 `HSpacing(1),
  746.                 // push button
  747.                 //`PushButton(`id(`details), _("&Details...")),
  748.                 //`HSpacing(1),
  749.                 // push button
  750.                 `PushButton(`id(`dont_import), _("Do &Not Import"))
  751.                 )
  752.             )
  753.             )
  754.         )
  755.         )
  756.     );
  757.  
  758.     // No details available - disable button
  759.     // if (key_detailed_description == "") UI::ChangeWidget(`id(`details), `Enabled, false);
  760.     UI::SetFocus(`dont_import);
  761.  
  762.     symbol ret = nil;
  763.     while (ret == nil || ret == `details) {
  764.         // wait for one of listed ID's, return the default value in case of `cancel
  765.         ret = WaitForSymbolUserInput([`import, `details, `dont_import], `dont_import);
  766.         if (contains([`import, `dont_import], ret)) break;
  767.         // else if (ret == `details) Popup::LongMessage(key_detailed_description);
  768.     }
  769.  
  770.     UI::CloseDialog();
  771.     return ret;
  772.     }
  773.  
  774.     /**
  775.      * ImportUntrustedGPGKeyIntoTrustedDialog
  776.      *
  777.      * @param string key_id
  778.      * @param string key_name
  779.      * @param string fingerprint
  780.      * @return boolean whether zypp should import the key into the keyring of trusted keys
  781.      */
  782.     global boolean ImportUntrustedGPGKeyIntoTrustedDialog (string key_id, string key_name, string fingerprint) {
  783.     // additional Richtext (HTML) warning text (kind of help), 1/2
  784.     string warning_text = _("<p>The owner of the key may distribute updates,
  785. packages, and package repositories that your system will trust and offer
  786. for installation and update without any further warning. In this way,
  787. importing the key into your keyring of trusted keys allows the key owner
  788. to have a certain amount of control over the software on your system.</p>") +
  789.  
  790.     // additional Richtext (HTML) warning text (kind of help), 2/2, %1 stands for the GnuPG key ID
  791.     sformat(_("<p>A warning dialog opens for every package that
  792. is not signed by a trusted (imported) key. If you do not import the key,
  793. packages created by the owner of key <tt>%1</tt> show this warning.</p>"), key_id);
  794.  
  795.     // popup message, %1 stands for string "GPG key ID\nfingerprint", %2 for key name
  796.     string dialog_text = sformat(_("The following GnuPG key has been found: %1
  797.  
  798. You can choose to import it into your keyring of trusted
  799. public keys, meaning that you trust the owner of the key.
  800. You should be sure that you can trust the owner and that
  801. the key really belongs to that owner before importing it."),
  802.         "\n" +
  803.         // Part of the GnuPG key description in popup, %1 is a GnuPG key ID
  804.         sformat(_("ID: %1"), key_id) + "\n" +
  805.         ((fingerprint == nil || fingerprint == "") ?
  806.             // Part of the GnuPG key description in popup, %1 is a GnuPG key fingerprint
  807.             "" : sformat(_("Fingerprint: %1") + "\n", StringSplitter(fingerprint, " ", 4))) +
  808.         // Part of the GnuPG key description in popup, %1 is a GnuPG key name
  809.         sformat(_("Name: %1"), key_name)
  810.     );
  811.  
  812.     UI::OpenDialog(
  813.         `opt(`decorated),
  814.         `HBox (
  815.             `VSpacing(19),
  816.             // left-side help
  817.             `HWeight(3,
  818.             `VBox (
  819.                 `RichText(warning_text)
  820.             )
  821.             ),
  822.             `HSpacing(1.5),
  823.             // dialog
  824.             `HWeight(5,
  825.             `VBox(
  826.                 `Top (
  827.                 `VBox (
  828.                     `HBox (
  829.                     `VCenter(MessageIcon("question")),
  830.                     // popup heading
  831.                     `VCenter(`Heading(_("Import Untrusted GnuPG Key"))),
  832.                     `HStretch()
  833.                     ),
  834.                     // dialog message
  835.                     `MarginBox(0.5, 0.5, `Label(dialog_text))
  836.                 )
  837.                 ),
  838.             // dialog buttons
  839.             `Bottom(
  840.                 `HBox (
  841.                 // push button
  842.                 `PushButton(`id(`import), _("&Import")),
  843.                 `HSpacing(1),
  844.                 // push button
  845.                 //`PushButton(`id(`details), _("&Details...")),
  846.                 //`HSpacing(1),
  847.                 // push button
  848.                 `PushButton(`id(`dont_import), _("Do &Not Import"))
  849.                 )
  850.             )
  851.             )
  852.         )
  853.         )
  854.     );
  855.  
  856.     // No details available - disable button
  857.     // if (key_detailed_description == "") UI::ChangeWidget(`id(`details), `Enabled, false);
  858.     UI::SetFocus(`dont_import);
  859.  
  860.     symbol ret = nil;
  861.     while (ret == nil || ret == `details) {
  862.         // wait for one of listed ID's, return the default value in case of `cancel
  863.         ret = WaitForSymbolUserInput([`import, `details, `dont_import], `dont_import);
  864.         if (contains([`import, `dont_import], ret)) break;
  865.         // else if (ret == `details) Popup::LongMessage(key_detailed_description);
  866.     }
  867.  
  868.     UI::CloseDialog();
  869.  
  870.     return ret == `import;
  871.     }
  872. }
  873.