Class: Yast::AuditLafClass

Inherits:
Module
  • Object
show all
Defined in:
../../src/modules/AuditLaf.rb

Instance Method Summary (collapse)

Instance Method Details

- (Object) Abort

Returns a confirmation popup dialog whether user wants to really abort.



190
191
192
# File '../../src/modules/AuditLaf.rb', line 190

def Abort
  Popup.ReallyAbort(Modified())
end

- (Object) AuditStatus



222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
# File '../../src/modules/AuditLaf.rb', line 222

def AuditStatus
  output = Convert.to_map(
    SCR.Execute(path(".target.bash_output"), "LANG=POSIX auditctl -s")
  )
  Builtins.y2milestone("auditctl: %1", output)

  audit_status = Ops.get_string(output, "stdout", "")

  if Builtins.regexpmatch(audit_status, "^.*enabled=2.*")
    return _("The rules for auditctl are locked.")
  elsif Builtins.regexpmatch(audit_status, "^.*enabled=1.*")
    return _("Auditing enabled")
  else
    return _("Auditing disabled")
  end
end

- (Hash) AutoPackages

Return packages needed to be installed and removed during Autoinstallation to insure module has all needed software installed.

Returns:

  • (Hash)

    with 2 lists.



725
726
727
# File '../../src/modules/AuditLaf.rb', line 725

def AutoPackages
  { "install" => ["audit"], "remove" => [] }
end

- (Object) CheckAuditdStatus



352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
# File '../../src/modules/AuditLaf.rb', line 352

def CheckAuditdStatus
  auditd_active = Service.active?("auditd")

  if !auditd_active
    Report.Error(
      _(
        "Cannot start the audit daemon.\n" +
          "Please check /var/log/messages for auditd errors.\n" +
          "You can use the module 'System Log' from group\n" +
          "'Miscellaneous' in YaST Control Center."
      )
    )
    return false
  else
    return true
  end
end

- (Object) CheckInstalledPackages

Check whether package 'audit' is installed and install it if user agrees



309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
# File '../../src/modules/AuditLaf.rb', line 309

def CheckInstalledPackages
  ret = false

  # skip it during initial and second stage or when create AY profile
  return true if Stage.cont || Stage.initial || Mode.config
  Builtins.y2milestone("Check whether package 'audit' is installed")

  if !Package.InstallMsg(
      "audit",
      _(
        "<p>To continue the configuration of Linux Auditing, the package <b>%1</b> must be installed.</p>"
      ) +
        _("<p>Install it now?</p>")
    )
    Popup.Error(Message.CannotContinueWithoutPackagesInstalled)
  else
    ret = true
  end
  ret
end

- (Hash) Export

Dump the auditd settings and the rules to a single map (For use by autoinstallation.)

Returns:

  • (Hash)

    Dumped settings (later acceptable by Import ())



693
694
695
# File '../../src/modules/AuditLaf.rb', line 693

def Export
  { "auditd" => @SETTINGS, "rules" => @RULES }
end

- (Object) GetAuditdOption(key)

Get value of given option from SEETINGS



251
252
253
# File '../../src/modules/AuditLaf.rb', line 251

def GetAuditdOption(key)
  Ops.get(@SETTINGS, key, Ops.get(@DEFAULT_CONFIG, key, ""))
end

- (Object) GetConfigFile



139
140
141
# File '../../src/modules/AuditLaf.rb', line 139

def GetConfigFile
  @config_file
end

- (Object) GetInitialRules



273
274
275
# File '../../src/modules/AuditLaf.rb', line 273

def GetInitialRules
  @INITIAL_RULES
end

- (Object) GetRules

Get the current rules



269
270
271
# File '../../src/modules/AuditLaf.rb', line 269

def GetRules
  @RULES
end

- (Object) GetRulesFile

Return rules file path



135
136
137
# File '../../src/modules/AuditLaf.rb', line 135

def GetRulesFile
  @rules_file
end

- (Object) GetWatches

Testing only



144
145
146
147
148
149
# File '../../src/modules/AuditLaf.rb', line 144

def GetWatches
  [
    "exit,always watch=/etc/passwd perm=rwx",
    "entry,always watch=/etc/sysconfig/yast2 perm=rwx"
  ]
end

- (Boolean) Import(settings)

