• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

yast / yast-security / 7348705966

28 Dec 2023 02:50PM UTC coverage: 39.237% (-0.3%) from 39.568%
7348705966

Pull #157

github

web-flow
Merge 7db7fc531 into a9a6f29de
Pull Request #157: Update rubocop

68 of 442 new or added lines in 17 files covered. (15.38%)

40 existing lines in 4 files now uncovered.

1378 of 3512 relevant lines covered (39.24%)

5.86 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

0.0
/src/include/security/dialogs.rb
1
# ------------------------------------------------------------------------------
2
# Copyright (c) 2006-2012 Novell, Inc. All Rights Reserved.
3
#
4
#
5
# This program is free software; you can redistribute it and/or modify it under
6
# the terms of version 2 of the GNU General Public License as published by the
7
# Free Software Foundation.
8
#
9
# This program is distributed in the hope that it will be useful, but WITHOUT
10
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
11
# FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
12
#
13
# You should have received a copy of the GNU General Public License along with
14
# this program; if not, contact Novell, Inc.
15
#
16
# To contact Novell about this file by physical or electronic mail, you may find
17
# current contact information at www.novell.com.
18
# ------------------------------------------------------------------------------
19

20
# File:        include/security/dialogs.ycp
21
# Package:        Security configuration
22
# Summary:        Dialogs definitions
23
# Authors:        Michal Svec <msvec@suse.cz>
24
#
25
# $Id$
26
module Yast
×
27
  module SecurityDialogsInclude
×
28
    def initialize_security_dialogs(include_target)
×
29
      Yast.import "UI"
×
30

31
      textdomain "security"
×
32

33
      Yast.import "Label"
×
34
      Yast.import "Popup"
×
35
      Yast.import "Message"
×
36
      Yast.import "Security"
×
37
      Yast.import "Wizard"
×
38

39
      Yast.include include_target, "security/helps.rb"
×
40
      Yast.include include_target, "security/routines.rb"
×
41

42
      @display_manager = Security.display_manager
×
43

44
      @tree_dialogs = [
×
45
        "main",
×
46
        "overview",
×
47
        "password",
×
48
        "boot",
×
49
        "login",
×
50
        "users",
×
51
        "misc",
×
52
        :wizardTree
×
53
      ]
×
54

55
      @configurable_options = [
×
56
        "PERMISSION_SECURITY",
×
57
        "MANDATORY_SERVICES",
×
58
        "EXTRA_SERVICES",
×
59
        "kernel.sysrq"
×
60
      ]
×
61

62
      @UNKNOWN_STATUS = _("Unknown")
×
63

64
      @label_mapping = {
×
65
        "kernel.sysrq"                              => _("Use magic SysRq keys"),
×
66
        "PERMISSION_SECURITY"                       => _(
×
67
          "Use secure file permissions"
×
68
        ),
×
69
        "DISPLAYMANAGER_REMOTE_ACCESS"              => _(
×
70
          "Remote access to the display manager"
×
71
        ),
×
72
        "SYSLOG_ON_NO_ERROR"                        => _(
×
73
          "Always generate syslog message for cron scripts"
×
74
        ),
×
75
        "DHCPD_RUN_CHROOTED"                        => _(
×
76
          "Run the DHCP daemon in a chroot"
×
77
        ),
×
78
        "DHCPD_RUN_AS"                              => _(
×
79
          "Run the DHCP daemon as dhcp user"
×
80
        ),
×
81
        "DISPLAYMANAGER_ROOT_LOGIN_REMOTE"          => _(
×
82
          "Remote root login in the display manager"
×
83
        ),
×
84
        "DISPLAYMANAGER_XSERVER_TCP_PORT_6000_OPEN" => _(
×
85
          "Remote access to the X server"
×
86
        ),
×
87
        "SMTPD_LISTEN_REMOTE"                       => _(
×
88
          "Remote access to the email delivery subsystem"
×
89
        ),
×
90
        "DISABLE_RESTART_ON_UPDATE"                 => _(
×
91
          "Restart services on update"
×
92
        ),
×
93
        "DISABLE_STOP_ON_REMOVAL"                   => _(
×
94
          "Stop services on removal"
×
95
        ),
×
96
        "net.ipv4.tcp_syncookies"                   => _(
×
97
          "Enable TCP syncookies"
×
98
        ),
×
99
        "net.ipv4.ip_forward"                       => _("IPv4 forwarding"),
×
100
        "net.ipv6.conf.all.forwarding"              => _("IPv6 forwarding"),
×
101
        "MANDATORY_SERVICES"                        => _(
×
102
          "Enable basic system services"
×
103
        ),
×
104
        "EXTRA_SERVICES"                            => _(
×
105
          "Disable extra services"
×
106
        )
×
107
      }
×
108

