1*6777b538SAndroid Build Coastguard Worker // Copyright 2012 The Chromium Authors 2*6777b538SAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be 3*6777b538SAndroid Build Coastguard Worker // found in the LICENSE file. 4*6777b538SAndroid Build Coastguard Worker 5*6777b538SAndroid Build Coastguard Worker #ifndef BASE_MAC_SCOPED_AUTHORIZATIONREF_H_ 6*6777b538SAndroid Build Coastguard Worker #define BASE_MAC_SCOPED_AUTHORIZATIONREF_H_ 7*6777b538SAndroid Build Coastguard Worker 8*6777b538SAndroid Build Coastguard Worker #include <Security/Authorization.h> 9*6777b538SAndroid Build Coastguard Worker 10*6777b538SAndroid Build Coastguard Worker #include <utility> 11*6777b538SAndroid Build Coastguard Worker 12*6777b538SAndroid Build Coastguard Worker #include "base/base_export.h" 13*6777b538SAndroid Build Coastguard Worker #include "base/check.h" 14*6777b538SAndroid Build Coastguard Worker 15*6777b538SAndroid Build Coastguard Worker // `ScopedAuthorizationRef` maintains ownership of an `AuthorizationRef`. It is 16*6777b538SAndroid Build Coastguard Worker // patterned after the `unique_ptr` interface. 17*6777b538SAndroid Build Coastguard Worker 18*6777b538SAndroid Build Coastguard Worker namespace base::mac { 19*6777b538SAndroid Build Coastguard Worker 20*6777b538SAndroid Build Coastguard Worker class BASE_EXPORT ScopedAuthorizationRef { 21*6777b538SAndroid Build Coastguard Worker public: 22*6777b538SAndroid Build Coastguard Worker explicit ScopedAuthorizationRef(AuthorizationRef authorization = nullptr) authorization_(authorization)23*6777b538SAndroid Build Coastguard Worker : authorization_(authorization) {} 24*6777b538SAndroid Build Coastguard Worker 25*6777b538SAndroid Build Coastguard Worker ScopedAuthorizationRef(const ScopedAuthorizationRef&) = delete; 26*6777b538SAndroid Build Coastguard Worker ScopedAuthorizationRef& operator=(const ScopedAuthorizationRef&) = delete; 27*6777b538SAndroid Build Coastguard Worker ScopedAuthorizationRef(ScopedAuthorizationRef && that)28*6777b538SAndroid Build Coastguard Worker ScopedAuthorizationRef(ScopedAuthorizationRef&& that) 29*6777b538SAndroid Build Coastguard Worker : authorization_(std::exchange(that.authorization_, nullptr)) {} 30*6777b538SAndroid Build Coastguard Worker ScopedAuthorizationRef& operator=(ScopedAuthorizationRef&& that) { 31*6777b538SAndroid Build Coastguard Worker authorization_ = std::exchange(that.authorization_, nullptr); 32*6777b538SAndroid Build Coastguard Worker return *this; 33*6777b538SAndroid Build Coastguard Worker } 34*6777b538SAndroid Build Coastguard Worker ~ScopedAuthorizationRef()35*6777b538SAndroid Build Coastguard Worker ~ScopedAuthorizationRef() { 36*6777b538SAndroid Build Coastguard Worker if (authorization_) { 37*6777b538SAndroid Build Coastguard Worker FreeInternal(); 38*6777b538SAndroid Build Coastguard Worker } 39*6777b538SAndroid Build Coastguard Worker } 40*6777b538SAndroid Build Coastguard Worker 41*6777b538SAndroid Build Coastguard Worker void reset(AuthorizationRef authorization = nullptr) { 42*6777b538SAndroid Build Coastguard Worker if (authorization_ != authorization) { 43*6777b538SAndroid Build Coastguard Worker if (authorization_) { 44*6777b538SAndroid Build Coastguard Worker FreeInternal(); 45*6777b538SAndroid Build Coastguard Worker } 46*6777b538SAndroid Build Coastguard Worker authorization_ = authorization; 47*6777b538SAndroid Build Coastguard Worker } 48*6777b538SAndroid Build Coastguard Worker } 49*6777b538SAndroid Build Coastguard Worker 50*6777b538SAndroid Build Coastguard Worker bool operator==(AuthorizationRef that) const { 51*6777b538SAndroid Build Coastguard Worker return authorization_ == that; 52*6777b538SAndroid Build Coastguard Worker } 53*6777b538SAndroid Build Coastguard Worker 54*6777b538SAndroid Build Coastguard Worker bool operator!=(AuthorizationRef that) const { 55*6777b538SAndroid Build Coastguard Worker return authorization_ != that; 56*6777b538SAndroid Build Coastguard Worker } 57*6777b538SAndroid Build Coastguard Worker AuthorizationRef()58*6777b538SAndroid Build Coastguard Worker operator AuthorizationRef() const { 59*6777b538SAndroid Build Coastguard Worker return authorization_; 60*6777b538SAndroid Build Coastguard Worker } 61*6777b538SAndroid Build Coastguard Worker 62*6777b538SAndroid Build Coastguard Worker explicit operator bool() const { return authorization_ != nullptr; } 63*6777b538SAndroid Build Coastguard Worker 64*6777b538SAndroid Build Coastguard Worker // This is to be used only to take ownership of objects that are created 65*6777b538SAndroid Build Coastguard Worker // by pass-by-pointer create functions. To enforce this, require that the 66*6777b538SAndroid Build Coastguard Worker // object be reset to NULL before this may be used. InitializeInto()67*6777b538SAndroid Build Coastguard Worker [[nodiscard]] AuthorizationRef* InitializeInto() { 68*6777b538SAndroid Build Coastguard Worker DCHECK(!authorization_); 69*6777b538SAndroid Build Coastguard Worker return &authorization_; 70*6777b538SAndroid Build Coastguard Worker } 71*6777b538SAndroid Build Coastguard Worker get()72*6777b538SAndroid Build Coastguard Worker AuthorizationRef get() const { 73*6777b538SAndroid Build Coastguard Worker return authorization_; 74*6777b538SAndroid Build Coastguard Worker } 75*6777b538SAndroid Build Coastguard Worker 76*6777b538SAndroid Build Coastguard Worker // ScopedAuthorizationRef::release() is like std::unique_ptr<>::release. It is 77*6777b538SAndroid Build Coastguard Worker // NOT a wrapper for AuthorizationFree(). To force a ScopedAuthorizationRef 78*6777b538SAndroid Build Coastguard Worker // object to call AuthorizationFree(), use ScopedAuthorizationRef::reset(). release()79*6777b538SAndroid Build Coastguard Worker [[nodiscard]] AuthorizationRef release() { 80*6777b538SAndroid Build Coastguard Worker AuthorizationRef temp = authorization_; 81*6777b538SAndroid Build Coastguard Worker authorization_ = nullptr; 82*6777b538SAndroid Build Coastguard Worker return temp; 83*6777b538SAndroid Build Coastguard Worker } 84*6777b538SAndroid Build Coastguard Worker 85*6777b538SAndroid Build Coastguard Worker private: 86*6777b538SAndroid Build Coastguard Worker // Calling AuthorizationFree, defined in Security.framework, from an inline 87*6777b538SAndroid Build Coastguard Worker // function, results in link errors when linking dynamically with 88*6777b538SAndroid Build Coastguard Worker // libbase.dylib. So wrap the call in an un-inlined method. This method 89*6777b538SAndroid Build Coastguard Worker // doesn't check if |authorization_| is null; that check should be in the 90*6777b538SAndroid Build Coastguard Worker // inlined callers. 91*6777b538SAndroid Build Coastguard Worker void FreeInternal(); 92*6777b538SAndroid Build Coastguard Worker 93*6777b538SAndroid Build Coastguard Worker AuthorizationRef authorization_; 94*6777b538SAndroid Build Coastguard Worker }; 95*6777b538SAndroid Build Coastguard Worker 96*6777b538SAndroid Build Coastguard Worker } // namespace base::mac 97*6777b538SAndroid Build Coastguard Worker 98*6777b538SAndroid Build Coastguard Worker #endif // BASE_MAC_SCOPED_AUTHORIZATIONREF_H_ 99