Get all audit settings from the first parameter (For use by autoinstallation.)

Parameters:

  • settings (Hash)

    The YCP structure to be imported.

Returns:

  • (Boolean)

    True on success



675
676
677
678
679
680
681
682
683
684
685
686
687
688
# File '../../src/modules/AuditLaf.rb', line 675

def Import(settings)
  settings = deep_copy(settings)
  @SETTINGS = Convert.convert(
    Ops.get(settings, "auditd", @DEFAULT_CONFIG),
    :from => "any",
    :to   => "map <string, string>"
  )
  @RULES = Ops.get_string(settings, "rules", "")

  SetModified(true)
  Builtins.y2milestone("Configuration has been imported")

  true
end

- (Object) main



34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
# File '../../src/modules/AuditLaf.rb', line 34

def main
  Yast.import "UI"
  textdomain "audit-laf"

  Yast.import "Progress"
  Yast.import "Report"
  Yast.import "Summary"
  Yast.import "Message"
  Yast.import "Popup"
  Yast.import "Mode"
  Yast.import "FileUtils"
  Yast.import "Service"
  Yast.import "Stage"
  Yast.import "Package"


  # Data was modified?
  @modified = false


  @proposal_valid = false

  # Filename (path) rules file
  @rules_file = "/etc/audit/audit.rules"

  # Filename (path) config file
  @config_file = "/etc/audit/auditd.conf"

  # Write only, used during autoinstallation.
  # Don't run services and SuSEconfig, it's all done at one place.
  @write_only = false

  # Option "Lock rules" is set (-e 2)
  @rules_locked = false

  # The rules have been changed (sent to 'autitctl' to check the syntax)
  @rules_changed = false

  #
  # Settings: Define all variables needed for the configuration of the audit daemon
  #

  # map of audit settings (from /etc/audit/auditd.conf)
  @SETTINGS = {}

  # default settings for /etc/audit/auditd.conf
  @DEFAULT_CONFIG = {
    "log_file"                => "/var/log/audit/audit.log",
    "log_format"              => "RAW",
    "priority_boost"          => "3",
    "flush"                   => "INCREMENTAL",
    "freq"                    => "20",
    "num_logs"                => "4",
    "dispatcher"              => "/sbin/audispd",
    "disp_qos"                => "lossy",
    "name_format"             => "NONE",
    "max_log_file"            => "5",
    "max_log_file_action"     => "ROTATE",
    "space_left"              => "75",
    "space_left_action"       => "SYSLOG",
    "action_mail_acct"        => "root",
    "admin_space_left"        => "50",
    "admin_space_left_action" => "SUSPEND",
    "disk_full_action"        => "SUSPEND",
    "disk_error_action"       => "SUSPEND"
  }

  # Save settings initially read from /etc/audit/auditd.conf to be able
  # to decide whether changes are made
  @INITIAL_SETTINGS = {}

  # Rules for the subsystem audit (passed via auditctl).
  # Initially read from /etc/audit/audit.rules and edited in
  # the rules editor.
  @RULES = ""

  # Save rules from /etc/audit/audit.rules to be able to restore it
  @INITIAL_RULES = ""
end

- (Object) Modified

Data was modified?

Returns:

  • true if modified



153
154
155
156
# File '../../src/modules/AuditLaf.rb', line 153

def Modified
  Builtins.y2milestone("modified=%1", @modified)
  @modified
end

- (Object) Overview

Create an overview table with all configured cards

Returns:

  • table items



716
717
718
719
# File '../../src/modules/AuditLaf.rb', line 716

def Overview
  # TODO FIXME: your code here...
  []
end

- (Boolean) PollAbort

Checks whether an Abort button has been pressed. If so, calls function to confirm the abort call.

Returns:

  • (Boolean)

    true if abort confirmed



198
199
200
201
202
203
204
205
# File '../../src/modules/AuditLaf.rb', line 198

def PollAbort
  # Do not check UI when running in CommandLine mode
  return false if Mode.commandline

  return Abort() if UI.PollInput == :abort

  false
end

- (Object) ProposalValid



167
168
169
# File '../../src/modules/AuditLaf.rb', line 167

def ProposalValid
  @proposal_valid
end

- (Object) Read

Read all auditd settings

Returns:

  • true on success



372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
# File '../../src/modules/AuditLaf.rb', line 372