109
      # mapping for "Enable" and "Disable" links
110
      # current value -> new value
111
      @link_value_mapping = {
×
112
        "yes" => "no",
×
NEW
113
        "no"  => "yes",
×
NEW
114
        "1"   => "0",
×
NEW
115
        "0"   => "1",
×
NEW
116
        true  => false,
×
117
        false => true
×
118
      }
×
119

120
      # mapping for "Configure" links
121
      # config name -> dialog name
122
      @link_config_mapping = {
×
123
        "PERMISSION_SECURITY" => "misc",
×
124
        "kernel.sysrq"        => "misc"
×
125
      }
×
126

127
      # mapping for "Configure" links
128
      # config name -> yast client
129
      @link_client_mapping = {
×
130
        "MANDATORY_SERVICES" => "services-manager",
×
131
        "EXTRA_SERVICES"     => "services-manager"
×
132
      }
×
133

134
      @link_update_mapping = {
×
NEW
135
        "MANDATORY_SERVICES" => -> { Security.ReadServiceSettings },
×
NEW
136
        "EXTRA_SERVICES"     => -> { Security.ReadServiceSettings }
×
137
      }
×
138
    end
×
139

140
    def SecurityStatus(option, plaintext)
×
141
      ret = ""
×
142

143
      value = Ops.get(Security.Settings, option, "")
×
144

145
      Builtins.y2milestone("Option: %1, value: %2", option, value)
×
146

147
      # handle the special cases at first
148
      if Builtins.contains(@configurable_options, option)
×
149
        ret = _("Configure")
×
150
      elsif ["1", "yes", true].include?(value)
×
151
        ret = _("Enabled")
×
152
      elsif ["0", "no", false].include?(value)
×
153
        ret = _("Disabled")
×
154
      else
×
155
        return @UNKNOWN_STATUS
×
156
      end
×
157

158
      return ret if plaintext
×
159

NEW
160
      Builtins.sformat("<A HREF=\"%1\">%2</A>", option, ret)
×
UNCOV
161
    end
×
162

163
    def OverviewText(type)
×
164
      ret = ""
×
165
      ret_table = []
×
166

167
      if type == :richtext
×
168
        # open a table
169
        ret = Builtins.sformat(
×
NEW
170
          "<TABLE><TR> <TD><BIG><B>%1</B></BIG></TD>\n" \
×
NEW
171
          "<TD ALIGN=center><BIG><B>&nbsp;&nbsp;&nbsp;&nbsp;%2" \
×
NEW
172
          "&nbsp;&nbsp;&nbsp;&nbsp;</B></BIG></TD>\n" \
×
NEW
173
          "<TD ALIGN=center><BIG><B>&nbsp;&nbsp;&nbsp;&nbsp;%3" \
×
NEW
174
          "&nbsp;&nbsp;&nbsp;&nbsp;</B></BIG></TD>\n" \
×
NEW
175
          "<TD></TD>\n" \
×
NEW
176
          "</TR> <TR></TR>",
×
177
          # table header
178
          _("Security Setting"),
×
179
          _("Status"),
×
180
          _("Security Status")
×
181
        )
×
182
      end
×
183

