1/* 2 Copyright (C) 2002-2005 SKYRIX Software AG 3 4 This file is part of SOPE. 5 6 SOPE is free software; you can redistribute it and/or modify it under 7 the terms of the GNU Lesser General Public License as published by the 8 Free Software Foundation; either version 2, or (at your option) any 9 later version. 10 11 SOPE is distributed in the hope that it will be useful, but WITHOUT ANY 12 WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public 14 License for more details. 15 16 You should have received a copy of the GNU Lesser General Public 17 License along with SOPE; see the file COPYING. If not, write to the 18 Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 19 02111-1307, USA. 20*/ 21 22#include "SoClassSecurityInfo.h" 23#include "SoClass.h" 24#include "common.h" 25 26@implementation SoClassSecurityInfo 27 28- (id)initWithSoClass:(SoClass *)_class { 29 if ((self = [self init])) { 30 self->className = [[_class className] copy]; 31 } 32 return self; 33} 34 35- (void)dealloc { 36 [self->defaultAccess release]; 37 [self->publicNames release]; 38 [self->privateNames release]; 39 [self->nameToPerm release]; 40 [self->defRoles release]; 41 [self->objectPermission release]; 42 [self->className release]; 43 [super dealloc]; 44} 45 46/* attribute security */ 47 48- (void)_logPermAlreadySetForName:(NSString *)_name { 49 [self warnWithFormat: 50 @"tried to declare permission for attribute '%@' twice!", _name]; 51} 52 53- (void)setDefaultAccess:(NSString *)_access { 54 if (self->defaultAccess) 55 [self _logPermAlreadySetForName:@"<default>"]; 56 else { 57 self->defaultAccess = [_access isNotNull] ? [_access copy] : nil; 58 [self debugWithFormat:@"set default access: '%@'", self->defaultAccess]; 59 } 60} 61- (NSString *)defaultAccess { 62 return self->defaultAccess; 63} 64- (BOOL)hasDefaultAccessDeclaration { 65 return [self->defaultAccess length] > 0 ? YES : NO; 66} 67 68- (void)declarePublic:(NSString *)_firstName, ... { 69 va_list va; 70 NSString *aname; 71 72 if (self->publicNames == nil) 73 self->publicNames = [[NSMutableSet alloc] init]; 74 75 va_start(va, _firstName); 76 for (aname = _firstName; aname != nil; aname = va_arg(va, id)) { 77 if ([self->publicNames containsObject:aname]) 78 [self _logPermAlreadySetForName:aname]; 79 else if ([self->privateNames containsObject:aname]) 80 [self _logPermAlreadySetForName:aname]; 81 else if ([self->nameToPerm objectForKey:aname]) 82 [self _logPermAlreadySetForName:aname]; 83 else { 84 [self->publicNames addObject:aname]; 85 [self debugWithFormat:@"set key public: '%@'", aname]; 86 } 87 } 88 va_end(va); 89} 90 91- (void)declarePrivate:(NSString *)_firstName, ... { 92 va_list va; 93 NSString *aname; 94 95 if (self->privateNames == nil) 96 self->privateNames = [[NSMutableSet alloc] init]; 97 98 va_start(va, _firstName); 99 for (aname = _firstName; aname != nil; aname = va_arg(va, id)) { 100 if ([self->publicNames containsObject:aname]) 101 [self _logPermAlreadySetForName:aname]; 102 else if ([self->privateNames containsObject:aname]) 103 [self _logPermAlreadySetForName:aname]; 104 else if ([self->nameToPerm objectForKey:aname]) 105 [self _logPermAlreadySetForName:aname]; 106 else { 107 [self->privateNames addObject:aname]; 108 [self debugWithFormat:@"set key private: '%@'", aname]; 109 } 110 } 111 va_end(va); 112} 113 114- (void)declareProtected:(NSString *)_perm :(NSString *)_firstName, ... { 115 va_list va; 116 NSString *aname; 117 118 _perm = [_perm lowercaseString]; 119 120 if (self->nameToPerm == nil) 121 self->nameToPerm = [[NSMutableDictionary alloc] initWithCapacity:16]; 122 123 va_start(va, _firstName); 124 for (aname = _firstName; aname != nil; aname = va_arg(va, id)) { 125 if ([self->publicNames containsObject:aname]) 126 [self _logPermAlreadySetForName:aname]; 127 else if ([self->privateNames containsObject:aname]) 128 [self _logPermAlreadySetForName:aname]; 129 else if ([self->nameToPerm objectForKey:aname]) 130 [self _logPermAlreadySetForName:aname]; 131 else { 132 [self->nameToPerm setObject:_perm forKey:aname]; 133 [self debugWithFormat:@"protect key by '%@': '%@'", _perm, aname]; 134 } 135 } 136 va_end(va); 137} 138 139- (BOOL)hasProtectionsForKey:(NSString *)_key { 140 if (_key == nil) return NO; 141 142 if ([self->publicNames containsObject:_key]) return YES; 143 if ([self->privateNames containsObject:_key]) return YES; 144 if ([self->nameToPerm objectForKey:_key]) return YES; 145 return NO; 146} 147 148- (BOOL)isKeyPrivate:(NSString *)_key { 149 return [self->privateNames containsObject:_key]; 150} 151- (BOOL)isKeyPublic:(NSString *)_key { 152 return [self->publicNames containsObject:_key]; 153} 154- (NSString *)permissionRequiredForKey:(NSString *)_key { 155 return [self->nameToPerm objectForKey:_key]; 156} 157 158/* object security */ 159 160- (void)_logObjPermAlreadySet { 161 [self warnWithFormat:@"tried to declare object permission twice! " 162 @"(perm=%@,private=%s,public=%s)", 163 self->objectPermission, 164 self->isObjectPrivate?"yes":"no", 165 self->isObjectPublic?"yes":"no"]; 166} 167 168- (BOOL)hasObjectProtections { 169 if (self->objectPermission) return YES; 170 if (self->isObjectPrivate) return YES; 171 if (self->isObjectPublic) return YES; 172 return NO; 173} 174- (BOOL)isObjectPublic { 175 return self->isObjectPublic; 176} 177- (BOOL)isObjectPrivate { 178 return self->isObjectPrivate; 179} 180- (NSString *)permissionRequiredForObject { 181 return self->objectPermission; 182} 183 184- (void)declareObjectPublic { 185 if ([self->objectPermission isNotNull] || self->isObjectPrivate) 186 [self _logObjPermAlreadySet]; 187 else { 188 [self debugWithFormat:@"declared object public"]; 189 self->isObjectPublic = YES; 190 } 191} 192- (void)declareObjectPrivate { 193 if ([self->objectPermission isNotNull] || self->isObjectPublic) 194 [self _logObjPermAlreadySet]; 195 else { 196 [self debugWithFormat:@"declared object private"]; 197 self->isObjectPrivate = YES; 198 } 199} 200- (void)declareObjectProtected:(NSString *)_perm { 201 _perm = [_perm isNotNull] ? [_perm lowercaseString] : (NSString *)nil; 202 203 if ([_perm length] == 0) { 204 [self logWithFormat:@"tried to declare empty permission !", _perm]; 205 return; 206 } 207 208 if (self->isObjectPrivate || self->isObjectPublic || 209 (self->objectPermission != nil)) { 210 [self _logObjPermAlreadySet]; 211 } 212 else { 213 [self debugWithFormat:@"declared object protected by: %@", _perm]; 214 self->objectPermission = [_perm copy]; 215 } 216} 217 218/* default role mappings */ 219 220- (BOOL)hasDefaultRoleForPermission:(NSString *)_p { 221 if (_p == nil) return NO; 222 _p = [_p lowercaseString]; 223 return [self->defRoles objectForKey:_p] == nil ? NO : YES; 224} 225 226- (void)declareRole:(NSString *)_role asDefaultForPermission:(NSString *)_per{ 227 id tmp; 228 229 _per = [_per isNotNull] ? [_per lowercaseString] : (NSString *)nil; 230 231 if (self->defRoles == nil) 232 self->defRoles = [[NSMutableDictionary alloc] initWithCapacity:8]; 233 234 if ((tmp = [self->defRoles objectForKey:_per])) { 235 [self warnWithFormat:@"tried to set default role of '%@' twice!" 236 @" (set to %@)", _per, tmp]; 237 return; 238 } 239 240 tmp = [_role isNotNull] ? [NSArray arrayWithObject:_role] : [NSArray array]; 241 [self->defRoles setObject:tmp forKey:_per]; 242} 243- (void)declareRole:(NSString *)_role 244 asDefaultForPermissions:(NSString *)_p,... 245{ 246 va_list va; 247 NSString *aperm; 248 249 va_start(va, _p); 250 for (aperm = _p; aperm != nil; aperm = va_arg(va, id)) { 251 [self declareRole:_role asDefaultForPermission:aperm]; 252 } 253 va_end(va); 254} 255 256- (void)declareRoles:(NSArray *)_roles asDefaultForPermission:(NSString *)_p { 257 id tmp; 258 259 _p = [_p isNotNull] ? [_p lowercaseString] : (NSString *)nil; 260 261 if (self->defRoles == nil) 262 self->defRoles = [[NSMutableDictionary alloc] initWithCapacity:8]; 263 264 if ((tmp = [self->defRoles objectForKey:_p])) { 265 [self warnWithFormat:@"tried to set default role of '%@' twice!" 266 @" (set to %@)", _p, tmp]; 267 return; 268 } 269 270 tmp = [_roles isNotNull] ? _roles : (NSArray *)[NSArray array]; 271 [self->defRoles setObject:tmp forKey:_p]; 272} 273 274- (NSArray *)defaultViewRoles { 275 static NSArray *defViewRoles = nil; 276 if (defViewRoles == nil) { 277 defViewRoles = [[NSArray alloc] initWithObjects: 278 @"Anonymous", @"Manager", nil]; 279 } 280 return defViewRoles; 281} 282- (NSArray *)defaultContentsRoles { 283 static NSArray *defContentRoles = nil; 284 if (defContentRoles == nil) { 285 defContentRoles = [[NSArray alloc] initWithObjects: 286 @"Anonymous", @"Manager", nil]; 287 } 288 return defContentRoles; 289} 290- (NSArray *)defaultRoles { 291 static NSArray *defRolesA = nil; 292 if (defRolesA == nil) 293 defRolesA = [[NSArray alloc] initWithObjects:@"Manager", nil]; 294 return defRolesA; 295} 296 297- (NSArray *)defaultRolesForPermission:(NSString *)_p { 298 NSArray *roles; 299 300 _p = [_p lowercaseString]; 301 302 if ((roles = [self->defRoles objectForKey:_p])) 303 ; 304 else if ([_p isEqualToString:@"view"]) 305 roles = [self defaultViewRoles]; 306 else if ([_p isEqualToString:@"access contents information"]) 307 roles = [self defaultContentsRoles]; 308 else 309 roles = [self defaultRoles]; 310 311 return roles; 312} 313 314@end /* SoClassSecurityInfo */ 315 316@implementation SoClassSecurityInfo(Logging) 317 318- (NSString *)loggingPrefix { 319 return [self->className length] > 0 320 ? [NSString stringWithFormat:@"[so-secinfo %@]", self->className] 321 : [NSString stringWithFormat:@"[so-secinfo 0x%p]", self]; 322} 323- (BOOL)isDebuggingEnabled { 324 static int debugOn = -1; 325 if (debugOn == -1) { 326 debugOn = [[NSUserDefaults standardUserDefaults] 327 boolForKey:@"SoLogSecurityDeclarations"] ? 1 : 0; 328 } 329 return debugOn ? YES : NO; 330} 331 332@end /* SoClassSecurityInfo(Logging) */ 333