def Read
  success = true

  # AuditLaf read dialog caption
  caption = _("Initializing Audit Configuration")

  # Set the right number of stages
  steps = 4

  sl = 500
  Builtins.sleep(sl)

  # We do not set help text here, because it was set outside
  Progress.New(
    caption,
    " ",
    steps,
    [
      # Progress stage 1/4
      _("Check for installed packages"),
      # Progress stage 2/4
      _("Read the configuration of auditd"),
      # Progress stage 3/4
      _("Read the rules file"),
      # Progress stage 4/4
      _("Check status of auditd")
    ],
    [
      # Progress stage 1/4
      _("Checking for packages..."),
      # Progress step 2/4
      _("Reading the configuration..."),
      # Progress step 3/4
      _("Reading the rules file..."),
      # Progress step 4/4
      _("Checking status..."),
      Message.Finished
    ],
    ""
  )

  # read database
  return false if PollAbort()
  Progress.NextStage

  installed = CheckInstalledPackages()

  return false if !installed
  Builtins.sleep(sl)

  return false if PollAbort()
  Progress.NextStep

  success = ReadAuditdSettings()

  # Log the status of the audit system
  output = Convert.to_map(
    SCR.Execute(path(".target.bash_output"), "auditctl -s")
  )
  Builtins.y2milestone("auditctl: %1", output)

  # Report error
  Report.Error(_("Cannot read auditd.conf.")) if !success
  Builtins.sleep(sl)

  # read another database
  return false if PollAbort()
  Progress.NextStep

  success = ReadAuditRules()

  # Error message
  Report.Error(_("Cannot read audit.rules.")) if !success
  Builtins.sleep(sl)

  # read current settings
  return false if PollAbort()
  Progress.NextStage
  # Error message
  Report.Error(Message.CannotReadCurrentSettings) if false
  Builtins.sleep(sl)

  Progress.NextStage
  auditd_active = Service.active?("auditd")
  Builtins.y2milestone("Auditd running: %1", auditd_active)

  apparmor_active = Service.active?("apparmor")
  Builtins.y2milestone("Apparmor loaded: %1", apparmor_active)

  if !auditd_active
    # question shown in a popup about start of audit daemon
    start_question = _("Do you want to start it and enable start at boot\n" +
                       "or only start the daemon for now?")

    message = _("The daemon 'auditd' doesn't run.\n") + start_question

    if apparmor_active
      # message about loaded kernel module
      message = _(
                  "The 'apparmor' kernel module is loaded.\n" +
                  "The kernel uses a running audit daemon to log audit\n" +
                  "events to /var/log/audit/audit.log (default).\n") +
        start_question
    end
    # Headline of a popup
    enable = Popup.AnyQuestion3(_("Start of Audit Daemon"), message,
                                # label of three buttons belonging to the popup
                               _("Start and &Enable"), _("&Start"), _("&Do not start"),
                               :focus_yes)

    if enable == :yes || enable == :no
      success = Service.Start("auditd")
      Service.Enable("auditd") if enable == :yes

      if !success
        go_on = Popup.ContinueCancelHeadline(
          _("Cannot start the audit daemon."),
          _(
            "The rules may be locked.\n" +
              "Continue to check the rules. You can change\n" +
              "the 'Enabled Flag', but to activate the change\n" +
              "a reboot is required afterwards.\n"
          )
        )
        if go_on
          return true
        else
          return false
        end
      else
        CheckAuditdStatus()
        return true
      end
    end
  end

  return false if PollAbort()
  @modified = false
  true
end

- (Object) ReadAuditdSettings

Read settings from auditd.conf

Returns:

  • true on success



332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
# File '../../src/modules/AuditLaf.rb', line 332

def ReadAuditdSettings
  return false if !FileUtils.Exists(@config_file)

  optionsList = SCR.Dir(path(".auditd"))
  Builtins.y2milestone("List of options: %1", optionsList)

  # list all options set in auditd.conf
  Builtins.foreach(SCR.Dir(path(".auditd"))) do |key|
    # and read the value for each of them
    val = Convert.to_string(SCR.Read(Builtins.add(path(".auditd"), key)))
    Ops.set(@SETTINGS, key, val) if val != nil
  end

  # additionally save initial settings
  @INITIAL_SETTINGS = deep_copy(@SETTINGS)

  Builtins.y2milestone("%1 has been read: %2", @config_file, @SETTINGS)
  true