184
      security_mapping = [
×
185
        {
×
186
          "id"        => "kernel.sysrq",
×
187
          "is_secure" => Ops.get(Security.Settings, "kernel.sysrq", "0") == "0"
×
188
        },
×
189
        {
×
190
          "id"        => "PERMISSION_SECURITY",
×
191
          "is_secure" => Ops.get(Security.Settings, "PERMISSION_SECURITY", "") == "secure" ||
×
192
            Ops.get(Security.Settings, "PERMISSION_SECURITY", "") == "paranoid"
×
193
        },
×
194
        {
×
195
          "id"        => "DISPLAYMANAGER_REMOTE_ACCESS",
×
196
          "is_secure" => Ops.get(
×
197
            Security.Settings,
×
198
            "DISPLAYMANAGER_REMOTE_ACCESS",
×
199
            ""
×
200
          ) == "no"
×
201
        },
×
202
        {
×
203
          "id"        => "SYSLOG_ON_NO_ERROR",
×
204
          "is_secure" => Ops.get(Security.Settings, "SYSLOG_ON_NO_ERROR", "") == "yes"
×
205
        },
×
206
        {
×
207
          "id"        => "DHCPD_RUN_CHROOTED",
×
208
          "is_secure" => Ops.get(Security.Settings, "DHCPD_RUN_CHROOTED", "") == "yes"
×
209
        },
×
210
        {
×
211
          "id"        => "DHCPD_RUN_AS",
×
212
          "is_secure" => Ops.get(Security.Settings, "DHCPD_RUN_AS", "") == "dhcp"
×
213
        },
×
214
        {
×
215
          "id"        => "DISPLAYMANAGER_ROOT_LOGIN_REMOTE",
×
216
          "is_secure" => Ops.get(
×
217
            Security.Settings,
×
218
            "DISPLAYMANAGER_ROOT_LOGIN_REMOTE",
×
219
            ""
×
220
          ) == "no"
×
221
        },
×
222
        {
×
223
          "id"        => "DISPLAYMANAGER_XSERVER_TCP_PORT_6000_OPEN",
×
224
          "is_secure" => Ops.get(
×
225
            Security.Settings,
×
226
            "DISPLAYMANAGER_XSERVER_TCP_PORT_6000_OPEN",
×
227
            ""
×
228
          ) == "no"
×
229
        },
×
230
        {
×
231
          "id"        => "SMTPD_LISTEN_REMOTE",
×
232
          "is_secure" => Ops.get(Security.Settings, "SMTPD_LISTEN_REMOTE", "") == "no"
×
233
        },
×
234
        {
×
235
          "id"        => "DISABLE_RESTART_ON_UPDATE",
×
236
          "is_secure" => Ops.get(
×
237
            Security.Settings,
×
238
            "DISABLE_RESTART_ON_UPDATE",
×
239
            ""
×
240
          ) == "no"
×
241
        },
×
242
        {
×
243
          "id"        => "DISABLE_STOP_ON_REMOVAL",
×
244
          "is_secure" => Ops.get(
×
245
            Security.Settings,
×
246
            "DISABLE_STOP_ON_REMOVAL",
×
247
            ""
×
248
          ) == "no"
×
249
        },
×
250
        {
×
251
          "id"        => "net.ipv4.tcp_syncookies",
×
NEW
252
          "is_secure" => Security.Settings["net.ipv4.tcp_syncookies"]
×
253
        },
×
254
        {
×
255
          "id"        => "net.ipv4.ip_forward",
×
256
          "is_secure" => !Security.Settings["net.ipv4.ip_forward"]
×
257
        },
×
258
        {
×
259
          "id"        => "net.ipv6.conf.all.forwarding",
×
260
          "is_secure" => !Security.Settings["net.ipv6.conf.all.forwarding"]
×
261
        },
×
262
        {
×
263
          "id"        => "MANDATORY_SERVICES",
×
264
          "is_secure" => Security.Settings["MANDATORY_SERVICES"] == "secure"
×
265
        },
×
266
        {
×
267
          "id"        => "EXTRA_SERVICES",
×
268
          "is_secure" => Security.Settings["EXTRA_SERVICES"] == "secure"
×
269
        }
×
270
      ]
×
271

272
      Builtins.foreach(security_mapping) do |setting|
×
273
        id = Ops.get_string(setting, "id", "")
×
NEW
274
        case type
×
NEW
275
        when :table
×
276
          ret_table = Builtins.add(
×
277
            ret_table,
×
278
            Item(
×
279
              Id(id),
×
280
              Ops.get(@label_mapping, id, ""),
×
281
              SecurityStatus(id, true),
×
282
              Ops.get_boolean(setting, "is_secure", false) ? "\u2714" : "\u2718"
×
283
            )
×
284
          )
×
NEW
285
        when :richtext
×
286
          # add one line for each security setting
287
          ret = Ops.add(
×
288
            ret,
×
289
            Builtins.sformat(
×
NEW
290
              "<TR><TD>%1&nbsp;&nbsp;&nbsp;&nbsp;</TD>" \
×
NEW
291
              "<TD ALIGN=center>%2</TD>" \
×
NEW
292
              "<TD ALIGN=center>&nbsp;&nbsp;&nbsp;%3</TD><TD>%4</TD></TR>",
×
293
              Ops.get(@label_mapping, id, ""),
×
294
              SecurityStatus(id, false),
×
NEW
295
              if Ops.get_boolean(setting, "is_secure", false)
×
NEW
296
                "<SUP><FONT COLOR=green SIZE=20>\u2714</FONT></SUP>"
×
NEW
297
              else
×
NEW
298
                "<FONT COLOR=red SIZE=20><SUP>\u2718</SUP></FONT>"
×
NEW
299
              end,
×
NEW
300
              if Builtins.haskey(@help_mapping, id)
×
301
                Builtins.sformat(
×
302
                  "<A HREF=\"help_%1\">%2</A>&nbsp;&nbsp;<BR>",
×
303
                  id,
×
304
                  _("Help")
×
NEW
305
                )
×
NEW
306
              else
×
307
                ""
×
NEW
308
              end
×
309
            )
×
310
          )
×
311
        end
×
NEW
312
      end
×
313

NEW
314
      case type
×
NEW
315
      when :table
×
316
        Builtins.y2debug("Overview table: %1", ret_table)
×
317
        return deep_copy(ret_table)
×
NEW
318
      when :richtext
×
319
        # close the table
