]>
git.saurik.com Git - apple/security.git/blob - securityd/src/tokencache.cpp
2 * Copyright (c) 2004-2006,2008 Apple Inc. All Rights Reserved.
4 * @APPLE_LICENSE_HEADER_START@
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. Please obtain a copy of the License at
10 * http://www.opensource.apple.com/apsl/ and read it before using this
13 * The Original Code and all software distributed under the License are
14 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
15 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
16 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
18 * Please see the License for the specific language governing rights and
19 * limitations under the License.
21 * @APPLE_LICENSE_HEADER_END@
26 // tokencache - persistent (on-disk) hardware token directory
28 // Here's the basic disk layout, rooted at /var/db/TokenCache (or $TOKENCACHE):
31 #include "tokencache.h"
32 #include <security_utilities/unix++.h>
33 #include <security_utilities/casts.h>
37 using namespace UnixPlusPlus
;
41 // Here are the uid/gid values we assign to token daemons and their cache files
43 #define TOKEND_UID "tokend"
44 #define TOKEND_GID "tokend"
45 #define TOKEND_UID_FALLBACK uid_t(-2)
46 #define TOKEND_GID_FALLBACK gid_t(-2)
50 // Fixed relative file paths
53 // relative to cache root (use cache->path())
54 static const char configDir
[] = "config";
55 static const char lastSSIDFile
[] = "config/lastSSID";
56 static const char tokensDir
[] = "tokens";
58 // relative to token directory (use token->path())
59 static const char ssidFile
[] = "SSID";
63 // Internal file I/O helpers. These read/write entire files.
64 // Note that the defaulted read functions do NOT write the default
65 // to disk; they work fine in read-only disk areas.
67 static unsigned long getFile(const string
&path
, unsigned long defaultValue
)
70 AutoFileDesc
fd(path
, O_RDONLY
, FileDesc::modeMissingOk
);
72 string s
; fd
.readAll(s
);
73 unsigned long value
= defaultValue
;
74 sscanf(s
.c_str(), "%lu", &value
);
82 static string
getFile(const string
&path
, const string
&defaultValue
)
85 AutoFileDesc
fd(path
, O_RDONLY
, FileDesc::modeMissingOk
);
87 string s
; fd
.readAll(s
);
96 static void putFile(const string
&path
, uint32 value
)
99 snprintf(buffer
, sizeof(buffer
), "%u\n", value
);
100 AutoFileDesc(path
, O_WRONLY
| O_CREAT
| O_TRUNC
).writeAll(buffer
);
103 static void putFile(const string
&path
, const string
&value
)
105 AutoFileDesc(path
, O_WRONLY
| O_CREAT
| O_TRUNC
).writeAll(value
);
110 // The "rooted tree" utility class
112 void Rooted::root(const string
&r
)
114 assert(mRoot
.empty()); // can't re-set this
118 string
Rooted::path(const char *sub
) const
122 return mRoot
+ "/" + sub
;
127 // Open a TokenCache.
128 // If the cache does not exist at the path given, initialize it.
129 // If that fails, throw an exception.
131 TokenCache::TokenCache(const char *where
)
132 : Rooted(where
), mLastSubservice(0)
134 makedir(root(), O_CREAT
, 0711, securityd
);
135 makedir(path(configDir
), O_CREAT
, 0700, securityd
);
136 makedir(path(tokensDir
), O_CREAT
, 0711, securityd
);
138 mLastSubservice
= int_cast
<ssize_t
, uint32
>(getFile(path(lastSSIDFile
), 1));
140 // identify uid/gid for token daemons
141 struct passwd
*pw
= getpwnam(TOKEND_UID
);
142 mTokendUid
= pw
? pw
->pw_uid
: TOKEND_UID_FALLBACK
;
143 struct group
*gr
= getgrnam(TOKEND_GID
);
144 mTokendGid
= gr
? gr
->gr_gid
: TOKEND_GID_FALLBACK
;
146 secinfo("tokencache", "token cache rooted at %s (last ssid=%u, uid/gid=%d/%d)",
147 root().c_str(), mLastSubservice
, mTokendUid
, mTokendGid
);
150 TokenCache::~TokenCache()
156 // Get a new, unused subservice id number.
157 // Update the tracking file so we won't hand it out again (ever) within this cache.
159 uint32
TokenCache::allocateSubservice()
161 putFile(path(lastSSIDFile
), ++mLastSubservice
);
162 return mLastSubservice
;
167 // A slightly souped-up UnixPlusPlus::makedir
169 void TokenCache::makedir(const char *path
, int flags
, mode_t mode
, Owner owner
)
171 UnixPlusPlus::makedir(path
, flags
, mode
);
174 // leave it alone; we own it alrady
177 ::chown(path
, tokendUid(), tokendGid());
184 // Make a cache entry from a valid tokenUid.
185 // This will locate an existing entry or make a new one.
187 TokenCache::Token::Token(TokenCache
&c
, const string
&tokenUid
)
188 : Rooted(c
.path(string(tokensDir
) + "/" + tokenUid
)), cache(c
)
190 cache
.makedir(root(), O_CREAT
, 0711, securityd
);
191 if ((mSubservice
= int_cast
<unsigned long, uint32
>(getFile(path(ssidFile
), 0)))) {
192 secinfo("tokencache", "found token \"%s\" ssid=%u", tokenUid
.c_str(), mSubservice
);
195 mSubservice
= cache
.allocateSubservice(); // allocate new, unique ssid...
196 putFile(path(ssidFile
), mSubservice
); // ... and save it in cache
197 secinfo("tokencache", "new token \"%s\" ssid=%u", tokenUid
.c_str(), mSubservice
);
204 // Make a cache entry that is temporary and will never be reused.
206 TokenCache::Token::Token(TokenCache
&c
)
209 mSubservice
= cache
.allocateSubservice(); // new, unique id
210 char rootForm
[30]; snprintf(rootForm
, sizeof(rootForm
),
211 "%s/temporary:%u", tokensDir
, mSubservice
);
212 root(cache
.path(rootForm
));
213 cache
.makedir(root(), O_CREAT
| O_EXCL
, 0711, securityd
);
214 putFile(path(ssidFile
), mSubservice
); // ... and save it in cache
215 secinfo("tokencache", "temporary token \"%s\" ssid=%u", rootForm
, mSubservice
);
221 // Common constructor setup code
223 void TokenCache::Token::init(Type type
)
226 cache
.makedir(workPath(), O_CREAT
, 0700, tokend
);
227 cache
.makedir(cachePath(), O_CREAT
, 0700, tokend
);
232 // The Token destructor might clean or preen a bit, but shouldn't take
233 // too long (or too much effort).
235 TokenCache::Token::~Token()
237 if (type() == temporary
)
238 secinfo("tokencache", "@@@ should delete the cache directory here...");
243 // Attributes of TokenCache::Tokens
245 string
TokenCache::Token::workPath() const
250 string
TokenCache::Token::cachePath() const
252 return path("Cache");
256 string
TokenCache::Token::printName() const
258 return getFile(path("PrintName"), "");
261 void TokenCache::Token::printName(const string
&name
)
263 putFile(path("PrintName"), name
);