end

- (Object) ReadAuditRules

Read rules from audit.rules



288
289
290
291
292
293
294
295
296
297
298
299
# File '../../src/modules/AuditLaf.rb', line 288

def ReadAuditRules
  rules = Convert.to_string(SCR.Read(path(".target.string"), @rules_file))

  if rules != nil && rules != ""
    @RULES = rules
    # additionally save initial rules
    @INITIAL_RULES = rules
    return true
  else
    return false
  end
end

- (Object) RulesAlreadyLocked



207
208
209
210
211
212
213
214
215
216
217
218
219
220
# File '../../src/modules/AuditLaf.rb', line 207

def RulesAlreadyLocked
  output = Convert.to_map(
    SCR.Execute(path(".target.bash_output"), "LANG=POSIX auditctl -s")
  )
  Builtins.y2milestone("auditctl: %1", output)

  audit_status = Ops.get_string(output, "stdout", "")

  if Builtins.regexpmatch(audit_status, "^.*enabled=2.*")
    return true
  else
    return false
  end
end

- (Object) RulesChanged



130
131
132
# File '../../src/modules/AuditLaf.rb', line 130

def RulesChanged
  @rules_changed
end

- (Object) RulesLocked



120
121
122
# File '../../src/modules/AuditLaf.rb', line 120

def RulesLocked
  @rules_locked
end

- (Object) SetAuditdOption(key, value)

Set option to given value in SETTINGS



257
258
259
260
261
262
263
264
265
266
# File '../../src/modules/AuditLaf.rb', line 257

def SetAuditdOption(key, value)
  # Don't set empty values (seems that 'auditd' doesn't like it)
  if value != ""
    Ops.set(@SETTINGS, key, value)
    Builtins.y2milestone("Setting %1 to %2", key, value)
    return true
  else
    return false
  end
end

- (Object) SetDataModified

Set data modified only if really has changed



240
241
242
243
244
245
246
247
248
# File '../../src/modules/AuditLaf.rb', line 240

def SetDataModified
  if @INITIAL_SETTINGS != @SETTINGS || @INITIAL_RULES != @RULES
    @modified = true
  else
    @modified = false
  end

  nil
end

- (Object) SetModified(value)

Mark as modified, for Autoyast.



159
160
161
162
163
# File '../../src/modules/AuditLaf.rb', line 159

def SetModified(value)
  @modified = value

  nil
end

- (Object) SetProposalValid(value)



171
172
173
174
175
# File '../../src/modules/AuditLaf.rb', line 171

def SetProposalValid(value)
  @proposal_valid = value

  nil
end

- (Object) SetRules(rules)

Set rules



278
279
280
281
282
283
284
285
# File '../../src/modules/AuditLaf.rb', line 278

def SetRules(rules)
  if rules != nil && rules != ""
    @RULES = rules
    return true
  else
    return false
  end
end

- (Object) SetRulesChanged(value)



124
125
126
127
128
# File '../../src/modules/AuditLaf.rb', line 124

def SetRulesChanged(value)
  @rules_changed = value

  nil
end

- (Object) SetRulesLocked(value)



114
115
116
117
118
# File '../../src/modules/AuditLaf.rb', line 114

def SetRulesLocked(value)
  @rules_locked = value

  nil
end

- (Object) SetWriteOnly(value)

Set write_only flag (for autoinstalation).



183
184
185
186
187
# File '../../src/modules/AuditLaf.rb', line 183

def SetWriteOnly(value)
  @write_only = value

  nil
end

- (Object) Summary

Create a textual summary and a list of unconfigured cards

Returns:

  • summary of the current configuration



699
700
701
702
703
704
705
706
707
708
709
710
711
712
# File '../../src/modules/AuditLaf.rb', line 699

def Summary
  summary = ""

  summary = Summary.AddLine(
    summary,
    Builtins.sformat("%1: %2", _("Log file"), GetAuditdOption("log_file"))
  )
  summary = Summary.AddLine(summary, AuditStatus())

  Builtins.y2milestone("Summary: %1", summary)

  # Configuration summary text for autoyast
  summary
end

- (Object) Write

Write all auditd settings