320
        ret = Ops.add(ret, "</TABLE>")
×
321

322
        Builtins.y2debug("Overview text: %1", ret)
×
323
        return ret
×
324
      end
×
325

326
      Builtins.y2error("Unknown type: %1", type)
×
327

328
      nil
×
329
    end
×
330

331
    def DisplayHelpPopup(help_id)
×
332
      help = Ops.get(@help_mapping, help_id, "")
×
333

334
      # add the warning if the option is unknown
335
      if SecurityStatus(help_id, true) == @UNKNOWN_STATUS
×
336
        help = Ops.add(help, Ops.get_string(@HELPS, "unknown_status", ""))
×
337
      end
×
338

339
      # add extra help to service related options
NEW
340
      case help_id
×
NEW
341
      when "MANDATORY_SERVICES"
×
UNCOV
342
        missing = Security.MissingMandatoryServices
×
343

NEW
344
        if !missing.nil? && missing != []
×
345
          srvs = ""
×
346

347
          Builtins.foreach(missing) do |l|
×
348
            # this is a separator between service names
349
            # e.g.: "postfix" + " or " + "sendmail"
350
            group = Builtins.mergestring(l, _(" or "))
×
351
            srvs = Ops.add(Ops.add(srvs, group), "<BR>")
×
352
          end
×
353

354
          # richtext message: %1 = runlevel ("3" or "5"), %2 = list of services
355
          help +=
×
356
            _("<P>These basic system services are not enabled:<BR><B>%s</B></P>") % srvs
×
357
        else
×
358
          help += _("<P>All basic services are enabled.</P>")
×
359
        end
×
NEW
360
      when "EXTRA_SERVICES"
×
361
        extra = Security.ExtraServices
×
362

NEW
363
        if !extra.nil? && extra != []
×
364
          srvs = Builtins.mergestring(extra, "<BR>")
×
365
          help +=
×
366
            _("<P>These extra services are enabled:<BR><B>%s</B></P>") % srvs
×
367
          help += _("<P>Check the list of services and disable all unused services.</P>")
×
368
        else
×
369
          help += _("<P>Only basic system services are enabled.</P>")
×
370
        end
×
371
      end
×
372

NEW
373
      if !help.nil? && help != ""
×
374
        Popup.LongText(
×
375
          Ops.get(@label_mapping, help_id, _("Description")),
×
376
          RichText(help),
×
377
          70,
×
378
          15
×
379
        )
×
380
      end
×
381

382
      nil
×
383
    end
×
384

385
    def OverviewDialog
×
386
      # Overview dialog caption
387
      caption = _("Security Overview")
×
388
      help = Ops.get_string(@HELPS, "overview", "")
×
389
      no_richtext = !Ops.get_boolean(
×
390
        UI.GetDisplayInfo,
×
391
        "RichTextSupportsTable",
×
392
        true
×
393
      )
×
394

395
      # table header
396
      tabheader = Header(
×
397
        _("Security Setting"),
×
398
        _("Status"),
×
399
        Center(_("Security Status"))
×
400
      )
×
NEW
401
      contents = if no_richtext
×
NEW
402
        Table(Id(:table), Opt(:immediate), tabheader, OverviewText(:table))
×
NEW
403
      else
×
UNCOV
404
        RichText(Id(:rtext), OverviewText(:richtext))
×
NEW
405
      end
×
406

407
      if no_richtext
×
408
        # add a button box below the table
409
        contents = VBox(
×
410
          contents,
×
411
          VSpacing(1),
×
412
          HBox(
×
413
            # push button label
414
            PushButton(Id(:change), _("Change &Status")),
×
415
            HSpacing(2),
×
416
            # push button label
417
            PushButton(Id(:descr), _("&Description"))
×
418
          ),
×
419
          VSpacing(1)
×
420
        )
×
421
      end
×
422

423
      Wizard.SetContentsButtons(
×
424
        caption,
×
425
        contents,
×
426
        help,
×
427
        Label.BackButton,
×
428
        Label.OKButton
×
429
      )
×
430

431
      Wizard.HideBackButton
×
432
      Wizard.SetAbortButton(:abort, Label.CancelButton)
×
433

434
      # select the dialog in the tree navigation
435
      Wizard.SelectTreeItem("overview")
×
436

437
      ret = nil
×
NEW
438
      loop do
×
439
        ret = UI.UserInput
×
440

441
        # abort?
NEW
442
        if [:abort, :cancel].include?(ret)
×
NEW
443
          ReallyAbort() ? break : next
×
444
        elsif ret == :back || ret == :next ||
×
445
            Builtins.contains(@tree_dialogs, ret)
×
446
          # the current item has been selected, do not change to the same dialog
447
          if ret == "overview"
×
448
            # preselect the item if it has been unselected
