github.com/hugh712/snapd@v0.0.0-20200910133618-1a99902bd583/polkit/authority.go (about) 1 // -*- Mode: Go; indent-tabs-mode: t -*- 2 3 /* 4 * Copyright (C) 2017 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 polkit 21 22 import ( 23 "errors" 24 25 "github.com/godbus/dbus" 26 ) 27 28 type CheckFlags uint32 29 30 const ( 31 CheckNone CheckFlags = 0x00 32 CheckAllowInteraction CheckFlags = 0x01 33 ) 34 35 var ( 36 ErrDismissed = errors.New("Authorization request dismissed") 37 ErrInteraction = errors.New("Authorization requires interaction") 38 ) 39 40 func checkAuthorization(subject authSubject, actionId string, details map[string]string, flags CheckFlags) (bool, error) { 41 bus, err := dbus.SystemBus() 42 if err != nil { 43 return false, err 44 } 45 authority := bus.Object("org.freedesktop.PolicyKit1", 46 "/org/freedesktop/PolicyKit1/Authority") 47 48 var result authResult 49 err = authority.Call( 50 "org.freedesktop.PolicyKit1.Authority.CheckAuthorization", 0, 51 subject, actionId, details, flags, "").Store(&result) 52 if err != nil { 53 return false, err 54 } 55 if !result.IsAuthorized { 56 if result.IsChallenge { 57 err = ErrInteraction 58 } else if result.Details["polkit.dismissed"] != "" { 59 err = ErrDismissed 60 } 61 } 62 return result.IsAuthorized, err 63 } 64 65 // CheckAuthorization queries polkit to determine whether a process is 66 // authorized to perform an action. 67 func CheckAuthorization(pid int32, uid uint32, actionId string, details map[string]string, flags CheckFlags) (bool, error) { 68 subject := authSubject{ 69 Kind: "unix-process", 70 Details: make(map[string]dbus.Variant), 71 } 72 subject.Details["pid"] = dbus.MakeVariant(uint32(pid)) // polkit is *wrong*! 73 startTime, err := getStartTimeForPid(pid) 74 if err != nil { 75 return false, err 76 } 77 // While discovering the pid's start time is racy, it isn't security 78 // relevant since it only impacts expiring the permission after 79 // process exit. 80 subject.Details["start-time"] = dbus.MakeVariant(startTime) 81 subject.Details["uid"] = dbus.MakeVariant(uid) 82 return checkAuthorization(subject, actionId, details, flags) 83 } 84 85 type authSubject struct { 86 Kind string 87 Details map[string]dbus.Variant 88 } 89 90 type authResult struct { 91 IsAuthorized bool 92 IsChallenge bool 93 Details map[string]string 94 }