home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 2000 April: Mac OS SDK / Dev.CD Apr 00 SDK1.toast / Development Kits / Mac OS / Apple Remote Access API / ARA Security API 1.0 / Sample Protocol Module / SampleClientModule.c < prev    next >
Encoding:
Text File  |  1993-11-04  |  16.1 KB  |  584 lines  |  [TEXT/MPS ]

  1. //234567890123456789012345678901234567890123456789012345678901234567890123456789
  2. //===========================================================================
  3. //    File:    SampleClientModule.c
  4. //
  5. //    This is a sample client-side add-on security code resource for Apple
  6. //    Remote Access.  It works in conjunction with the other sample code resources
  7. //    to allow additional authentication of a user during remote log-on.
  8. //
  9. //    It runs as a slave to the corresponding server-side code resource.  The
  10. //    server requests an extra password from this code resource.  This resource
  11. //    then displays an additional dialog box to prompt the user for a password.
  12. //
  13. //    Copyright © 1992, 1993 Apple Computer Inc.
  14. //    All rights reserved
  15. //
  16. //    Author:  Farzad Sarabi
  17. //
  18. //    Modification history:
  19. //
  20. //    5/3/1993    Farzad        Made changes to support the enhanced SecurityMgr
  21. //                            that creates an A5 world for the security modules.
  22. //    12/17/1992    Farzad        Created
  23. //===========================================================================
  24.  
  25. #include <Values.h>
  26. #include <Types.h>
  27. #include <Resources.h>
  28. #include <QuickDraw.h>
  29. #include <Fonts.h>
  30. #include <Events.h>
  31. #include <Windows.h>
  32. #include <Menus.h>
  33. #include <TextEdit.h>
  34. #include <Dialogs.h>
  35.  
  36.  
  37. #include    "SecurityInterface.h"
  38. #include    "SamplePackets.h"            // has types for packets sent back
  39.                                         // and forth between the
  40.                                         // authentication modules
  41.  
  42.  
  43. // #define SecurityShellVersion 0x0080
  44.  
  45.  
  46. //===========================================================================
  47. //    Macros
  48. //===========================================================================
  49.  
  50. #define kPasswordDialogID    128
  51. #define kOKButtonID            1
  52. #define kCancelButtonID        2
  53. #define kPasswordTextID        3
  54.  
  55.  
  56.  
  57.  
  58. //===========================================================================
  59. //    Types
  60. //===========================================================================
  61. // the following enum contains our state machine's states
  62.  
  63. typedef enum
  64. {
  65.     // the tickle routine gets a 0 when ARA sends a tickle, so here we
  66.     // start with a 
  67.     kStateGotRequest = 1,            // server sent us a request
  68.     kStatePutUpDialog,                // display password dialog
  69.                                     // handled at non-interrupt time
  70.     kStateSentResponse,                // sent a response to the other side
  71.     kStateGotAnswer,                // response to our password
  72.     kStateSentCancel,                // sent a cancel to other side
  73.  
  74.     kStateMiscCompletion            // for all other stuff
  75.  
  76. } TClientStates;
  77.  
  78. //===========================================================================
  79. //    Data
  80. //===========================================================================
  81. // this data will be stored in our A5 world
  82. static struct
  83. {
  84.     TSamplePacket            fout_pkt;
  85.     TSamplePacket            fin_pkt;
  86.  
  87.     DialogPtr                fpassword_dialog;
  88.  
  89. } MyData;                            // this is only data that is
  90.                                     // visible to this code resource
  91.  
  92.  
  93. //===========================================================================
  94. //    Functions
  95. //===========================================================================
  96.  
  97. // function prototypes
  98. static long        DoMyStartup( MyReference, LongParam );
  99. static long        DoMyShutdown( MyReference, LongParam );
  100. static long        DoMyBegin( MyReference, LongParam );
  101. static long        DoMyEnd( MyReference, LongParam );
  102. static long        DoMyDataHandler( MyReference, LongParam );
  103. static long        DoMyAbortHandler( MyReference, LongParam );
  104. static long        DoMyTickleHandler( MyReference, LongParam );
  105. pascal void        MyCompletionProc( SecurityReference        MyReference,
  106.                                   int                    ResultCode,
  107.                                   void                    * DataPtr,
  108.                                   int                    DataSize,
  109.                                   long                    CompletionParam );
  110.  
  111.  
  112.  
  113.  
  114. pascal long        MySecurityProcEntry( SecurityActions        Action,
  115.                                      SecurityReference        MyReference,
  116.                                      long                    LongParam )
  117. //===========================================================================
  118. //    Description:    this is the entry point for the ??? security operation.
  119. //                    It is called by AppleTalk Remote Access to have this
  120. //                    security module perform the given operation.  It
  121. //                    dispatches to a variety of routines based on the
  122. //                    requested action.
  123. //
  124. //    Parameters:        Action                the action to be performed
  125. //                    MyReference            this is a unique value representing
  126. //                                        this instance of this code module.
  127. //                    DataPtr                the data for this action
  128. //                    DataSize            the size of data
  129. //
  130. //    Return Value:    long                result code, nonzero indicates an
  131. //                                        error.  Its value is one of the
  132. //                                        SecurityResultCodes.
  133. //
  134. //    Creation Date:
  135. //
  136. //    Modifications:
  137. //
  138. //===========================================================================
  139. {
  140.     switch ( Action )    {
  141.  
  142.       case    kSecurityStartup:
  143.         return DoMyStartup( MyReference, LongParam );
  144.  
  145.  
  146.       case    kSecurityShutdown:
  147.           return DoMyShutdown( MyReference, LongParam );
  148.  
  149.  
  150.       case    kSecurityBegin:
  151.           return DoMyBegin( MyReference, LongParam );
  152.  
  153.  
  154.       case    kSecurityEnd:
  155.           return DoMyEnd( MyReference, LongParam );
  156.  
  157.  
  158.       case    kSecurityDataAvailable:
  159.         return DoMyDataHandler( MyReference, LongParam );
  160.  
  161.  
  162.       case    kSecurityAbort:
  163.         return DoMyAbortHandler( MyReference, LongParam );
  164.  
  165.  
  166.       case    kSecurityTickleAction:
  167.           return DoMyTickleHandler( MyReference, LongParam );
  168.  
  169.     }
  170.  
  171.     return ( kSecurityUnsupportedAction );
  172. }
  173.  
  174.  
  175.  
  176.  
  177. static long        DoMyStartup( MyReference, LongParam )
  178. //===========================================================================
  179. //    Description:    this routine handles the kSecurityStartup action.  You
  180. //                    should allocate any memory and setup the working
  181. //                    environment (e.g. A5 world) here.
  182. //
  183. //    Parameters:        MyReference        My unique reference
  184. //                    LongParam        additional information
  185. //
  186. //    Return Value:    long            result code, nonzero indicates error
  187. //
  188. //    Creation Date:
  189. //
  190. //    Modifications:
  191. //
  192. //===========================================================================
  193. {
  194. #pragma unused(MyReference,LongParam)
  195.  
  196.     // we have our own A5 world and quickdraw globals.  We need to
  197.     // initialize everything, since we will be displaying a dialog box.
  198.  
  199.     InitGraf((Ptr) &qd.thePort);        // toolbox stuff
  200.     InitFonts();
  201.     InitWindows();
  202.     InitMenus();
  203.     TEInit();
  204.     InitDialogs(nil);
  205.     InitCursor();
  206.  
  207.     return ( kSecurityNoErr );
  208. }
  209.  
  210.  
  211.  
  212. static long        DoMyShutdown( MyReference, LongParam )
  213. //===========================================================================
  214. //    Description:    this routine handles the kSecurityShutdown action.  You
  215. //                    should release any memory allocated by the DoMyStartup
  216. //                    routine.
  217. //
  218. //    Parameters:        MyReference        My unique reference
  219. //                    LongParam        additional information
  220. //
  221. //    Return Value:    long            result code, nonzero indicates error
  222. //
  223. //    Creation Date:
  224. //
  225. //    Modifications:
  226. //
  227. //===========================================================================
  228. {
  229. #pragma unused(MyReference,LongParam)
  230.  
  231.     // this action is sent as a response to one of our requests (e.g.
  232.     // ARACompleteOperation) for ending the process
  233.  
  234.     // We would normally use this as an indicator that the operation that
  235.     // the module is performing is ended as per our request.  We could do
  236.     // some cleanup here.  We should then wait for the ShutDown action as
  237.     // an indication that our module will be unloaded.
  238.  
  239.     return ( kSecurityNoErr );
  240. }
  241.  
  242.  
  243.  
  244. static long        DoMyBegin( MyReference, LongParam )
  245. //===========================================================================
  246. //    Description:    this routine handles the kSecurityBeing action.  This
  247. //                    routine should start the operations the code resource
  248. //                    must do.  For example an authentication code resource
  249. //                    should start the authentication process.
  250. //
  251. //    Parameters:        MyReference        My unique reference
  252. //                    LongParam        additional information
  253. //
  254. //    Return Value:    long            result code, nonzero indicates error
  255. //
  256. //    Creation Date:
  257. //
  258. //    Modifications:
  259. //
  260. //===========================================================================
  261. {
  262. #pragma unused(LongParam)
  263.  
  264.     // The server will send us a request.  The client is basically driven
  265.     // by the requests that come from the server.  We need to post a read
  266.     // to get the initial request.
  267.  
  268.     if ( ARARead( MyReference,
  269.                   & MyData.fin_pkt,
  270.                   sizeof( MyData.fin_pkt ),
  271.                   MyCompletionProc,
  272.                   kStateGotRequest ) != ARANoErr )
  273.     {
  274.         // Something went wrong.  Don't continue.  Let ARA know, so it
  275.         // can tear down the connection.
  276.  
  277.         ARACompleteOperation( MyReference );
  278.         return ( kSecurityGenericErr );
  279.     }
  280.     
  281.     return ( kSecurityNoErr );
  282.  
  283.     
  284. }
  285.  
  286.  
  287.  
  288. static long        DoMyEnd( MyReference, LongParam )
  289. //===========================================================================
  290. //    Description:    this routine handles the kSecurityEnd action.  The action
  291. //                    is sent to signal the end of the operation the code
  292. //                    resource was created to do.
  293. //
  294. //    Parameters:        MyReference        My unique reference
  295. //                    LongParam        additional information
  296. //
  297. //    Return Value:    long            result code, nonzero indicates error
  298. //
  299. //    Creation Date:
  300. //
  301. //    Modifications:
  302. //
  303. //===========================================================================
  304. {
  305. #pragma unused(MyReference,LongParam)
  306.  
  307.     // this action is sent as a response to one of our requests (e.g.
  308.     // ARACompleteOperation) for ending the process
  309.  
  310.     // We would normally use this as an indicator that the operation that
  311.     // the module is performing is ended as per our request.  We could do
  312.     // some cleanup here.  We should then wait for the ShutDown action as
  313.     // an indication that our code resource will be unloaded.
  314.  
  315.     return ( kSecurityNoErr );
  316. }
  317.  
  318.  
  319.  
  320. static long        DoMyDataHandler( MyReference, LongParam )
  321. //===========================================================================
  322. //    Description:    this routine handles the kSecurityDataAvailable action.
  323. //                    The action is sent when data has arrived for the code
  324. //                    resource.
  325. //
  326. //    Parameters:        MyReference        My unique reference
  327. //                    LongParam        additional information
  328. //
  329. //    Return Value:    long            result code, nonzero indicates error
  330. //
  331. //    Creation Date:
  332. //
  333. //    Modifications:
  334. //
  335. //===========================================================================
  336. {
  337. #pragma unused(MyReference,LongParam)
  338.  
  339.     // Currently DataAvailable action is not being used.  It may in the future
  340.     // be put to some use.  One possible use might be for cases when you have
  341.     // a modeless dialog box.  We could send you the events through the use
  342.     // of this action.
  343.  
  344.     // This action might also be used when we get data during
  345.     // the authentication process, and you don't have a read pending.
  346.  
  347.     // Again, it is not used now but may be used in the future!
  348.  
  349.     return ( kSecurityNoErr );
  350. }
  351.  
  352.  
  353.  
  354. static long        DoMyAbortHandler( MyReference, LongParam )
  355. //===========================================================================
  356. //    Description:    this routine handles the kSecurityAbort action.  The
  357. //                    abort action is sent when the code resources operation
  358. //                    needs to be terminated abnormally.
  359. //
  360. //    Parameters:        MyReference        My unique reference
  361. //                    LongParam        additional information
  362. //
  363. //    Return Value:    long            result code, nonzero indicates error
  364. //
  365. //    Creation Date:
  366. //
  367. //    Modifications:
  368. //
  369. //===========================================================================
  370. {
  371. #pragma unused(MyReference,LongParam)
  372.  
  373.     // We are being aborted.  You need to abort what you are doing.  
  374.     // ARAServices will not be available after this (at least the read and
  375.     // writes will not be available, but you shouldn't expect any of the
  376.     // ARA services to be available).  The kSecurityAbort action is sent
  377.     // because of some type of exception.
  378.  
  379.     return ( kSecurityNoErr );
  380. }
  381.  
  382.  
  383.  
  384. static long        DoMyTickleHandler( MyReference, LongParam )
  385. //===========================================================================
  386. //    Description:    this routine handles the kSecurityTickle action.  ARA
  387. //                    sends this action periodically.  The action is also
  388. //                    generated as a result of a call to ARATickleMe routine.
  389. //                    
  390. //
  391. //    Parameters:        MyReference        My unique reference
  392. //                    LongParam        When ARA calls this value will be 0,
  393. //                                    otherwise it is the value passed to
  394. //                                    the ARATickleMe routine.
  395. //
  396. //    Return Value:    long            result code, nonzero indicates error
  397. //
  398. //    Creation Date:
  399. //
  400. //    Modifications:
  401. //
  402. //===========================================================================
  403. {
  404.     // When ARA is sending us a kSecurityTickle action, the LongParam will
  405.     // be 0 (zero).  
  406.  
  407.     if ( LongParam == kStatePutUpDialog )
  408.     {                                            // need to get the user's password
  409.         short                item_hit;
  410.         Handle                item_handle;
  411.         short                item_type;
  412.         Rect                item_box;
  413.         DialogPtr            tmp_dlg_ptr;
  414.  
  415.         
  416.  
  417.         MyData.fpassword_dialog = GetNewDialog( kPasswordDialogID,
  418.                                                 nil,
  419.                                                 (WindowPtr) -1 );
  420.  
  421.         if ( MyData.fpassword_dialog == nil )        {
  422.             ARADontAllowUser( MyReference,
  423.                               "\pSecurity module couldn't load its password dialog box.",
  424.                               MyCompletionProc,
  425.                               kStateMiscCompletion );
  426.             return ( kSecurityGenericErr );
  427.         }
  428.  
  429.         do
  430.         {
  431.             ModalDialog( nil, & item_hit );
  432.         } while (( item_hit != kOKButtonID ) && ( item_hit != kCancelButtonID ));
  433.  
  434.         tmp_dlg_ptr = MyData.fpassword_dialog;
  435.         MyData.fpassword_dialog = nil;
  436.  
  437.         if ( item_hit == kCancelButtonID )
  438.         {
  439.             MyData.fout_pkt.fpkt_type = kPktCancel;
  440.             ARAWrite( MyReference,
  441.                       & MyData.fout_pkt,
  442.                       sizeof( MyData.fout_pkt ),
  443.                       MyCompletionProc,
  444.                       kStateSentCancel );
  445.         }
  446.         else
  447.         {                                            // ok button
  448.             GetDItem( tmp_dlg_ptr,
  449.                       kPasswordTextID,
  450.                       & item_type,
  451.                       & item_handle,
  452.                       & item_box );
  453.             GetIText( item_handle,
  454.                       MyData.fout_pkt.u.fresponse.fpassword );
  455.             DisposDialog( tmp_dlg_ptr );
  456.             MyData.fout_pkt.fpkt_type = kPktPasswordResponse;
  457.             if ( ARAWrite( MyReference,
  458.                            & MyData.fout_pkt,
  459.                            sizeof( MyData.fout_pkt ),
  460.                            MyCompletionProc,
  461.                            kStateSentResponse ) != ARANoErr )
  462.             {
  463.                 ARACompleteOperation( MyReference );
  464.                 return ( kSecurityGenericErr );
  465.             }
  466.         }
  467.     }              
  468.  
  469.     return ( kSecurityNoErr );
  470. }
  471.  
  472.  
  473.  
  474.  
  475. pascal void            MyCompletionProc( SecurityReference        MyReference,
  476.                                       int                    ResultCode,
  477.                                       void                    * DataPtr,
  478.                                       int                    DataSize,
  479.                                       long                    CompletionParam )
  480. //===========================================================================
  481. //    Description:    this is the completion routine that is called when the
  482. //                    ARA services routines are completed.  We use the
  483. //                    CompletionParam to indicate the state we are processing.
  484. //
  485. //    Parameters:        MyReference            my unique reference
  486. //                    ResultCode            for the ARA service call
  487. //                    DataPtr                pointer to the data we passed in
  488. //                    DataSize            the actual size of data
  489. //                    CompletionParam        additional info we passed.  We use
  490. //                                        this value to indicate the state
  491. //                                        we are processing
  492. //
  493. //    Return Value:    none
  494. //
  495. //    Creation Date:    12/17/1992
  496. //
  497. //    Modifications:
  498. //
  499. //===========================================================================
  500. {
  501. #pragma unused(DataPtr,DataSize)
  502.  
  503.     if ( ResultCode == ARAAbort )
  504.     {
  505.         // we are being aborted
  506.         return;
  507.     }
  508.  
  509.     switch ( CompletionParam )
  510.     {
  511.  
  512.       case    kStateGotRequest:                // server sent us a request
  513.  
  514.           if ( MyData.fin_pkt.fpkt_type == kPktRequestPassword )
  515.         {                                    // server wants the password
  516.  
  517.             ARATickleMe( MyReference, kStatePutUpDialog );
  518.             break;
  519.         }
  520.         else
  521.         {                                    // invalid request
  522.             ARADontAllowUser( MyReference,
  523.                               "\pServer sent an invalid request.",
  524.                               MyCompletionProc,
  525.                               kStateMiscCompletion );
  526.             break;
  527.         }
  528.  
  529.  
  530.       case    kStateSentResponse:                // sent a response to the other side
  531.         if ( ARARead( MyReference,
  532.                       & MyData.fin_pkt,
  533.                       sizeof( MyData.fin_pkt ),
  534.                       MyCompletionProc,
  535.                       kStateGotAnswer ) != ARANoErr )
  536.         {
  537.             ARACompleteOperation( MyReference );
  538.             break;                            // redundant break.  It's here in case
  539.                                             // someone adds code after the
  540.                                             // if statement
  541.         }
  542.         break;
  543.  
  544.  
  545.       case    kStateGotAnswer:
  546.           switch ( MyData.fin_pkt.fpkt_type )
  547.         {
  548.           case    kPktRequestPassword:        // server wants the user's password
  549.               ARATickleMe( MyReference, kStatePutUpDialog );
  550.             break;
  551.  
  552.           case    kPktAllow:
  553.               ARAAllowUser( MyReference,
  554.                           MyCompletionProc,
  555.                           kStateMiscCompletion );
  556.             break;
  557.  
  558.           case    kPktCancel:
  559.           default:
  560.               ARADontAllowUser( MyReference,
  561.                               "\pYou were not authenticated by the server.",
  562.                               MyCompletionProc,
  563.                               kStateMiscCompletion );
  564.             break;
  565.         }
  566.         break;
  567.  
  568.  
  569.       case    kStateSentCancel:                // sent a cancel to other side
  570.           ARACompleteOperation( MyReference );
  571.         break;
  572.  
  573.  
  574.       case    kStateMiscCompletion:            // for all other stuff
  575.       default:
  576.           break;                                // don't need to do anything
  577.  
  578.     }
  579.  
  580.     return;
  581. }
  582.  
  583.  
  584.