NEW
449
            Wizard.SelectTreeItem("overview") if Wizard.QueryTreeItem != "overview"
×
450

451
            next
×
452
          end
×
453

454
          break
×
455
        # user clicked a link in the richtext
NEW
456
        elsif (Ops.is_string?(ret) && Builtins.haskey(Security.Settings, ret)) ||
×
457
            ret == :change
×
458
          if ret == :change
×
459
            # query the table in textmode
460
            ret = Convert.to_string(UI.QueryWidget(Id(:table), :CurrentItem))
×
461
          end
×
462

463
          Builtins.y2milestone("Clicked %1 link", ret)
×
464

465
          current_value = Ops.get(Security.Settings, Convert.to_string(ret), "")
×
466
          new_value = @link_value_mapping[current_value]
×
467

468
          # set the new value and refresh the overview
469
          if Builtins.haskey(@link_value_mapping, current_value) &&
×
470
              new_value != current_value
×
471
            Builtins.y2milestone("New value for %1: %2", ret, new_value)
×
472
            Ops.set(Security.Settings, Convert.to_string(ret), new_value)
×
473
            # the config has been changed
474
            Security.SetModified
×
475

476
            if no_richtext
×
477
              UI.ChangeWidget(Id(:table), :Items, OverviewText(:table))
×
478
              UI.ChangeWidget(Id(:table), :CurrentItem, ret)
×
479
              UI.SetFocus(Id(:table))
×
480
            else
×
481
              UI.ChangeWidget(Id(:rtext), :Value, OverviewText(:richtext))
×
482
            end
×
483
          elsif Builtins.haskey(@link_config_mapping, ret)
×
484
            new_dialog = Ops.get_string(@link_config_mapping, ret, "")
×
485

486
            Builtins.y2milestone("Switching to dialog %1", new_dialog)
×
487
            return new_dialog
×
488
          elsif Builtins.haskey(@link_client_mapping, ret)
×
489
            client = Ops.get_string(@link_client_mapping, ret, "")
×
490

491
            if client != ""
×
492
              Builtins.y2milestone("Calling Yast client %1", client)
×
493
              client_ret = WFM.CallFunction(client, [])
×
494
              Builtins.y2milestone("Client returned %1", client_ret)
×
495

NEW
496
              if [:next, :ok, :finish, true].include?(client_ret)
×
497
                # update the current value
NEW
498
                if @link_update_mapping.key?(ret)
×
499
                  Popup.Feedback(_("Analyzing system"), Message.takes_a_while) do
×
500
                    @link_update_mapping[ret].call
×
501
                  end
×
502
                end
×
503

504
                # update the overview
505
                if no_richtext
×
506
                  UI.ChangeWidget(Id(:table), :Items, OverviewText(:table))
×
507
                  UI.ChangeWidget(Id(:table), :CurrentItem, ret)
×
508
                  UI.SetFocus(Id(:table))
×
509
                else
×
510
                  UI.ChangeWidget(Id(:rtext), :Value, OverviewText(:richtext))
×
511
                end
×
512
              end
×
513
            end
×
514
          else
×
515
            Builtins.y2error("Unknown action for link %1", ret)
×
516
          end
×
NEW
517
        elsif (Ops.is_string?(ret) &&
×
NEW
518
            Builtins.regexpmatch(Convert.to_string(ret), "^help_")) ||
×
519
            ret == :descr
×
NEW
520
          help_id = if no_richtext
×
NEW
521
            Convert.to_string(UI.QueryWidget(Id(:table), :CurrentItem))
×
NEW
522
          else
×
523
            Builtins.regexpsub(Convert.to_string(ret), "^help_(.*)", "\\1")
×
NEW
524
          end
×
UNCOV
525
          Builtins.y2milestone("Clicked help link: %1", help_id)
×
526

527
          DisplayHelpPopup(help_id)
×
528

529
          # switch the focus back to the table in text/GTK UI
530
          UI.SetFocus(Id(:table)) if no_richtext
×
531
        elsif ret == :table
×
532
          # disable "Change Status" button if the action is unknown
533
          current_item = Convert.to_string(
×
534
            UI.QueryWidget(Id(:table), :CurrentItem)
×
535
          )
×
536
          status = SecurityStatus(
×
537
            current_item, # plaintext
×
538
            true
×
539
          )
×
540

541
          UI.ChangeWidget(Id(:change), :Enabled, status != @UNKNOWN_STATUS)
×
542
        else
×
543
          Builtins.y2error("Unexpected return code: %1", ret)
×
544
          next
×
545
        end
×
546
      end
×
547

548
      deep_copy(ret)
×
549
    end
×
550

551
    def vbox_boot_permissions
×
552
      display_manager_widget = Empty()
×
553
      if @display_manager && !@display_manager.shutdown_var_name.empty?