Returns:

  • true on success



540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
# File '../../src/modules/AuditLaf.rb', line 540

def Write
  go_on = false
  ret = true

  # Auditd read dialog caption
  caption = _("Saving Audit Configuration")

  # set the right number of stages
  steps = 2

  sl = 500
  Builtins.sleep(sl)

  # Names of the stages
  # We do not set help text here, because it was set outside
  Progress.New(
    caption,
    " ",
    steps,
    [
      # Progress stage 1/2
      _("Write the settings"),
      # Progress stage 2/2
      _("Write the rules")
    ],
    [
      # Progress step 1/2
      _("Writing the settings..."),
      # Progress step 2/2
      _("Writing the rules..."),
      Message.Finished
    ],
    ""
  )

  # check first whether rules are already locked
  locked = RulesAlreadyLocked()

  Builtins.y2milestone(
    "Rules already locked: %1",
    locked ? "true" : "false"
  )

  if locked
    write_rules = Popup.YesNoHeadline(
      _("The rules are already locked."),
      _(
        "Do you want to change the 'Enabled Flag'?\n" +
          "If yes, the new rules will be written to /etc/audit/audit.rules.\n" +
          "Reboot the system afterwards for the change to take effect.\n"
      )
    )
    WriteAuditRules() if write_rules

    # don't try to restart the daemon - daemon will stop
    return false
  end

  # write settings
  return false if PollAbort()
  Progress.NextStage

  write_success = WriteAuditdSettings()

  if write_success
    # restart auditd
    success = Service.Restart("auditd")
    Builtins.y2milestone("'auditd restart' returned: %1", success)

    if !success
      # Error message
      Report.Error(_("Restart of the audit daemon failed."))
      ret = false
    else
      go_on = true
    end
  else
    # Error message
    Report.Error(_("Cannot write settings to auditd.conf."))
    ret = false
  end

  Builtins.sleep(sl)

  return false if PollAbort()

  Progress.NextStage

  if go_on
    write_success = WriteAuditRules()

    # Error message
    if write_success
      # call auditctl -R audit.rules
      Builtins.y2milestone("Calling auditctl -R /etc/audit/audit.rules")

      output = Convert.to_map(
        SCR.Execute(
          path(".target.bash_output"),
          "auditctl -R /etc/audit/audit.rules"
        )
      )

      if Ops.get_integer(output, "exit", 0) != 0
        Report.Error(
          Builtins.sformat(
            "%1\n%2",
            Ops.get_string(output, "stderr", ""),
            # Error message, rules cannot be set
            _("Start yast2-audit-laf again and check the rules.")
          )
        )
        ret = false
      end
    else
      Report.Error(_("Cannot write settings to auditd.rules."))
      ret = false
    end

    Builtins.sleep(sl)
  end

  # Finally check status of auditd (if restart has worked but daemon exited afterwards)
  ret = false if !CheckAuditdStatus()

  return false if PollAbort()

  Builtins.y2milestone("Auditd::Write() returns: %1", ret)
  ret
end

- (Object) WriteAuditdSettings

Write settings to auditd.conf

Returns:

  • true on success



515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
# File '../../src/modules/AuditLaf.rb', line 515

def WriteAuditdSettings
  ret = true

  return false if !FileUtils.Exists(@config_file)

  # write all options to auditd.conf
  Builtins.foreach(@SETTINGS) do |key, value|
    # and write each value
    success = SCR.Write(Builtins.add(path(".auditd"), key), value)
    ret = false if !success
  end

  # This is very important
  # it flushes the cache, and stores the configuration on the disk
  SCR.Write(path(".auditd"), nil)

  if ret
    Builtins.y2milestone("%1 has been written: %2", @config_file, @SETTINGS)
  end

  ret
end

- (Object) WriteAuditRules

Write rules to audit.rules



302
303
304
305
306
# File '../../src/modules/AuditLaf.rb', line 302

def WriteAuditRules
  success = SCR.Write(path(".target.string"), @rules_file, @RULES)

  success
end

- (Object) WriteOnly

Returns true if module is marked as “write only” (don't start services etc…)

Returns:

  • true if module is marked as “write only” (don't start services etc…)



178
179
180
# File '../../src/modules/AuditLaf.rb', line 178

def WriteOnly
  @write_only
end