Retired Document
Important: This sample code may not represent best practices for current development. The project may use deprecated symbols and illustrate technologies and techniques that are no longer recommended.
sources/PGPserverUAM.c
// |
// Apple Macintosh Developer Technical Support |
// Written by: Vinnie Moscaritolo |
// |
// Copyright (work in progress) Apple Computer, Inc All rights reserved. |
// |
// You may incorporate this sample code into your applications without |
// restriction, though the sample code has been provided "AS IS" and the |
// responsibility for its operation is 100% yours. However, what you are |
// not permitted to do is to redistribute the source as "DSC Sample Code" |
// after having made changes. If you're going to re-distribute the source, |
// we require that you make it clear in the source that the code was |
// descended from Apple Sample Code, but that you've made changes. |
// |
#include <types.h> |
typedef UInt32 KernelID; |
#include <string.h> |
#include <PLStringFuncs.h> |
#include <CodeFragments.h> |
#include "AppleShareRegistry.h" |
#include "AppleShareFileServerRegistry.h" |
#include "UAM.h" |
//#include "OAMTypes.h" |
#define PGP_MACINTOSH 1 |
#include "pgpErrors.h" |
#include "pgpKeys.h" |
#include "pgpMemoryMgr.h" |
#include "pgpUtilities.h" |
#include "pgpFeatures.h" |
#include "pgpHash.h" |
#include "pgpPublicKey.h" |
#include "TPGPException.h" |
#include "TMacException.h" |
#include "TPGPkey.h" |
#include "TMemPGPkey.h" |
#include "PGPUAMmsgFormat.h" |
#include "PGPServerMemory.h" |
#include "ASIPChallenge.h" |
// --------------------------------------------------------------------------- |
#pragma mark Prototypes |
// --------------------------------------------------------------------------- |
#ifdef __cplusplus |
extern "C" { |
#endif |
#pragma export on |
unsigned long UAMVersion = 0; |
unsigned long UAMFlags = 0; |
unsigned char *UAMName = "\pPGPUAM 1.0"; |
OAMStatus UAMAuthenticate ( int operation, int id, |
void* authState, int authStateSize, |
void* authData, int authDataSize, |
void* authStateOut, int* authStateSizeOut, |
void* authDataOut, int* authDataSizeOut); |
pascal OSErr UAMSetUP(const CFragInitBlock *theInitBlock); |
pascal void UAMCleanUP(void); |
pascal OSErr __initialize(const CFragInitBlock *theInitBlock); |
pascal OSErr __terminate(void); |
#pragma export off |
#ifdef __cplusplus |
} |
#endif |
static void BuildObjectSpecByNameType(OAMObjectSpec *obj, StringPtr name, OAMType type); |
// --------------------------------------------------------------------------- |
#pragma mark Globals |
// --------------------------------------------------------------------------- |
static TMemPGPkey * gServerKey = nil; |
static PGPMemoryMgrRef gMemMgr = nil; |
static Boolean gReloadServerKey = false; |
class TLoginState |
{ |
public: |
void* operator new (size_t size) { return ::OTAllocMem (size); }; |
void operator delete (void* deadObject) { ::OTFreeMem(deadObject); }; |
// PRIVATE FIELDS |
TMemPGPkey fClientKey; |
Str255 fCounterChallengeString; |
}; |
// --------------------------------------------------------------------------- |
static void BuildObjectSpecByNameType(OAMObjectSpec *obj, StringPtr name, OAMType type) |
// --------------------------------------------------------------------------- |
// |
{ |
short len = 0; |
memset(obj, 0, sizeof(OAMObjectSpec)); |
obj->specType = kOAMObjectSpecByNameType; |
obj->objectType = type; |
len = *name + 1; |
memcpy(obj->u.name, name, len); |
} |
// --------------------------------------------------------------------------- |
OAMStatus UAMAuthenticate |
(int operation, int id, |
void* authState, int authStateSize, void* authData, int authDataSize, |
void* authStateOut, int* authStateSizeOut, void* authDataOut, int* authDataSizeOut) |
// --------------------------------------------------------------------------- |
// |
{ |
*authStateSizeOut = 0; |
*authDataSizeOut = 0; |
OAMStatus err = kOAMAuthenticationErr; |
try |
{ |
switch (operation) |
{ |
case kUAMAuthLogin: |
// DebugStr("\pPGP UAMAuthenticate operation = kUAMAuthLogin"); |
// check if server key needs to be reloaded |
if(gReloadServerKey) |
{ |
OAMObjectSpec obj; |
unsigned char keyBuf[1024]; |
UInt32 bufLen = sizeof (keyBuf); |
// DebugStr("\pInitializing Server Key"); |
memset(&obj, 0, sizeof(OAMObjectSpec)); |
obj.specType = kOAMObjectSpecByShortID; |
obj.u.shortID = kOAMMachineShortID; |
err = UAMGetAttribute(&obj, kOAMMachine, 'PGPs', (void*) keyBuf, &bufLen); |
if(err == noErr) |
{ |
gServerKey->Initialize( (void*)keyBuf, bufLen ); |
gReloadServerKey = false; |
} |
} |
// Do authentication challenge. |
{ |
PUAM_LOGIN_CMD cmd; |
TLoginState* stateP; |
OAMObjectSpec obj; |
unsigned char keyBuf[1024]; |
UInt32 bufLen = sizeof (keyBuf); |
Str32 fpString; |
ParseLoginCmd(authData, (unsigned long *) &authDataSize, &cmd); |
// find users key |
memset(&obj, 0, sizeof(OAMObjectSpec)); |
BuildObjectSpecByNameType(&obj,(StringPtr) cmd.userName, kOAMUser); |
err = UAMGetAttribute(&obj, kOAMUser, 'PGPs', (void*) keyBuf, &bufLen); |
if(err != noErr) break; |
stateP = new TLoginState(); |
stateP->fClientKey.Initialize((void*) keyBuf, bufLen ); |
// build Challenge String . |
stateP->fClientKey.GetFingerprintBinaryPString(fpString ); |
ReplyToChallenge(gServerKey, "\0", &stateP->fClientKey, (StringPtr) cmd.challengeString, stateP->fCounterChallengeString); |
*authDataSizeOut = ((char*) FormatLoginResp(authDataOut, stateP->fCounterChallengeString, fpString) - (char*)authDataOut); |
memcpy( authStateOut, &stateP, sizeof stateP ); |
*authStateSizeOut = sizeof stateP; |
err = kOAMAuthenticationInProgressErr; |
} |
break; |
case kUAMAuthLoginContinue: |
err = kOAMAuthenticationErr; |
if (authStateSize == sizeof (TLoginState*) ) |
{ |
PUAM_LOGIN_CONT_CMD cmd; |
TLoginState* stateP = nil; |
memcpy( &stateP,authState, sizeof stateP ); |
if(stateP) |
{ |
ParseLoginContinueCmd(authData, (unsigned long *) &authDataSize, &cmd); |
err = VerifyCounterChallenge( &stateP->fClientKey, stateP->fCounterChallengeString, cmd.SigPString) |
? noErr : kOAMAuthenticationErr; |
delete stateP; |
} |
} |
*authStateSizeOut = 0; |
break; |
case kUAMAuthChangeKey: // for change password |
DebugStr("\pPGP UAMAuthenticate operation = kUAMAuthChangeKey"); |
break; |
case kUAMAuthChangeKeyContinue: // for change password |
DebugStr("\pPGP UAMAuthenticate operation = kUAMAuthChangeKeyContinue"); |
break; |
} |
} |
// handle PGP errors |
catch (TPGPException &ex) |
{ |
DebugStr("\pTPGPException"); |
err = kOAMAuthenticationErr; |
} |
return err; |
} |
// --------------------------------------------------------------------------- |
pascal OSErr UAMSetUP(const CFragInitBlock *theInitBlock) |
// --------------------------------------------------------------------------- |
// |
{ |
OSStatus err = noErr; |
// DebugStr("\pPGP UAMSetUP"); |
err = __initialize( theInitBlock ); |
if (err != noErr) return err; |
try |
{ |
// Create a custom PGP context |
ThrowIfMacErr( InitializeServerMemory(&gMemMgr)); |
TPGPkey::Initialize(gMemMgr); |
gServerKey = new TMemPGPkey(); |
gReloadServerKey = true; |
} |
catch (TMacException & ex) |
{ |
err = ex.GetExceptionErr(); |
} |
catch (TPGPException &ex) |
{ |
err = ex.GetExceptionErr(); |
} |
return err; |
} |
// --------------------------------------------------------------------------- |
pascal void UAMCleanUP(void) |
// --------------------------------------------------------------------------- |
// |
{ |
DebugStr("\pUAM UAMCleanUP"); |
try |
{ |
// if(gClientKey) delete gClientKey; |
// if(gServerKey) delete gServerKey; |
TPGPkey::Finalize(); |
FinalizeServerMemory(gMemMgr); |
} |
catch (TMacException & ex) |
{ |
} |
catch (TPGPException &ex) |
{ |
} |
__terminate(); |
} |
Copyright © 2003 Apple Computer, Inc. All Rights Reserved. Terms of Use | Privacy Policy | Updated: 2003-07-22