×
554
        display_manager_widget = VBox(
×
555
          VSpacing(1.0),
×
556
          settings2widget(@display_manager.shutdown_var_name)
×
557
        )
×
558
      end
×
559

560
      VBox(
×
561
        VSpacing(1),
×
562
        settings2widget("CONSOLE_SHUTDOWN"),
×
563
        display_manager_widget,
×
564
        VSpacing(1.0),
×
565
        settings2widget("HIBERNATE_SYSTEM"),
×
566
        VSpacing(1)
×
567
      )
×
568
    end
×
569

570
    # Boot dialog
571
    # @return dialog result
572
    def BootDialog
×
573
      # Boot dialog caption
574
      caption = _("Boot Settings")
×
575
      help = Ops.get_string(@HELPS, "boot", "")
×
576

577
      # Boot dialog contents
578
      contents = HVCenter(
×
579
        HVSquash(
×
580
          HBox(
×
581
            HSpacing(5),
×
582
            VBox(
×
583
              VSpacing(2),
×
584
              # Frame label
585
              Frame(
×
586
                _("Boot Permissions"),
×
587
                HBox(
×
588
                  HSpacing(3),
×
589
                  vbox_boot_permissions,
×
590
                  HSpacing(3)
×
591
                )
×
592
              ),
×
593
              VSpacing(2)
×
594
            ),
×
595
            HSpacing(5)
×
596
          )
×
597
        )
×
598
      )
×
599

600
      Wizard.SetContentsButtons(
×
601
        caption,
×
602
        contents,
×
603
        help,
×
604
        Label.BackButton,
×
605
        Label.OKButton
×
606
      )
×
607

608
      Wizard.HideBackButton
×
609
      Wizard.SetAbortButton(:abort, Label.CancelButton)
×
610

611
      # select the dialog in the tree navigation
612
      Wizard.SelectTreeItem("boot")
×
613

614
      ret = nil
×
NEW
615
      loop do
×
616
        ret = UI.UserInput
×
617

618
        # abort?
NEW
619
        if [:abort, :cancel].include?(ret)
×
NEW
620
          ReallyAbort() ? break : next
×
621
        elsif ret == :back || ret == :next ||
×
622
            Builtins.contains(@tree_dialogs, ret)
×
623
          # the current item has been selected, do not change to the same dialog
624
          if ret == "boot"
×
625
            # preselect the item if it has been unselected
626
            Wizard.SelectTreeItem("boot") if Wizard.QueryTreeItem != "boot"
×
627

628
            next
×
629
          end
×
630

631
          break
×
632
        else
×
633
          Builtins.y2error("Unexpected return code: %1", ret)
×
634
          next
×
635
        end
×
636
      end
×
637

638
      if ret == :next || Builtins.contains(@tree_dialogs, ret)
×
639
        widget2settings("CONSOLE_SHUTDOWN")
×
640
        if @display_manager && !@display_manager.shutdown_var_name.empty?
×
641
          widget2settings(@display_manager.shutdown_var_name)
×
642
        end
×
643
        widget2settings("HIBERNATE_SYSTEM")
×
644
      end
×
645

646
      deep_copy(ret)
×
647
    end
×
648

649
    # Misc dialog
650
    # @return dialog result
651
    def MiscDialog
×
652
      # Misc dialog caption
653
      caption = _("Miscellaneous Settings")
×
654
      help = Ops.get_string(@HELPS, "misc", "")
×
655

656
      # Misc dialog contents
657
      contents = VBox(
×
658
        VSeparator(),
×
659
        settings2widget("PERMISSION_SECURITY"),
×
660
        VSpacing(1.0),
×
661
        settings2widget("RUN_UPDATEDB_AS"),
×
662
        VSpacing(1.0),
×
663
        settings2widget("kernel.sysrq"),
×
664
        VSpacing(1.8)
×
665
      )
×
666
      contents = HVCenter(
×
667
        HVSquash(
×
668
          HBox(
×
669
            HSpacing(5),
×
670
            VBox(VSpacing(2), ReplacePoint(Id(:rp_main), contents), VSpacing(2)),
×
671
            HSpacing(5)
×
672
          )
×
673
        )
×
674
      )
×
675

676
      Wizard.SetContentsButtons(
×
677
        caption,
×
678
        contents,
×
679
        help,
×
680
        Label.BackButton,
×
681
        Label.OKButton
×
682
      )
×
683

684
      Wizard.HideBackButton
×
685
      Wizard.SetAbortButton(:abort, Label.CancelButton)
×
686

687
      # select the dialog in the tree navigation
688
      Wizard.SelectTreeItem("misc")
×
689

690
      ret = nil
×
NEW
691
      loop do
×
692
        ret = UI.UserInput
×
693

694
        # abort?
NEW
695
        if [:abort, :cancel].include?(ret)
