1// ====================================================================== 2// File: KCParamUtility.h 3// 4// Wrapper classes for function parameters 5// (using Parry's PodWrapper) 6// 7// 8// Copyright: Copyright (c) 2000,2003,2006 Apple Computer, Inc. All Rights Reserved. 9// 10// Change History (most recent first): 11// 12// <1> 2/22/00 em Created. 13// ====================================================================== 14#ifndef __KC_PARAM_UTILITY_ 15#define __KC_PARAM_UTILITY_ 16 17#if TARGET_RT_MAC_MACHO 18 #include <OSServices/KeychainCore.h> 19 #include <OSServices/KeychainCorePriv.h> 20 #include <SecurityHI/KeychainHI.h> 21 //#include <SecurityCore/SecKeychainAPI.h> 22#else 23 #include <Keychain.h> 24#endif 25#include <security_utilities/utilities.h> 26 27#include <list> 28#include <stdio.h> 29#include <string> 30#include <Carbon/Carbon.h> 31 32#undef check 33//typedef const char* SecStringPtr; 34 35// ��������������������������������������������������������������������������� 36// � CParam - base class for TParam template 37// ��������������������������������������������������������������������������� 38class CParam 39{ 40public: 41 virtual void Write(FILE *inFile)=0; 42 virtual void Read(FILE *inFile)=0; 43 virtual bool Compare(FILE *inFile)=0; 44}; 45typedef std::list<CParam*> tParamList; 46// ��������������������������������������������������������������������������� 47// � TParam 48// ��������������������������������������������������������������������������� 49template <class Wrapper, class StructT, class T> 50class TParam : public CParam 51{ 52public: 53 TParam(const char *inName) 54 :mName(inName), mResult(true) 55 { 56 } 57 58 TParam(const char *inName, T&inData) 59 :mPod(inData), mName(inName), mResult(true) 60 { 61 } 62 63 virtual ~TParam(){} 64 65 bool operator == (const T inData) const { return (mPod == inData); } 66 Wrapper& operator = (const T inData){ return mPod = inData; } 67 Wrapper& operator = (const T* inData){ return mPod = inData; } 68 operator T*(){ return (T*)mPod; } 69 operator T(){ return (T)mPod; } 70 71 virtual void Write(FILE *inFile) 72 { 73 WriteTitle(inFile); 74 mPod.WriteData(inFile); 75 } 76 77 virtual void Read(FILE *inFile) 78 { 79 ReadTitle(inFile); 80 mPod.ReadData(inFile); 81 } 82 83 virtual bool Compare(FILE *inFile) 84 { 85 ReadTitle(inFile); 86 Wrapper aWrapper; 87 aWrapper.ReadData(inFile); 88 return (mResult = (mPod == aWrapper)); 89 } 90 91protected: 92 Wrapper mPod; 93 const char *mName; 94 bool mResult; 95 96 virtual void WriteTitle(FILE *inFile) 97 { 98 if(mResult) 99 fprintf(inFile, " %s : ", mName); 100 else 101 fprintf(inFile, "*** %s : ", mName); 102 } 103 104 virtual void ReadTitle(FILE *inFile) 105 { 106 char aTitle[256]; 107 fscanf(inFile, "%s : ", aTitle); 108 if(::strcmp(mName, aTitle) != 0){ 109 throw(mName); 110 } 111 } 112 113}; 114 115// ��������������������������������������������������������������������������� 116// � Non-struct POD wrapping macros 117// ��������������������������������������������������������������������������� 118#define POD_STRUCT(type) type##Struct 119#define POD_CLASS(type) CParam##type 120#define TYPEDEF_POD_STRUCT(type) typedef struct type##Struct { type data; } type##Struct; 121#define TYPEDEF_POD_CLASS(type) typedef TParam<C##type, type##Struct, type> CParam##type; 122#define TYPEDEF_STRUCTPOD_CLASS(type) typedef TParam<C##type, type, type> CParam##type; 123// ��������������������������������������������������������������������������� 124// � UInt32 wrapper 125// ��������������������������������������������������������������������������� 126TYPEDEF_POD_STRUCT(UInt32) 127class CUInt32 : public PodWrapper<CUInt32, POD_STRUCT(UInt32)>{ 128public: 129 CUInt32(){ data = 0; }; 130 CUInt32(const UInt32 &inData){ data = inData; } 131 132 CUInt32 & operator = (const UInt32 &inData){ data = inData; return *this; } 133 bool operator == (const UInt32 inData) const { return data == inData; } 134 operator UInt32*(){ return &data; } 135 operator UInt32(){ return data; } 136 137 virtual void WriteData(FILE *inFile) 138 { 139 fprintf(inFile, "%ld\n", data); 140 } 141 142 virtual void ReadData(FILE *inFile) 143 { 144 fscanf(inFile, "%ld\n", &data); 145 } 146}; 147TYPEDEF_POD_CLASS(UInt32) 148 149// ��������������������������������������������������������������������������� 150// � UInt16 wrapper 151// ��������������������������������������������������������������������������� 152TYPEDEF_POD_STRUCT(UInt16) 153class CUInt16 : public PodWrapper<CUInt16, POD_STRUCT(UInt16)>{ 154public: 155 CUInt16(){ data = 0; }; 156 CUInt16(const UInt16 &inData){ data = inData; } 157 158 CUInt16 & operator = (const UInt16 &inData){ data = inData; return *this; } 159 bool operator == (const UInt16 inData) const { return data == inData; } 160 operator UInt16*(){ return &data; } 161 operator UInt16(){ return data; } 162 163 virtual void WriteData(FILE *inFile) 164 { 165 fprintf(inFile, "%ld\n", (UInt32)data); 166 } 167 168 virtual void ReadData(FILE *inFile) 169 { 170 UInt32 aData; 171 fscanf(inFile, "%ld\n", &aData); 172 data = aData; 173 } 174}; 175TYPEDEF_POD_CLASS(UInt16) 176 177// ��������������������������������������������������������������������������� 178// � Boolean wrapper 179// ��������������������������������������������������������������������������� 180TYPEDEF_POD_STRUCT(Boolean) 181class CBoolean : public PodWrapper<CBoolean, POD_STRUCT(Boolean)>{ 182public: 183 CBoolean(){ data = false; } 184 CBoolean(const Boolean &inData){ data = inData; } 185 operator Boolean*(){ return &data; } 186 operator Boolean(){ return data; } 187 188 CBoolean & operator = (const Boolean &inData){ data = inData; return *this; } 189 bool operator == (const Boolean inData) const { return data == inData; } 190 191 virtual void WriteData(FILE *inFile) 192 { 193 fprintf(inFile, "%d\n", data); 194 } 195 196 virtual void ReadData(FILE *inFile) 197 { 198 int aValue; 199 fscanf(inFile, "%d\n", &aValue); 200 data = ((aValue == 0) ? false : true); 201 } 202 203}; 204TYPEDEF_POD_CLASS(Boolean) 205 206// ��������������������������������������������������������������������������� 207// � FourCharCode wrapper 208// ��������������������������������������������������������������������������� 209TYPEDEF_POD_STRUCT(FourCharCode) 210class CFourCharCode : public PodWrapper<CFourCharCode, POD_STRUCT(FourCharCode)>{ 211public: 212 CFourCharCode(){ data = '????'; } 213 CFourCharCode(const FourCharCode &inData){ data = inData; } 214 215 CFourCharCode & operator = (const FourCharCode &inData){ data = inData; return *this; } 216 bool operator == (const FourCharCode inData) const { return data == inData; } 217 operator FourCharCode*(){ return &data; } 218 operator FourCharCode(){ return data; } 219 220 virtual void WriteData(FILE *inFile) 221 { 222 for(UInt16 i=0; i<sizeof(FourCharCode); i++){ 223 fprintf(inFile, "%c", (char)(data >> ((sizeof(FourCharCode)-i-1) * 8))); 224 } 225 fprintf(inFile, "\n"); 226 } 227 228 virtual void ReadData(FILE *inFile) 229 { 230 FourCharCode aValue = 0; 231 for(UInt16 i=0; i<sizeof(FourCharCode); i++){ 232 char aChar; 233 fscanf(inFile, "%c", &aChar); 234 aValue += (UInt32)aChar << ((sizeof(FourCharCode)-i-1)*8); 235 } 236 fscanf(inFile, "\n"); 237 data = aValue; 238 } 239 240}; 241TYPEDEF_POD_CLASS(FourCharCode) 242 243typedef CParamFourCharCode CParamOSType; 244typedef CParamFourCharCode CParamKCItemClass; 245typedef CParamFourCharCode CParamKCAttrType; 246 247// ��������������������������������������������������������������������������� 248// � AliasHandle wrapper 249// ��������������������������������������������������������������������������� 250TYPEDEF_POD_STRUCT(AliasHandle) 251class CAliasHandle : public PodWrapper<CAliasHandle, POD_STRUCT(AliasHandle)>{ 252public: 253 CAliasHandle(){ data = NULL; } 254 CAliasHandle(const AliasHandle &inData){ data = inData; } 255 256 CAliasHandle & operator = (const AliasHandle &inData){ data = inData; return *this; } 257 bool operator == (const AliasHandle inData) const { return data == inData; } 258 operator AliasHandle*(){ return &data; } 259 operator AliasHandle(){ return data; } 260 261 virtual void WriteData(FILE *inFile) 262 { 263 fprintf(inFile, "%s\n", mFullPathName); 264 } 265 266 virtual void ReadData(FILE *inFile) 267 { 268 memset(mFullPathName, 0, sizeof(mFullPathName)); 269 if(UNIX_fgets(mFullPathName, sizeof(mFullPathName), inFile)){ 270 // fgets grabs the newline code too 271 mFullPathName[strlen(mFullPathName)-1] = 0; 272 } 273 else throw("Syntax error in CAliasHandle"); 274 275 if(strchr(mFullPathName, ':')){ 276 // Create a alias from the full-path name 277 //%%%cpm - this WONT work, Keychain mgr does not fill in the FSSpec 278 ::NewAliasMinimalFromFullPath( 279 strlen(mFullPathName), 280 mFullPathName, 281 NULL, 282 NULL, 283 &data); 284 } 285 else{ 286 // Ask KeychainLib to fill in the FSSpec for us 287 FSSpec tmpSpec = {0,0}; 288 tmpSpec.name[0] = ::strlen(mFullPathName); 289 memcpy(tmpSpec.name+1, mFullPathName, tmpSpec.name[0]); 290 291 KCRef aKeychain; 292 ::KCMakeKCRefFromFSSpec(&tmpSpec, &aKeychain); 293 ::KCReleaseKeychain(&aKeychain); 294 //%%%cpm - this WONT work, Keychain mgr does not fill in the FSSpec 295 ::NewAliasMinimal( 296 &tmpSpec, 297 &data); 298 } 299 } 300protected: 301 char mFullPathName[1024]; 302}; 303TYPEDEF_POD_CLASS(AliasHandle) 304// ��������������������������������������������������������������������������� 305// � StringPtr wrapper 306// ��������������������������������������������������������������������������� 307TYPEDEF_POD_STRUCT(StringPtr) 308class CStringPtr : public PodWrapper<CStringPtr, POD_STRUCT(StringPtr)>{ 309public: 310 CStringPtr(){ data = new unsigned char[256]; memset(data, 0, 256); } 311 CStringPtr(const StringPtr &inData){ memset(data, 0, 256); memcpy(data, inData, inData[0]); } 312 virtual ~CStringPtr(){ delete data; } 313 314 CStringPtr & operator = (const StringPtr inData){ memset(data, 0, 256); memcpy(data, inData, inData[0]); return *this; } 315 bool operator == (const StringPtr inData) const { return ((data[0] == inData[0]) && (memcmp(data, inData, data[0]+1) == 0)); } 316 operator StringPtr*(){ return &data; } 317 operator StringPtr(){ return data; } 318 319 virtual void WriteData(FILE *inFile) 320 { 321 fprintf(inFile, "%s\n", data+1); 322 } 323 324 virtual void ReadData(FILE *inFile) 325 { 326 memset(data, 0, 256); 327 328 char cString[256]; 329 if(UNIX_fgets(cString, 256, inFile)){ 330 data[0] = strlen(cString)-1; 331 memcpy(data+1, cString, data[0]); 332 } 333 else 334 throw("Syntax error in CStringPtr"); 335 } 336}; 337TYPEDEF_POD_CLASS(StringPtr) 338 339 340TYPEDEF_POD_STRUCT(AFPServerSignature) 341class CAFPServerSignature : public PodWrapper<CAFPServerSignature, POD_STRUCT(AFPServerSignature)>{ 342public: 343 CAFPServerSignature(){ memset(data, 0, sizeof(data)); } 344 CAFPServerSignature(const AFPServerSignature &inData){ memcpy(data, inData, sizeof(data)); } 345 346 CAFPServerSignature &operator = (const AFPServerSignature inData){ memcpy(data, inData, sizeof(data)); return *this; } 347 bool operator == (const AFPServerSignature inData) const { return (memcmp(data, inData, sizeof(data)) == 0); } 348 operator AFPServerSignature*(){ return &data; } 349 350 virtual void WriteData(FILE *inFile) 351 { 352 for(UInt16 i=0; i<sizeof(data); i++) fprintf(inFile, "%c", data[i]); 353 fprintf(inFile, "\n"); 354 } 355 356 virtual void ReadData(FILE *inFile) 357 { 358 for(UInt16 i=0; i<sizeof(data); i++) fscanf(inFile, "%c", (UInt8*)(data+i)); 359 fscanf(inFile, "\n"); 360 } 361}; 362//TYPEDEF_POD_CLASS(AFPServerSignature) 363typedef TParam<CAFPServerSignature, AFPServerSignatureStruct, AFPServerSignatureStruct> CParamAFPServerSignature; 364 365// ��������������������������������������������������������������������������� 366// � Blob wrapper 367// ��������������������������������������������������������������������������� 368typedef struct kcBlob{UInt32 length; void* data; } kcBlob; 369class CkcBlob : public PodWrapper<CkcBlob, kcBlob>{ 370public: 371 CkcBlob(){ length = 0; data = NULL; } 372 CkcBlob(const kcBlob &inData){ length = 0; data = NULL; DeepCopy(inData.length, inData.data); } 373 CkcBlob & operator = (const kcBlob &inData){ DeepCopy(inData.length, inData.data); return *this; } 374 bool operator == (const kcBlob inData) const { return ((inData.length == length) && (memcmp(data, inData.data, length) == 0)); } 375 operator kcBlob*(){ return this; } 376 377#if defined(__MWERKS__) 378 operator kcBlob(){ return *this; } 379#endif 380 381 virtual void WriteData(FILE *inFile) 382 { 383 fprintf(inFile, "/%ld/", length); 384 if(length > 0){ 385 for(UInt32 i=0; i<length; i++) fprintf(inFile, "%c", ((UInt8*)data)[i]); 386 } 387 fprintf(inFile, "\n"); 388 } 389 390 virtual void ReadData(FILE *inFile) 391 { 392 UInt32 aLength; 393 fscanf(inFile, "/%ld/", &aLength); 394 395 // recyle 'data' if the size remains the same 396 if(aLength != length){ 397 if(data) delete (UInt8*)data; 398 data = NULL; 399 if(aLength > 0) data = (UInt8*)new char[aLength+2]; 400 length = aLength; 401 } 402 if(length > 0){ 403 UNIX_fgets((char*)data, aLength+3, inFile); 404 ((UInt8*)data)[length] = 0; 405 } 406 else 407 fscanf(inFile, "\n"); 408 } 409protected: 410 virtual void DeepCopy(UInt32 inLength, const void *inData) 411 { 412 if(data != NULL) delete (UInt8*)data; 413 data = NULL; 414 415 length = inLength; 416 if(length == 0) return; 417 data = (UInt8*)new char[length]; 418 memcpy(data, inData, length); 419 } 420}; 421TYPEDEF_STRUCTPOD_CLASS(kcBlob) 422 423// ��������������������������������������������������������������������������� 424// � FSSpec wrapper 425// ��������������������������������������������������������������������������� 426class CFSSpec : public PodWrapper<CFSSpec, FSSpec>{ 427public: 428 CFSSpec(){ vRefNum = 0; parID = 0; memset(name, 0, sizeof(name)); mFullPathName[0] = 0;} 429 CFSSpec(const FSSpec &inData){ memcpy(this, &inData, sizeof(*this)); } 430 CFSSpec & operator = (const FSSpec &inData){ memcpy(this, &inData, sizeof(*this)); return *this; } 431 bool operator == (const FSSpec inData) const { return (this == &inData) || !memcmp(this, &inData, sizeof(FSSpec)); } 432 operator FSSpec*(){ return this ; } 433 434 virtual void WriteData(FILE *inFile) 435 { 436 fprintf(inFile, "%s\n", mFullPathName); 437 } 438 439 virtual void ReadData(FILE *inFile) 440 { 441 memset(mFullPathName, 0, sizeof(mFullPathName)); 442 if(UNIX_fgets(mFullPathName, sizeof(mFullPathName), inFile)){ 443 // fgets grabs the newline code too 444 name[0] = strlen(mFullPathName)-1; 445 mFullPathName[name[0]] = 0; 446 memcpy(name+1, mFullPathName, name[0]); 447 } 448 else throw("Syntax error in CFSSpec"); 449 } 450protected: 451 char mFullPathName[1024]; 452}; 453TYPEDEF_STRUCTPOD_CLASS(FSSpec) 454 455// ��������������������������������������������������������������������������� 456// � FSRef wrapper 457// ��������������������������������������������������������������������������� 458class CFSRef : public PodWrapper<CFSRef, FSRef>{ 459public: 460 CFSRef(){ memset(hidden, 0, sizeof(hidden)); } 461 CFSRef(const FSRef &inData){ memcpy(this, &inData, sizeof(*this)); } 462 463 CFSRef & operator = (const FSRef &inData){ memcpy(this, &inData, sizeof(*this)); return *this; } 464 bool operator == (const FSRef inData) const { return (this == &inData) || !memcmp(this, &inData, sizeof(FSRef)); } 465 operator FSRef*(){ return this; } 466 467 virtual void WriteData(FILE *inFile) 468 { 469 // ��� need work 470 fprintf(inFile, "\n"); 471 } 472 473 virtual void ReadData(FILE *inFile) 474 { 475 // ��� need work 476 fscanf(inFile, "\n"); 477 } 478}; 479TYPEDEF_STRUCTPOD_CLASS(FSRef) 480 481 482// ��������������������������������������������������������������������������� 483// � KCAttribute wrapper 484// ��������������������������������������������������������������������������� 485class CKCAttribute : public PodWrapper<CKCAttribute, KCAttribute>{ 486public: 487 CKCAttribute(){ tag = '0000'; length = 0; data = NULL; } 488 CKCAttribute(const KCAttribute &inData){ memcpy(this, &inData, sizeof(*this)); } 489 490 CKCAttribute & operator = (const KCAttribute &inData){ memcpy(this, &inData, sizeof(*this)); return *this; } 491 bool operator == (const KCAttribute inData) const 492 { 493 if(inData.tag != tag) return false; 494 return(memcmp(inData.data, data, ((inData.length < length) ? inData.length : length)) == 0); 495 } 496 497 operator KCAttribute*(){ return this; } 498#if defined(__MWERKS__) 499 operator KCAttribute(){ return *this; } 500#endif 501 virtual void WriteData(FILE *inFile) 502 { 503 fprintf(inFile, "\n"); 504 505 CParamKCAttrType aTag(".tag", tag); 506 aTag.Write(inFile); 507 508 kcBlob theBlob = {length, data}; 509 CParamkcBlob aData(".data", theBlob); 510 aData.Write(inFile); 511 } 512 513 virtual void ReadData(FILE *inFile) 514 { 515 fscanf(inFile, "\n"); 516 517 CParamKCAttrType aTag(".tag"); 518 aTag.Read(inFile); 519 tag = aTag; 520 521 CParamkcBlob aData(".data"); 522 aData.Read(inFile); 523 524 kcBlob aBlob; 525 aBlob = aData; 526 length = aBlob.length; 527 data = aBlob.data; 528 } 529}; 530TYPEDEF_STRUCTPOD_CLASS(KCAttribute) 531 532 533// ��������������������������������������������������������������������������� 534// � KCAttributeList wrapper 535// ��������������������������������������������������������������������������� 536class CKCAttributeList : public PodWrapper<CKCAttributeList, KCAttributeList>{ 537public: 538 CKCAttributeList(){ count = 0; attr = NULL; } 539 CKCAttributeList(const CKCAttributeList &inData){ memcpy(this, &inData, sizeof(*this)); } 540 541 CKCAttributeList & operator = (const CKCAttributeList &inData){ memcpy(this, &inData, sizeof(*this)); return *this; } 542 bool operator == (const CKCAttributeList inData) const { return (this == &inData) || !memcmp(this, &inData, sizeof(CKCAttributeList)); } 543 operator CKCAttributeList*(){ return this; } 544 545 virtual void WriteData(FILE *inFile) 546 { 547 fprintf(inFile, "\n"); 548 549 CParamUInt32 aCount(".count", count); 550 aCount.Write(inFile); 551 552 for(UInt32 i=0; i<count; i++){ 553 char aAttributeTitle[32]; 554 sprintf(aAttributeTitle, ".%ld", i); 555 CParamKCAttribute aAttr(aAttributeTitle, *(attr+i)); 556 aAttr.Write(inFile); 557 } 558 } 559 560 virtual void ReadData(FILE *inFile) 561 { 562 fscanf(inFile, "\n"); 563 564 CParamUInt32 aCount(".count"); 565 aCount.Read(inFile); 566 567 // recycle if the size does not change 568 if(count != (UInt32)aCount){ 569 if(attr) delete attr; 570 count = (UInt32)aCount; 571 attr = new KCAttribute[count]; 572 } 573 574 for(UInt32 i=0; i<count; i++){ 575 char aAttributeTitle[32]; 576 sprintf(aAttributeTitle, ".%ld", i); 577 CParamKCAttribute aAttr(aAttributeTitle); 578 aAttr.Read(inFile); 579 *(attr+i) = (KCAttribute)aAttr; 580 } 581 } 582}; 583TYPEDEF_STRUCTPOD_CLASS(KCAttributeList) 584 585// ��������������������������������������������������������������������������� 586// � CKCRef wrapper 587// ��������������������������������������������������������������������������� 588TYPEDEF_POD_STRUCT(KCRef) 589class CKCRef : public PodWrapper<CKCRef, POD_STRUCT(KCRef)>{ 590public: 591 CKCRef(){ data = NULL; } 592 CKCRef(const KCRef &inData){ data = inData; } 593 bool operator == (const KCRef inKC) 594 { 595 if(inKC == data) return true; 596 597 char thisName[256] = ""; 598 char aInName[256] = ""; 599 ::kcgetkeychainname(data, thisName); 600 ::kcgetkeychainname(inKC, aInName); 601 return(::strcmp(thisName, aInName)); 602 } 603}; 604 605 606// ��������������������������������������������������������������������������� 607// � KCItemRef wrapper 608// ��������������������������������������������������������������������������� 609TYPEDEF_POD_STRUCT(KCItemRef) 610class CKCItemRef : public PodWrapper<CKCItemRef, POD_STRUCT(KCItemRef)>{ 611public: 612 CKCItemRef(){ data = NULL; } 613 CKCItemRef(const KCItemRef &inData){ data = inData; } 614 bool operator == (const KCItemRef inKCItem) 615 { 616 if(inKCItem == data) return true; 617 618 KCRef thisKeychain = 0; 619 KCRef aInKeychain = 0; 620 ::KCGetKeychain(data, &thisKeychain); 621 ::KCGetKeychain(inKCItem, &aInKeychain); 622 if((CKCRef(thisKeychain) == aInKeychain) == false) return false; 623 624// Bug #2458217 - (KCGetData() causes bus error) 625#if TARGET_RT_MAC_MACHO 626 return true; 627#else 628 UInt32 thisLength; 629 UInt32 aInLength; 630 ::KCGetData(data, 0, NULL, &thisLength); 631 ::KCGetData(inKCItem, 0, NULL, &aInLength); 632 if(thisLength != aInLength) return false; 633 634 char *thisData = new char[thisLength]; 635 char *aInData = new char[aInLength]; 636 ::KCGetData(data, thisLength, thisData, &thisLength); 637 ::KCGetData(inKCItem, aInLength, aInData, &aInLength); 638 639 int aResult = ::memcmp(thisData, aInData, thisLength); 640 641 delete thisData; 642 delete aInData; 643 return(aResult == 0); 644#endif 645 } 646}; 647 648 649#endif // __KC_PARAM_UTILITY_ 650