github.com/meulengracht/snapd@v0.0.0-20210719210640-8bde69bcc84e/sandbox/selinux/selinux.go (about)

     1  // -*- Mode: Go; indent-tabs-mode: t -*-
     2  
     3  /*
     4   * Copyright (C) 2014-2018 Canonical Ltd
     5   *
     6   * This program is free software: you can redistribute it and/or modify
     7   * it under the terms of the GNU General Public License version 3 as
     8   * published by the Free Software Foundation.
     9   *
    10   * This program is distributed in the hope that it will be useful,
    11   * but WITHOUT ANY WARRANTY; without even the implied warranty of
    12   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    13   * GNU General Public License for more details.
    14   *
    15   * You should have received a copy of the GNU General Public License
    16   * along with this program.  If not, see <http://www.gnu.org/licenses/>.
    17   *
    18   */
    19  
    20  package selinux
    21  
    22  import (
    23  	"fmt"
    24  )
    25  
    26  // LevelType encodes the state of SELinux support found on this system.
    27  type LevelType int
    28  
    29  const (
    30  	// SELinux is not supported
    31  	Unsupported LevelType = iota
    32  	// SELinux is supported and in permissive mode
    33  	Permissive
    34  	// SELinux is supported and in enforcing mode
    35  	Enforcing
    36  )
    37  
    38  var (
    39  	selinuxIsEnabled   = IsEnabled
    40  	selinuxIsEnforcing = IsEnforcing
    41  )
    42  
    43  // ProbedLevel tells what level of SELinux enforcement is currently used
    44  func ProbedLevel() LevelType {
    45  	level, _ := probeSELinux()
    46  	return level
    47  }
    48  
    49  // Summary describes SELinux status
    50  func Summary() string {
    51  	_, summary := probeSELinux()
    52  	return summary
    53  }
    54  
    55  // Status returns the current level of SELinux support and a descriptive summary
    56  func Status() (level LevelType, summary string) {
    57  	return probeSELinux()
    58  }
    59  
    60  func probeSELinux() (LevelType, string) {
    61  	enabled, err := selinuxIsEnabled()
    62  	if err != nil {
    63  		return Unsupported, err.Error()
    64  	}
    65  	if !enabled {
    66  		return Unsupported, ""
    67  	}
    68  
    69  	enforcing, err := selinuxIsEnforcing()
    70  	if err != nil {
    71  		return Unsupported, fmt.Sprintf("SELinux is enabled, but status cannot be determined: %v", err)
    72  	}
    73  	if !enforcing {
    74  		return Permissive, "SELinux is enabled but in permissive mode"
    75  	}
    76  	return Enforcing, "SELinux is enabled and in enforcing mode"
    77  }
    78  
    79  // MockIsEnabled makes the system believe a certain SELinux state is currently
    80  // true
    81  func MockIsEnabled(isEnabled func() (bool, error)) (restore func()) {
    82  	old := selinuxIsEnabled
    83  	selinuxIsEnabled = isEnabled
    84  	return func() {
    85  		selinuxIsEnabled = old
    86  	}
    87  }
    88  
    89  // MockIsEnforcing makes the system believe the current SELinux is currently
    90  // enforcing
    91  func MockIsEnforcing(isEnforcing func() (bool, error)) (restore func()) {
    92  	old := selinuxIsEnforcing
    93  	selinuxIsEnforcing = isEnforcing
    94  	return func() {
    95  		selinuxIsEnforcing = old
    96  	}
    97  }