×
NEW
696
          ReallyAbort() ? break : next
×
697
        elsif ret == :back
×
698
          break
×
699
        elsif ret == :next || Builtins.contains(@tree_dialogs, ret)
×
700
          # the current item has been selected, do not change to the same dialog
701
          if ret == "misc"
×
702
            # preselect the item if it has been unselected
703
            Wizard.SelectTreeItem("misc") if Wizard.QueryTreeItem != "misc"
×
704

705
            next
×
706
          end
×
707

708
          # check_*
709
          break
×
710
        else
×
711
          Builtins.y2error("Unexpected return code: %1", ret)
×
712
          next
×
713
        end
×
714
      end
×
715

716
      if ret == :next || Builtins.contains(@tree_dialogs, ret)
×
717
        widget2settings("PERMISSION_SECURITY")
×
718
        widget2settings("RUN_UPDATEDB_AS")
×
719
        widget2settings("kernel.sysrq")
×
720
      end
×
721

722
      deep_copy(ret)
×
723
    end
×
724

725
    # Password dialog
726
    # @return dialog result
727
    def PassDialog
×
728
      # Password dialog caption
729
      caption = _("Password Settings")
×
730
      help = Ops.get_string(@HELPS, "password", "")
×
731

732
      # Password dialog contents
733
      contents = VBox(
×
734
        # Frame label
735
        XFrame(
×
736
          0.3,
×
737
          0.15,
×
738
          _("Checks"),
×
739
          VBox(
×
740
            settings2widget("PASSWD_USE_PWQUALITY"),
×
741
            VSeparator(),
×
742
            settings2widget("PASS_MIN_LEN"),
×
743
            VSeparator(),
×
744
            settings2widget("PASSWD_REMEMBER_HISTORY"),
×
745
            VSeparator()
×
746
          )
×
747
        ),
×
748
        VSpacing(0.4),
×
749
        settings2widget("PASSWD_ENCRYPTION"),
×
750
        VSpacing(0.4),
×
751
        # Frame label
752
        Frame(
×
753
          _("Password Age"),
×
754
          HBox(
×
755
            HSpacing(0.4),
×
756
            settings2widget("PASS_MIN_DAYS"),
×
757
            HSpacing(0.4),
×
758
            settings2widget("PASS_MAX_DAYS"),
×
759
            HSpacing(0.4)
×
760
          )
×
761
        ),
×
762
        VSpacing(0.15),
×
763
        settings2widget("PASS_WARN_AGE"),
×
764
        VSpacing(0.0)
×
765
      )
×
766
      contents = HVCenter(
×
767
        HVSquash(
×
768
          HBox(
×
769
            HSpacing(5),
×
770
            VBox(VSpacing(2), ReplacePoint(Id(:rp_main), contents), VSpacing(2)),
×
771
            HSpacing(5)
×
772
          )
×
773
        )
×
774
      )
×
775

776
      Wizard.SetContentsButtons(
×
777
        caption,
×
778
        contents,
×
779
        help,
×
780
        Label.BackButton,
×
781
        Label.OKButton
×
782
      )
×
783

784
      Wizard.HideBackButton
×
785
      Wizard.SetAbortButton(:abort, Label.CancelButton)
×
786

787
      # select the dialog in the tree navigation
788
      Wizard.SelectTreeItem("password")
×
789

790
      UI.ChangeWidget(
×
791
        Id("PASS_MIN_LEN"),
×
792
        :Enabled,
×
793
        Ops.get(Security.Settings, "PASSWD_USE_PWQUALITY", "") == "yes"
×
794
      )
×
795

796
      ret = nil
×
NEW
797
      loop do
×
798
        ret = UI.UserInput
×
799

800
        # abort?
NEW
801
        if [:abort, :cancel].include?(ret)
×
NEW
802
          ReallyAbort() ? break : next
×
803
        elsif ret == :back
×
804
          break
×
805
        elsif ret == "PASSWD_USE_PWQUALITY"
×
806
          # minlen is an option for pam_pwquality
807
          UI.ChangeWidget(
×
808
            Id("PASS_MIN_LEN"),
×
809
            :Enabled,
×
810
            UI.QueryWidget(Id(ret), :Value) == true
×
811
          )
×
812
        elsif ret == :next || Builtins.contains(@tree_dialogs, ret)
×
813
          # the current item has been selected, do not change to the same dialog
814
          if ret == "password"
×
815
            # preselect the item if it has been unselected
NEW
816
            Wizard.SelectTreeItem("password") if Wizard.QueryTreeItem != "password"
×
817

818
            next
×
819
          end
×
820

821
          # check_*
822
          if checkMinMax("PASS_MIN_DAYS", "PASS_MAX_DAYS") != true
×
823
            # Popup text
