home *** CD-ROM | disk | FTP | other *** search
Text File | 1993-11-04 | 17.2 KB | 571 lines | [TEXT/MPS ] |
- //234567890123456789012345678901234567890123456789012345678901234567890123456789
- //===========================================================================
- // File: SampleUserConfigModule.c
- //
- // This is the user configuration code resource of the sample add-on security
- // module for Apple Remote Access. This code resource is responsible
- // for putting up a dialog box on the server to configure this security
- // for a user.
- //
- // It displays a dialog box that the admin can put an extra password into.
- // During authentication the user is required to enter this additional
- // password.
- //
- // Copyright © 1992, 1993 Apple Computer Inc.
- // All rights reserved
- //
- // Author: Farzad Sarabi
- //
- // Modification history:
- //
- // 5/3/1993 Farzad Updated the code for changes in the Security
- // Manager such as setting up of the A5 world.
- // 12/14/1992 Farzad Created sample source from the shell file
- // 10/6/1992 Farzad Created
- //===========================================================================
-
-
- #include <Types.h>
- #include <Memory.h>
- #include <Resources.h>
- #include <Dialogs.h>
-
- #include "SecurityInterface.h" // has the interface for ARA services
-
-
-
-
- //===========================================================================
- // Macros
- //===========================================================================
-
- #define kUserConfigDialogID 129
- #define kOKButtonID 1
- #define kCancelButtonID 2
- #define kPasswordBoxID 3
- #define kDialogTitleID 4
-
-
-
- //===========================================================================
- // Types
- //===========================================================================
-
- // the following enumeration defines the states that our state machine
- // will use. They are used as either the CompletionParam field of the
- // the completion routine, or as the LongParam for a kSecurityTickleAction.
- // Using them in this way we can step through the state machine.
-
- typedef enum
- {
- kStateMiscCompletion, // used for all the other completions
- // we don't care about
- kStateGotPassword, // got the existing password
- kStatePutUpDialog, // display the dialog, this must be
- // done during a tickle action
- kStateStoredPassword, // wrote the new password out
- kStateFinish // used to indicate operation is
- // complete, and we should call
- // ARACompleteOperation
-
- } TUserConfigStates;
-
-
- // An A5 world is setup for this module, so we can have global data such
- // as the following
- static struct
- {
- char fold_password[ kSecurityMaxConfigData ];
- char fuser_name[ kSecurityUserInfoLength ];
- DialogPtr fconfig_dialog; // configuration dialog
-
- } MyData; // statically allocated in our
- // A5 world
-
-
-
-
- // function prototypes
- static long DoMyStartup( MyReference, LongParam );
- static long DoMyShutdown( MyReference, LongParam );
- static long DoMyBegin( MyReference, LongParam );
- static long DoMyEnd( MyReference, LongParam );
- static long DoMyDataHandler( MyReference, LongParam );
- static long DoMyAbortHandler( MyReference, LongParam );
- static long DoMyTickleHandler( MyReference, LongParam );
-
- pascal void MyCompletionProc( SecurityReference MyReference,
- int ResultCode,
- void * DataPtr,
- int DataSize,
- long CompletionParam );
-
-
-
-
- // this function is the entry point into this code resource, and it should
- // be the first function definition in this module. Also, during link
- // time this module should be the first object file listed.
-
- pascal long MySecurityProcEntry( SecurityActions Action,
- SecurityReference MyReference,
- long LongParam )
- //===========================================================================
- // Description: this is the entry point for the ??? security operation.
- // It is called by AppleTalk Remote Access to have this
- // security module perform the given operation. It
- // dispatches to a variety of routines based on the
- // requested action.
- //
- // Parameters: Action the action to be performed
- // MyReference this is a unique value representing
- // this instance of this code module.
- // DataPtr the data for this action
- // DataSize the size of data
- //
- // Return Value: long result code, nonzero indicates an
- // error. Its value is one of the
- // SecurityResultCodes.
- //
- // Creation Date:
- //
- // Modifications:
- //
- //===========================================================================
- {
- switch ( Action ) {
-
- case kSecurityStartup:
- return DoMyStartup( MyReference, LongParam );
-
-
- case kSecurityShutdown:
- return DoMyShutdown( MyReference, LongParam );
-
-
- case kSecurityBegin:
- return DoMyBegin( MyReference, LongParam );
-
-
- case kSecurityEnd:
- return DoMyEnd( MyReference, LongParam );
-
-
- case kSecurityDataAvailable:
- return DoMyDataHandler( MyReference, LongParam );
-
-
- case kSecurityAbort:
- return DoMyAbortHandler( MyReference, LongParam );
-
-
- case kSecurityTickleAction:
- return DoMyTickleHandler( MyReference, LongParam );
-
- }
-
- return ( kSecurityUnsupportedAction );
- }
-
-
-
-
- static long DoMyStartup( MyReference, LongParam )
- //===========================================================================
- // Description: this routine setsup our environment. It allocates the
- // memory we need and readies this resource for operating.
- //
- // Parameters: MyReference My unique reference
- // LongParam additional information
- //
- // Return Value: long result code, nonzero indicates error
- //
- // Creation Date:
- //
- // Modifications:
- //
- //===========================================================================
- {
- #pragma unused(LongParam,MyReference)
-
- // we don't need to do anything during the Startup action.
- // normally we could allocate memory and other types of initialization
- // prior to actually doing any work
-
- return ( kSecurityNoErr );
- }
-
-
-
- static long DoMyShutdown( MyReference, LongParam )
- //===========================================================================
- // Description: this routine handles the kSecurityShutdown action. It
- // cleans up any allocated memory.
- //
- // Parameters: MyReference My unique reference
- // LongParam additional information
- //
- // Return Value: long result code, nonzero indicates error
- //
- // Creation Date:
- //
- // Modifications:
- //
- //===========================================================================
- {
- #pragma unused(MyReference,LongParam)
-
- // We don't need to do anything here for the Shutdown action.
- // normally we would be releasing any resources that are allocated by
- // this module here.
- // this is the very last messages that is sent to the module
-
- return ( kSecurityNoErr );
- }
-
-
-
- static long DoMyBegin( MyReference, LongParam )
- //===========================================================================
- // Description: this routine is where we actually start doing work. When
- // we are called, we have already setup our memory area.
- // We first request our old password, and we can then
- // display our dialog box, and get the new password.
- //
- // Parameters: MyReference My unique reference
- // LongParam additional information
- //
- // Return Value: long result code, nonzero indicates error
- //
- // Creation Date:
- //
- // Modifications:
- //
- //===========================================================================
- {
-
- #pragma unused(LongParam) // so we don't get compiler warnings
-
- // We need to start the processing here when we get the Begin action.
- // We must get the user's name and existing password (i.e. secondary
- // password).
- //
- // notice we use the CompletionParam as the next state we will transition
- // to when this call completes. The states are defined above in
- // TUserConfigStates
-
- if (( ARAGetUserInfo( MyReference,
- MyData.fuser_name, // store it here
- sizeof( MyData.fuser_name ),
- MyCompletionProc,
- kStateMiscCompletion ) != ARANoErr ) ||
- // ignore the completion for this
- // call and get the password also
- ( ARAReadLockSecurityData( MyReference,
- MyData.fold_password,
- sizeof( MyData.fold_password ),
- MyCompletionProc,
- kStateGotPassword ) != ARANoErr ))
- {
- // something failed in the ARA services, don't even continue
- ARACompleteOperation( MyReference );
- return ( kSecurityGenericErr );
- }
- // we are done here, when this call completes
- return ( kSecurityNoErr );
- }
-
-
-
- static long DoMyEnd( MyReference, LongParam )
- //===========================================================================
- // Description: this routine handles the kSecurityEnd action. The action
- // is sent to signal the end of the operation the code
- // resource was created to do.
- //
- // Parameters: MyReference My unique reference
- // LongParam additional information
- //
- // Return Value: long result code, nonzero indicates error
- //
- // Creation Date:
- //
- // Modifications:
- //
- //===========================================================================
- {
- #pragma unused(MyReference,LongParam)
-
- // this action is sent as a response to one of our requests (e.g.
- // ARACompleteOperation) for ending the process
-
- // We would normally use this as an indicator that the operation that
- // the module is performing is ended as per our request. We could do
- // some cleanup here. We should then wait for the ShutDown action as
- // an indication that our module will be unloaded.
-
- return ( kSecurityNoErr );
- }
-
-
-
- static long DoMyDataHandler( MyReference, LongParam )
- //===========================================================================
- // Description: this routine handles the kSecurityDataAvailable action.
- // The action is sent when data has arrived for the code
- // resource.
- //
- // Parameters: MyReference My unique reference
- // LongParam additional information
- //
- // Return Value: long result code, nonzero indicates error
- //
- // Creation Date:
- //
- // Modifications:
- //
- //===========================================================================
- {
- #pragma unused(MyReference,LongParam)
-
- // Currently DataAvailable action is not being used. It may in the future
- // be put to some use. One possible use might be for cases when you have
- // a modeless dialog box. We could send you the events through the use
- // of this action.
-
- // This action might also be used when we get data during
- // the authentication process, and you don't have a read pending.
-
- // Again, it is not used now but may be used in the future!
-
- return ( kSecurityNoErr );
- }
-
-
-
- static long DoMyAbortHandler( MyReference, LongParam )
- //===========================================================================
- // Description: this routine handles the kSecurityAbort action. The
- // abort action is sent when the code resources operation
- // needs to be terminated abnormally.
- //
- // Parameters: MyReference My unique reference
- // LongParam additional information
- //
- // Return Value: long result code, nonzero indicates error
- //
- // Creation Date:
- //
- // Modifications:
- //
- //===========================================================================
- {
- #pragma unused(MyReference,LongParam)
-
- // We are being aborted. You need to abort what you are doing.
- // ARAServices will not be available after this (at least the read and
- // writes will not be available, but you shouldn't expect any of the
- // ARA services to be available). The kSecurityAbort action is sent
- // because of some type of exception.
-
- return ( kSecurityNoErr );
- }
-
-
-
- static long DoMyTickleHandler( MyReference, LongParam )
- //===========================================================================
- // Description: this routine is called periodically so we can perform
- // periodic tasks. It is also called when we call
- // ARATickleMe. It is called at non-interrupt time, so
- // we can perform memory management, etc. We use it to
- // do the operations that need to be done at this time,
- // e.g. the dialog box is displayed in this routine. We
- // use the LongParam (which is 0 if ARA calls us) to
- // show the state which we need to handle.
- //
- //
- // Parameters: MyReference My unique reference
- // LongParam When ARA calls this value will be 0,
- // otherwise it is the value passed to
- // the ARATickleMe routine. We use this
- // to show the state we need to handle.
- //
- // Return Value: long result code, nonzero indicates error
- //
- // Creation Date:
- //
- // Modifications:
- //
- //===========================================================================
- {
- #pragma unused(LongParam)
-
-
- // since we only care about one state here, we will use an if statement
- // otherwise we could use a switch
-
- if ( LongParam == kStatePutUpDialog )
- {
- short item_hit;
- Handle item_handle;
- short item_type;
- Rect item_box;
-
- // our resource file is on top of the resource file chain
- // get our configuration dialog box
- MyData.fconfig_dialog = GetNewDialog( kUserConfigDialogID,
- nil,
- (WindowPtr) -1 );
- if ( MyData.fconfig_dialog == nil )
- {
- ARALogMessage( MyReference,
- "\pCouldn't load user configuration dialog",
- MyCompletionProc,
- kStateFinish );
- return ( kSecurityGenericErr );
- }
- // In the following there should be more error checking on the
- // returned items from the Mac Toolbox, but to keep the code
- // clearer, I don't do all error checking some.
- // now set the dialog title and old password
- GetDItem( MyData.fconfig_dialog,
- kDialogTitleID,
- & item_type,
- & item_handle,
- & item_box );
- SetIText( item_handle, MyData.fuser_name );
-
- GetDItem( MyData.fconfig_dialog,
- kPasswordBoxID,
- & item_type,
- & item_handle,
- & item_box );
- SetIText( item_handle, MyData.fold_password );
-
- do
- {
- ModalDialog( nil, & item_hit );
- } while (( item_hit != kOKButtonID ) &&
- ( item_hit != kCancelButtonID ));
-
- if ( item_hit == kOKButtonID )
- { // we should really check to see if the password is different
- // then save it only if it's not the same as the old password
-
- GetDItem( MyData.fconfig_dialog,
- kPasswordBoxID,
- & item_type,
- & item_handle,
- & item_box );
- GetIText( item_handle, MyData.fold_password );
- ARAWriteSecurityData( MyReference,
- MyData.fold_password,
- sizeof( MyData.fold_password ),
- MyCompletionProc,
- kStateStoredPassword );
- }
- else
- { // user selected cancel, just unlock the data
- ARAUnlockSecurityData( MyReference,
- MyCompletionProc,
- kStateFinish );
- }
- DisposDialog( MyData.fconfig_dialog );
- }
-
- return ( kSecurityNoErr );
- }
-
-
-
- pascal void MyCompletionProc( SecurityReference MyReference,
- int ResultCode,
- void * DataPtr,
- int DataSize,
- long CompletionParam )
- //===========================================================================
- // Description: this is the completion routine that is called when
- // ARA Services have completed an asynchronous request.
- // We use the CompletionParam as a state indicator. ARA
- // lets us know which state has just been completed so
- // we can make a transition to the appropriate next state.
- // When we call ARA services we provide the value for
- // CompletionParam (i.e. our state indicator). This routine
- // is used for all asynchronous ARA routines.
- //
- // Parameters: MyReference my unique identifier
- // ResultCode result for the ARA call
- // DataPtr pointer to the data we passed to ARA
- // DataSize size of processed data (i.e. in the
- // cases of reads or writes this may
- // be different than what we passed to
- // the ARA call)
- // CompletionParam this is the parameter we passed to the
- // ARA service. We use it to indicate
- // what state we are in.
- //
- // Return Value: none
- //
- // Creation Date: 12/15/1992
- //
- // Modifications:
- //
- //===========================================================================
- {
- if ( ResultCode == ARAAbort ) // we are being aborted
- // don't do anything
- // ARA services calls with this
- // result code when we are
- // aborting
- {
- return;
- }
-
- switch ( CompletionParam )
- {
-
- case kStateGotPassword: // got the existing password
- // and the user name
- // we need to put up the dialog box now. But we can't do it
- // here, because we may be called at interrupt time, so
- // we send a tickle routine to ourselves.
- if (( ResultCode != ARANoErr ) ||
- ( DataSize == 0 ))
- { // initialize the password to
- // the empty string
- ((char*) DataPtr )[ 0 ] = '\0';
- }
- ARATickleMe( MyReference, kStatePutUpDialog );
- break;
-
-
- case kStateStoredPassword: // wrote the new password out
- // we have written a new password out. We must now unlock the
- // security configuration data
-
- if ( ARAUnlockSecurityData( MyReference,
- MyCompletionProc,
- kStateFinish ) != ARANoErr )
- {
- ARACompleteOperation( MyReference );
- return;
- }
- break;
-
-
- case kStateFinish: // all done
- ARACompleteOperation( MyReference );
- break;
-
-
- case kStateMiscCompletion: // used for all the other completions
- default:
- break; // don't need to do anything, this is
- // just used for routines for which we
- // don't need to do anything.
- // It is only put here to show this.
- }
-
- return;
- }