]>
git.saurik.com Git - apple/securityd.git/blob - src/tokencache.cpp
2 * Copyright (c) 2004 Apple Computer, 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>
36 using namespace UnixPlusPlus
;
40 // Here are the uid/gid values we assign to token daemons and their cache files
42 #define TOKEND_UID "tokend"
43 #define TOKEND_GID "tokend"
44 #define TOKEND_UID_FALLBACK uid_t(-2)
45 #define TOKEND_GID_FALLBACK gid_t(-2)
49 // Fixed relative file paths
52 // relative to cache root (use cache->path())
53 static const char configDir
[] = "config";
54 static const char lastSSIDFile
[] = "config/lastSSID";
55 static const char tokensDir
[] = "tokens";
57 // relative to token directory (use token->path())
58 static const char ssidFile
[] = "SSID";
59 static const char workDir
[] = "work";
60 static const char cacheDir
[] = "cache";
64 // Internal file I/O helpers. These read/write entire files.
65 // Note that the defaulted read functions do NOT write the default
66 // to disk; they work fine in read-only disk areas.
68 static uint32
getFile(const string
&path
, uint32 defaultValue
)
71 AutoFileDesc
fd(path
);
72 string s
; fd
.readAll(s
);
73 uint32 value
; sscanf(s
.c_str(), "%ld", &value
);
80 static string
getFile(const string
&path
, const string
&defaultValue
)
83 AutoFileDesc
fd(path
);
84 string s
; fd
.readAll(s
);
92 static void putFile(const string
&path
, uint32 value
)
95 snprintf(buffer
, sizeof(buffer
), "%ld\n", value
);
96 AutoFileDesc(path
, O_WRONLY
| O_CREAT
| O_TRUNC
).writeAll(buffer
);
99 static void putFile(const string
&path
, const string
&value
)
101 AutoFileDesc(path
, O_WRONLY
| O_CREAT
| O_TRUNC
).writeAll(value
);
106 // The "rooted tree" utility class
108 void Rooted::root(const string
&r
)
110 assert(mRoot
.empty()); // can't re-set this
114 string
Rooted::path(const char *sub
) const
118 return mRoot
+ "/" + sub
;
123 // Open a TokenCache.
124 // If the cache does not exist at the path given, initialize it.
125 // If that fails, throw an exception.
127 TokenCache::TokenCache(const char *where
)
128 : Rooted(where
), mLastSubservice(0)
130 makedir(root(), O_CREAT
, 0711, securityd
);
131 makedir(path(configDir
), O_CREAT
, 0700, securityd
);
132 makedir(path(tokensDir
), O_CREAT
, 0711, securityd
);
134 // get the path for the SSID file. Don't call getFile unless the file exists (avoids exception overhead)
135 string idFilePath
= path (lastSSIDFile
);
137 if (stat (idFilePath
.c_str (), &st
) == -1) {
140 mLastSubservice
= getFile(idFilePath
, 1);
143 // identify uid/gid for token daemons
144 struct passwd
*pw
= getpwnam(TOKEND_UID
);
145 mTokendUid
= pw
? pw
->pw_uid
: TOKEND_UID_FALLBACK
;
146 struct group
*gr
= getgrnam(TOKEND_GID
);
147 mTokendGid
= gr
? gr
->gr_gid
: TOKEND_GID_FALLBACK
;
149 secdebug("tokencache", "token cache rooted at %s (last ssid=%ld, uid/gid=%d/%d)",
150 root().c_str(), mLastSubservice
, mTokendUid
, mTokendGid
);
153 TokenCache::~TokenCache()
159 // Get a new, unused subservice id number.
160 // Update the tracking file so we won't hand it out again (ever) within this cache.
162 uint32
TokenCache::allocateSubservice()
164 putFile(path(lastSSIDFile
), ++mLastSubservice
);
165 return mLastSubservice
;
170 // A slightly souped-up UnixPlusPlus::makedir
172 void TokenCache::makedir(const char *path
, int flags
, mode_t mode
, Owner owner
)
174 UnixPlusPlus::makedir(path
, flags
, mode
);
177 // leave it alone; we own it alrady
180 ::chown(path
, tokendUid(), tokendGid());
187 // Make a cache entry from a valid tokenUid.
188 // This will locate an existing entry or make a new one.
190 TokenCache::Token::Token(TokenCache
&c
, const string
&tokenUid
)
191 : Rooted(c
.path(string(tokensDir
) + "/" + tokenUid
)), cache(c
)
193 cache
.makedir(root(), O_CREAT
, 0711, securityd
);
194 if (mSubservice
= getFile(path(ssidFile
), 0)) {
195 secdebug("tokencache", "found token \"%s\" ssid=%ld", tokenUid
.c_str(), mSubservice
);
198 mSubservice
= cache
.allocateSubservice(); // allocate new, unique ssid...
199 putFile(path(ssidFile
), mSubservice
); // ... and save it in cache
200 secdebug("tokencache", "new token \"%s\" ssid=%ld", tokenUid
.c_str(), mSubservice
);
207 // Make a cache entry that is temporary and will never be reused.
209 TokenCache::Token::Token(TokenCache
&c
)
212 mSubservice
= cache
.allocateSubservice(); // new, unique id
213 char rootForm
[30]; snprintf(rootForm
, sizeof(rootForm
),
214 "%s/temporary:%ld", tokensDir
, mSubservice
);
215 root(cache
.path(rootForm
));
216 cache
.makedir(root(), O_CREAT
| O_EXCL
, 0711, securityd
);
217 putFile(path(ssidFile
), mSubservice
); // ... and save it in cache
218 secdebug("tokencache", "temporary token \"%s\" ssid=%ld", rootForm
, mSubservice
);
224 // Common constructor setup code
226 void TokenCache::Token::init(Type type
)
229 cache
.makedir(workPath(), O_CREAT
, 0700, tokend
);
230 cache
.makedir(cachePath(), O_CREAT
, 0700, tokend
);
235 // The Token destructor might clean or preen a bit, but shouldn't take
236 // too long (or too much effort).
238 TokenCache::Token::~Token()
240 if (type() == temporary
)
241 secdebug("tokencache", "@@@ should delete the cache directory here...");
246 // Attributes of TokenCache::Tokens
248 string
TokenCache::Token::workPath() const
253 string
TokenCache::Token::cachePath() const
255 return path("Cache");
259 string
TokenCache::Token::printName() const
261 return getFile(path("PrintName"), "");
264 void TokenCache::Token::printName(const string
&name
)
266 putFile(path("PrintName"), name
);