824
            Popup.Error(
×
825
              _(
×
826
                "The minimum number of days cannot be larger\nthan the maximum."
×
827
              )
×
828
            )
×
829
            next
×
830
          end
×
831
          enc = Convert.to_string(
×
832
            UI.QueryWidget(Id("PASSWD_ENCRYPTION"), :Value)
×
833
          )
×
834
          min = Convert.to_integer(UI.QueryWidget(Id("PASS_MIN_LEN"), :Value))
×
835
          if Ops.greater_than(
×
NEW
836
            min,
×
NEW
837
            Ops.get_integer(Security.PasswordMaxLengths, enc, 8)
×
NEW
838
          )
×
839
            # Popup text, %1 is number
840
            Popup.Error(
×
841
              Builtins.sformat(
×
842
                _(
×
NEW
843
                  "The minimum password length cannot be larger than the maximum.\n" \
×
NEW
844
                  "The maximum password length for the selected encryption method is %1."
×
845
                ),
×
846
                Ops.get_integer(Security.PasswordMaxLengths, enc, 8)
×
847
              )
×
848
            )
×
849
            next
×
850
          end
×
851
          break
×
852
        elsif ret != "PASSWD_ENCRYPTION"
×
853
          Builtins.y2error("Unexpected return code: %1", ret)
×
854
          next
×
855
        end
×
856
      end
×
857

858
      if ret == :next || Builtins.contains(@tree_dialogs, ret)
×
859
        widget2settings("PASS_MIN_DAYS")
×
860
        widget2settings("PASS_MAX_DAYS")
×
861
        widget2settings("PASS_MIN_LEN")
×
862
        widget2settings("PASSWD_USE_PWQUALITY")
×
863
        widget2settings("PASS_WARN_AGE")
×
864
        widget2settings("PASSWD_ENCRYPTION")
×
865
        widget2settings("PASSWD_REMEMBER_HISTORY")
×
866
      end
×
867

868
      deep_copy(ret)
×
869
    end
×
870

871
    # Login dialog
872
    # @return dialog result
873
    def LoginDialog
×
874
      # Login dialog caption
875
      caption = _("Login Settings")
×
876
      help = Ops.get_string(@HELPS, "login", "")
×
877

878
      # Login dialog contents
879
      contents = VBox(
×
880
        # Frame label
881
        XFrame(
×
882
          3.0,
×
883
          1.0,
×
884
          _("Login"),
×
885
          VBox(
×
886
            # VSeparator(),
NEW
887
            settings2widget("FAIL_DELAY"), # VSeparator()
×
888
            # VSeparator(),
889
            VSpacing(0.5),
×
890
            VSeparator(),
×
891
            settings2widget("DISPLAYMANAGER_REMOTE_ACCESS")
×
892
          )
×
NEW
893
        ) # ,`VSpacing(1.7)
×
894
      )
×
895
      contents = HVCenter(
×
896
        HVSquash(
×
897
          HBox(
×
898
            HSpacing(5),
×
899
            VBox(VSpacing(2), ReplacePoint(Id(:rp_main), contents), VSpacing(2)),
×
900
            HSpacing(5)
×
901
          )
×
902
        )
×
903
      )
×
904

905
      Wizard.SetContentsButtons(
×
906
        caption,
×
907
        contents,
×
908
        help,
×
909
        Label.BackButton,
×
910
        Label.OKButton
×
911
      )
×
912

913
      Wizard.HideBackButton
×
914
      Wizard.SetAbortButton(:abort, Label.CancelButton)
×
915

916
      # select the dialog in the tree navigation
917
      Wizard.SelectTreeItem("login")
×
918

919
      ret = nil
×
NEW
920
      loop do
×
921
        ret = UI.UserInput
×
922

923
        # abort?
NEW
924
        if [:abort, :cancel].include?(ret)
×
NEW
925
          ReallyAbort() ? break : next
×
926
        elsif ret == :back
×
927
          break
×
928
        elsif ret == :next || Builtins.contains(@tree_dialogs, ret)
×
929
          # the current item has been selected, do not change to the same dialog
930
          if ret == "login"
×
931
            # preselect the item if it has been unselected
932
            Wizard.SelectTreeItem("login") if Wizard.QueryTreeItem != "login"
×
933

934
            next
×
935
          end
×
936

937
          # check_*
938
          break
×
939
        else
×
940
          Builtins.y2error("Unexpected return code: %1", ret)
×
941
          next
×
942
        end
×
943
      end
×
944

945
      if ret == :next || Builtins.contains(@tree_dialogs, ret)
×
946
        widget2settings("FAIL_DELAY")
×
947
        widget2settings("DISPLAYMANAGER_REMOTE_ACCESS")
×
948
      end
×
949

950
      deep_copy(ret)
×
951
    end
×
952
  end
×
953
end
×
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc