home *** CD-ROM | disk | FTP | other *** search
- /*
- * common routines for AFS Kerberos UAM and AFS Log re-authentication DA
- */
- /*
- * Copyright (c) 1990 Regents of The University of Michigan.
- * All Rights Reserved.
- *
- * Permission to use, copy, modify, and distribute this software
- * and its documentation for any purpose and without fee is hereby
- * granted, provided that the above copyright notice appears in all
- * copies and that both that copyright notice and this permission
- * notice appear in supporting documentation, and that the name of
- * The University of Michigan not be used in advertising or
- * publicity pertaining to distribution of the software without
- * specific, written prior permission. This software is supplied as
- * is without expressed or implied warranties of any kind.
- *
- * ITD Research Systems
- * University of Michigan
- * 535 W. William Street
- * Ann Arbor, Michigan
- * +1-313-936-2652
- * netatalk@terminator.cc.umich.edu
- */
- #include <types.h>
- #include <resources.h>
- #include <quickdraw.h>
- #include <dialogs.h>
- #include <memory.h>
- #include <osutils.h>
- #include <strings.h>
- #include <files.h>
- #include <appletalk.h>
- #include <toolutils.h>
- #include <fonts.h>
- #include <errors.h>
- #include <cursorctl.h>
-
- /*
- * MIT Kerberos and DES stuff
- */
- #include <des.h>
- #include <krb.h>
- #include <conf.h>
- #include <prot.h>
-
- #include "uam.h"
-
- pascal Boolean passwdfilter();
-
- char afp_server[ 257 ]; /* global server name */
- char afp_zone[34]; /* global zone name */
-
- int
- dologin( initial, doalerts, alpp, name, passwd, srefnum, rsesskey )
- short initial; /* true if first login */
- short doalerts;
- AFPLoginPrm *alpp;
- Str255 name;
- char *passwd;
- short *srefnum;
- des_cblock rsesskey;
- {
- des_cblock sesskey, pkey;
- des_key_schedule ks;
- char *mem, *recv, *send, *realm;
- char *p, *q;
- short rc, clen;
- Handle hdl;
- unsigned char tktlen, authlen;
-
- /*
- * allocate large buffers on the heap since our stack is tiny
- */
- if (( mem = NewPtrClear( RECV_SIZE + SEND_SIZE + REALM_SZ + 2 )) == NULL ) {
- doalert( ALRT_LOCALERR );
- return( -1 );
- }
- send = mem;
- recv = mem + SEND_SIZE;
- realm = mem + SEND_SIZE + RECV_SIZE;
-
- /* build and send the login packet:
- *
- * +-----+-----------+-------+---------------------------+
- * | CMD | \pVersion | \pUAM | \pUser[.Instance][@Realm] |
- * +-----+-----------+-------+---------------------------+
- */
-
- p = send;
- *p++ = afpLogin;
- if (( hdl = Get1Resource( 'STR ', UAM_VERSION )) == NULL ) {
- if ( doalerts ) doalert( ALRT_LOCALERR );
- DisposPtr( mem );
- return( -1 );
- }
- HLock( hdl );
- BlockMove( (char *)*hdl, p, **hdl + 1 );
- HUnlock( hdl );
- p += **hdl + 1;
- ReleaseResource( hdl );
-
- if (( hdl = Get1Resource( 'uamn', 1 )) == NULL ) {
- if ( doalerts ) doalert( ALRT_LOCALERR );
- DisposPtr( mem );
- return( -1 );
- }
- HLock( hdl );
- BlockMove( (char *)*hdl, p, **hdl + 1 );
- HUnlock( hdl );
- p += **hdl + 1;
- ReleaseResource( hdl );
-
- BlockMove( name, p, *name + 1 );
- p += *name + 1;
-
- alpp->cbPtr = send;
- alpp->cbSize = p - send;
- alpp->rbPtr = recv;
- alpp->rbSize = RECV_SIZE;
- alpp->ioCompletion = NULL;
-
- if ( initial ) {
- rc = AFPCommand( (XPPParmBlkPtr)alpp, true );
- if ( rc == noErr ) {
- rc = wait_for_completion( (XPPParmBlkPtr)alpp );
- }
- } else {
- alpp->sessRefnum = *srefnum;
- rc = ASPUserCommand( (XPPParmBlkPtr)alpp, true );
- if ( rc == noErr ) {
- rc = wait_for_completion( (XPPParmBlkPtr)alpp );
- }
- }
- if ( rc != noErr ) {
- if ( doalerts ) doalert( ALRT_LOCALERR );
- DisposPtr( mem );
- return( -1 );
- }
- switch ( alpp->cmdResult ) {
- case 0:
- case aspServerBusy:
- doalert( ALRT_NO_MORE_SESSIONS );
- DisposPtr( mem );
- return( -1 );
- case afpAuthContinue :
- break;
- case afpParmErr :
- if ( doalerts ) doalert( ALRT_AUTHERR );
- DisposPtr( mem );
- return( -1 );
- case afpBadUAM :
- default :
- if ( doalerts ) doalert( ALRT_REMOTEERR );
- DisposPtr( mem );
- return( -1 );
- }
-
- /*
- * What we get back:
- *
- * If this is the first login attempt by the user, the packet contains both
- * an application request and a ticket granting ticket. Since Kerberos
- * messages contain a type byte, we can use that to tell if we have been
- * given an ApplReq.
- *
- * +---------+-----+
- * | ApplReq | TGT |
- * +---------+-----+
- *
- * If the server and user have already negotiated a session key (stored in
- * the 'skey' resource), the packet will only contain a TGT:
- *
- * +-----+
- * | TGT |
- * +-----+
- *
- * One problem is that the user has no way of knowing what realm(s) the
- * server may share with the user. If the user attempts to use a realm
- * during the initial authentication that the server does not support, then
- * a ParamErr is returned by the server.
- */
- p = recv;
- if ( *p++ != KRB_PROT_VERSION ) {
- if ( doalerts ) doalert( ALRT_REMOTEERR );
- DisposPtr( mem );
- return( -1 );
- }
- if (( *p & 0xfe ) == AUTH_MSG_APPL_REQUEST ) {
- p += 2;
-
- bzero( realm, REALM_SZ + 1 );
- strncpy( realm+1, p, REALM_SZ );
- lncase( realm+1, REALM_SZ );
- strncpy( realm+1, p, REALM_SZ );
- lncase( realm+1, REALM_SZ );
- *realm = strlen( realm + 1 );
- ParamText( realm, NULL, NULL, NULL );
- while ( *p++ )
- ;
- tktlen = *p++;
- authlen = *p++;
- Andrew_StringToKey( passwd, realm + 1, pkey );
- des_key_sched( pkey, ks );
- des_pcbc_encrypt( p, p, tktlen, ks, &pkey, DES_DECRYPT );
- q = p;
- p += tktlen + authlen;
- q++;
- if ( strcmp( q, "afpserver" ) != 0 ) { /* check principal */
- if ( doalerts ) doalert( ALRT_REALMERR );
- DisposPtr( mem );
- return( -1 );
- }
- while ( *q++ )
- ;
- if ( strcmp( q, afp_server + 1 ) != 0 ) { /* check instance */
- if ( doalerts ) doalert( ALRT_REALMERR );
- DisposPtr( mem );
- return( -1 );
- }
- while ( *q++ )
- ;
- while ( *q++ ) /* Skip the realm */
- ;
- q += 4; /* skip afp server's ip address */
-
- BlockMove( q, sesskey, sizeof( des_cblock ) );
-
- /* save the session key under resource id == session refnum
- */
- if (( hdl = Get1Resource( 'skey', alpp->sessRefnum )) != NULL ) {
- RmveResource( hdl );
- DisposHandle( hdl );
- }
- if ( PtrToHand( q, &hdl, sizeof( des_cblock )) != noErr ) {
- if ( doalerts ) doalert( ALRT_LOCALERR );
- DisposPtr( mem );
- return( -1 );
- }
- AddResource( hdl, 'skey', alpp->sessRefnum, "\p" );
- if ( ResError() != noErr ) {
- if ( doalerts ) doalert( ALRT_LOCALERR );
- DisposPtr( mem );
- return( -1 );
- }
- WriteResource( hdl );
- if ( ResError() != noErr ) {
- if ( doalerts ) doalert( ALRT_LOCALERR );
- DisposPtr( mem );
- return( -1 );
- }
- ReleaseResource( hdl );
-
- if ( *p++ != KRB_PROT_VERSION ) {
- if ( doalerts ) doalert( ALRT_REMOTEERR );
- DisposPtr( mem );
- return( -1 );
- }
-
- } else if ( get_sesskey( alpp->sessRefnum, sesskey ) != 0 ) {
- if ( doalerts ) doalert( ALRT_LOCALERR );
- DisposPtr( mem );
- return( -1 );
- }
-
- if (( *p & 0xfe ) != AUTH_MSG_KDC_REPLY ) {
- if ( doalerts ) doalert( ALRT_REMOTEERR );
- DisposPtr( mem );
- return( -1 );
- }
- /*
- * the tgt is of the form (the cipher is encrypted under the user's key):
- *
- * +-------------+----------------------+--------+------------+--------+
- * | krb version | msg type (kdc reply) | realm | cipher len | cipher |
- * +-------------+----------------------+--------+------------+--------+
- */
- if (( *p++ & 1 ) != MSB_FIRST ) { /* incorrect byte order */
- if ( doalerts ) doalert( ALRT_LOCALERR );
- DisposPtr( mem );
- return( -1 );
- }
-
- bzero( realm, REALM_SZ + 1 ); /* save realm for string to key */
- strncpy( realm + 1, p, REALM_SZ );
- lncase( realm + 1, REALM_SZ );
- *realm = strlen( realm + 1 );
- ParamText( realm, NULL, NULL, NULL );
- while ( *p++ )
- ;
- BlockMove( p, (char *)&clen, sizeof( short ));
- p += sizeof( short );
-
- Andrew_StringToKey( passwd, realm + 1, &pkey );
- bzero( passwd, strlen( passwd ));
- des_key_sched( pkey, ks );
- des_pcbc_encrypt( p, p, clen, ks, &pkey, DES_DECRYPT );
- if ( strcmp( "krbtgt", p + 8 ) != 0 ) {
- if ( doalerts ) doalert( ALRT_REALMERR );
- DisposPtr( mem );
- return( -1 );
- }
-
- /* Send the next command packet. The CMD is AFPContLogin and the cipher is returned
- * re-encrypted under the session key:
- *
- * +-----+---+------------+--------+
- * | CMD | 0 | cipher len | cipher |
- * +-----+---+------------+--------+
- */
- q = send;
- *q++ = afpContLogin;
- *q++ = 0;
- BlockMove( (char*)&clen, q, sizeof( short ));
- q += sizeof( short);
- des_key_sched( sesskey, ks );
- des_pcbc_encrypt( p, q, clen, ks, &sesskey, DES_ENCRYPT );
- q += clen;
- alpp->cbPtr = send;
- alpp->cbSize = q - send;
- alpp->rbPtr = recv;
- alpp->rbSize = RECV_SIZE;
- rc = AFPCommand( (XPPParmBlkPtr)alpp, true );
- if ( rc == noErr ) {
- rc = wait_for_completion( (XPPParmBlkPtr)alpp );
- }
- DisposPtr( mem );
-
- if ( rc != noErr ) {
- if ( doalerts ) doalert( ALRT_LOCALERR );
- return( -1 );
- }
-
- switch ( alpp->cmdResult ) {
- case noErr :
- break;
- case afpParmErr :
- if ( doalerts ) doalert( ALRT_REALMERR );
- return( -1 );
- case afpBadUAM :
- default :
- if ( doalerts ) doalert( ALRT_REMOTEERR );
- return( -1 );
- }
-
- *srefnum = alpp->sessRefnum;
- bcopy( sesskey, rsesskey, sizeof( des_cblock ));
- return( noErr );
- }
-
-
- short
- wait_for_completion( xppp )
- XPPParmBlkPtr xppp;
- {
- EventRecord er;
- long count, ticks;
-
- ShowCursor();
-
- for( count = 0; xppp->XPP.ioResult == 1; ++count ) {
- RotateCursor( count );
- GetNextEvent( keyDownMask, &er );
- if ( er.what == keyDown && (( er.modifiers & cmdKey ) &&
- (( er.message & charCodeMask ) == '.' ))) {
- return( -1 );
- }
- Delay( 1L, &ticks );
- }
- return( noErr );
- }
-
-
- struct passwd_info {
- char *pwinfo_passwd;
- short pwinfo_dlogitem;
- short pwinfo_maxlen;
- };
-
-
- DialogPtr
- passwddialog( name, passwd, iconhdl, dlogid, in_uam, curr_srefnum, dosetpw )
- char *name;
- char *passwd;
- Handle iconhdl;
- short in_uam;
- short curr_srefnum; /* see setpw() routine */
- Boolean dosetpw; /* does the server support set password? */
- {
- DialogPtr dlog;
- short item, itemtype, h, v;
- Boolean ok_enabled;
- Handle ihdl;
- long len;
- StringHandle version_str;
- Rect irect, iconrect;
- Str255 pstr;
- TEPtr tep;
- struct passwd_info passwds[ 2 ];
-
- if (( version_str = GetString( VERSION_STR )) == NULL ) {
- doalert( ALRT_LOCALERR );
- return( NULL );
- }
-
- placewindow( 'DLOG', dlogid );
- if (( dlog = GetNewDialog( dlogid, (Ptr)NULL, (WindowPtr)-1 )) == NULL ) {
- doalert( ALRT_LOCALERR );
- return( NULL );
- }
- SetPort( dlog );
- if ( name[ 0 ] == 0 ) {
- /*
- * try to get Chooser name from system res. file
- * It is a 'STR ' resource w/ id -16096 it seems....
- */
- if (( ihdl = (Handle)GetString( -16096 )) != NULL ) {
- HLock( ihdl );
- len = **ihdl;
- if ( len > MAXNAMELEN ) {
- len = MAXNAMELEN;
- }
- bcopy( (char *)(*ihdl + 1), name + 1, len );
- name[ 0 ] = len;
- }
- }
- if ( name[ 0 ] != 0 ) {
- GetDItem( dlog, DLOG_NAMEBOX, &itemtype, &ihdl, &irect );
- SetIText( ihdl, name );
- SelIText( dlog, DLOG_PASSWDBOX, 0, 1 );
- enablebutton( dlog, DLOG_OK, true, true );
- ok_enabled = true;
- } else {
- enablebutton( dlog, DLOG_OK, false, true );
- ok_enabled = false;
- }
- enablebutton( dlog, DLOG_SETPASSWD, dosetpw && ok_enabled, false );
-
- if ( in_uam ) {
- GetDItem( dlog, DLOG_GUEST, &itemtype, &ihdl, &irect );
- SetDItem( dlog, DLOG_GUEST, itemtype | itemDisable, ihdl, &irect );
- SetCtlValue( (ControlHandle)ihdl, 0 );
- HiliteControl( (ControlHandle)ihdl, 255 );
- GetDItem( dlog, DLOG_REGUSER, &itemtype, &ihdl, &irect );
- SetDItem( dlog, DLOG_REGUSER, itemtype | itemDisable, ihdl, &irect );
- SetCtlValue( (ControlHandle)ihdl, 1 );
- }
-
- if ( iconhdl != NULL ) {
- iconrect.top = 8;
- iconrect.left = 21;
- iconrect.bottom = 40;
- iconrect.right = 53;
- PlotIcon( &iconrect, iconhdl );
- }
- TextFont( monaco );
- TextSize( 9 );
- HLock( version_str );
- h = dlog->portRect.right - 2 - StringWidth( *version_str );
- v = dlog->portRect.bottom;
- MoveTo( h, v );
- DrawString( *version_str );
-
- passwds[ 0 ].pwinfo_passwd = passwd;
- passwds[ 0 ].pwinfo_dlogitem = DLOG_PASSWDBOX;
- passwds[ 0 ].pwinfo_maxlen = MAXPASSWDLEN;
- passwds[ 1 ].pwinfo_passwd = NULL;
- ((WindowPeek)dlog)->refCon = (char *)passwds;
-
- do {
- ModalDialog( (ModalFilterProcPtr)passwdfilter, &item );
-
- if ( ((DialogPeek)dlog)->editField == DLOG_NAMEBOX - 1 ) {
- tep = *(((DialogPeek)dlog)->textH);
- if ( ok_enabled && tep->teLength < 1 ) {
- enablebutton( dlog, DLOG_OK, false, true );
- enablebutton( dlog, DLOG_SETPASSWD, false, false );
- ok_enabled = false;
- } else if ( !ok_enabled && tep->teLength >= 1 ) {
- enablebutton( dlog, DLOG_OK, true, true );
- enablebutton( dlog, DLOG_SETPASSWD, dosetpw, false );
- ok_enabled = true;
- }
- }
-
- if ( item == DLOG_SETPASSWD ) {
- /*
- * call set password routine
- */
- GetDItem( dlog, DLOG_NAMEBOX, &itemtype, &ihdl, &irect );
- GetIText( ihdl, pstr );
- setpw( pstr, curr_srefnum );
-
- /*
- * re-draw non-dialog items (since they might have been erased)
- */
- if ( iconhdl != NULL ) {
- PlotIcon( &iconrect, iconhdl );
- }
- TextFont( monaco );
- TextSize( 9 );
- MoveTo( h, v );
- DrawString( *version_str );
- enablebutton( dlog, DLOG_OK, ok_enabled, true );
- enablebutton( dlog, DLOG_SETPASSWD, ok_enabled && dosetpw, false );
- }
-
- } while ( item != DLOG_OK && item != DLOG_CANCEL );
-
- HUnlock( version_str );
- if ( item == DLOG_CANCEL ) {
- DisposDialog( dlog );
- return( NULL );
- }
-
- /*
- * get the name and null-terminate the passwd string
- */
- GetDItem( dlog, DLOG_NAMEBOX, &itemtype, &ihdl, &irect );
- GetIText( ihdl, pstr );
- BlockMove( pstr, name, pstr[ 0 ] + 1 );
-
- GetDItem( dlog, DLOG_PASSWDBOX, &itemtype, &ihdl, &irect );
- GetIText( ihdl, pstr );
- passwd[ pstr[ 0 ] ] = '\0';
- HideDItem( dlog, DLOG_OK );
- HideDItem( dlog, DLOG_SETPASSWD );
- HideDItem( dlog, DLOG_CANCEL );
- return( dlog );
- }
-
-
- pascal Boolean
- passwdfilter( dlog, event, item )
- DialogPtr dlog;
- EventRecord *event;
- short *item;
- {
- int i, j;
- char c;
- TEPtr tep;
- struct passwd_info *passwd;
- short type;
- Handle hdl;
- Rect r;
-
- if ( event->what == keyDown || event->what == autoKey ) {
- c = event->message & charCodeMask;
-
- if ( c == CHAR_ENTER || c == CHAR_RETURN ) {
- GetDItem( dlog, DLOG_OK, &type, &hdl, &r );
- *item = ( type & itemDisable ) ? 0 : DLOG_OK;
- return( true );
- }
- if ( c == CHAR_ESC ) {
- *item = DLOG_CANCEL;
- return( true );
- }
-
- for ( passwd = (struct passwd_info *)((WindowPeek)dlog)->refCon;
- passwd->pwinfo_passwd != NULL;
- ++passwd ) {
- if ( ((DialogPeek)dlog)->editField == passwd->pwinfo_dlogitem - 1 ) {
- break;
- }
- }
-
- if ( passwd->pwinfo_passwd == NULL ) {
- /*
- * must be in name entry item
- */
- if ( c > CHAR_MAXCTRL ) {
- tep = *(((DialogPeek)dlog)->textH);
- if ( tep->selStart >= tep->selEnd
- && (*(((DialogPeek)dlog)->textH))->teLength > MAXNAMELEN ) {
- SysBeep( 0 );
- return( true );
- }
- }
- return( false );
- }
-
- if ( c != CHAR_DELETE && c <= CHAR_MAXCTRL ) {
- return( false );
- }
-
- tep = *(((DialogPeek)dlog)->textH);
- if ( tep->selStart < tep->selEnd ) {
- for ( i = tep->selStart, j = tep->selEnd; i < tep->selEnd; ++i, ++j ) {
- passwd->pwinfo_passwd[ i ] = passwd->pwinfo_passwd[ j ];
- }
- } else if ( c != CHAR_DELETE && tep->teLength >= passwd->pwinfo_maxlen ) {
- SysBeep( 0 );
- return( true );
- }
-
- if ( c != CHAR_DELETE ) {
- passwd->pwinfo_passwd[ tep->selStart ] = c;
- event->message &= ( !charCodeMask | !keyCodeMask );
- event->message |= CHARMASK_BULLET | KEYMASK_BULLET;
- }
- }
- return( false );
- }
-
-
-
-
- void
- setpw( name, curr_srefnum )
- char *name; /* P-string */
- short curr_srefnum; /* if zero, we need to establish a connection */
- {
- short rc, len, clen, srefnum, cmd_result;
- char oldpw[ MAXPASSWDLEN + 1 ], oldpwsave[ MAXPASSWDLEN + 1 ];
- char newpw[ MAXPASSWDLEN + 1 ], abuf, *buf, *p, *q;
- Boolean success, already_connected;
- XPPParamBlock xpp;
- des_cblock sesskey;
- des_key_schedule ks;
- AddrBlock addr;
- DialogPtr dlp;
- GrafPtr saveport;
-
- /*
- * open the AppleTalk driver
- */
- bzero( (char*)&xpp, sizeof( XPPParamBlock ));
- if ( OpenXPP( &xpp.XPP.ioRefNum ) != noErr ) {
- doalert( ALRT_LOCALERR );
- return;
- }
-
- already_connected = ( curr_srefnum != 0 );
-
- /*
- * if we are not already connected, lookup server address
- */
- if ( !already_connected && lookup_address( afp_server, NBPTYPE_AFP,
- afp_zone, &addr ) != 0 ) {
- return;
- }
-
- success = false;
- GetPort( &saveport );
-
- while ( !success ) {
- /*
- * perform password set dialog to get old and new passwords
- */
- if (( dlp = setpwdialog( name, oldpw, newpw )) == NULL ) {
- SetPort( saveport );
- return;
- }
- strcpy( oldpwsave, oldpw );
-
- /*
- * set up for ASP calls
- */
- ParamText( afp_server, NULL, NULL, NULL );
- xpp.XPP.aspTimeout = 3; /* kind of arbitrary */
- xpp.XPP.ioCompletion = NULL;
-
- if ( already_connected ) {
- xpp.XPP.sessRefnum = curr_srefnum;
- if ( get_sesskey( curr_srefnum, sesskey ) != 0 ) {
- DisposDialog( dlp );
- SetPort( saveport );
- doalert( ALRT_LOCALERR );
- return;
- }
- } else {
- xpp.LOGIN.afpAddrBlock = addr;
- xpp.LOGIN.afpAttnRoutine = NULL;
- xpp.LOGIN.afpSCBPtr = NewPtrSysClear( scbMemSize );
-
- /*
- * call our login routine to log us in (we can't do the
- * change password call until we log in to the server)
- */
-
- if ( dologin( true, false, &xpp, name, oldpw, &srefnum, sesskey ) != 0 ) {
- /*
- * on error, send logout command (just in case)
- */
- abuf = afpLogout;
- xpp.XPP.cbPtr = &abuf;
- xpp.XPP.cbSize = 1;
- if( AFPCommand( &xpp, true ) == noErr ) {
- wait_for_completion( &xpp );
- }
- DisposPtr( xpp.LOGIN.afpSCBPtr );
- doalert( ALRT_OLDPWERR );
- DisposDialog( dlp );
- continue;
- }
- }
-
- ParamText( name, NULL, NULL, NULL );
-
- /*
- * send the afs_changepw command packet:
- * +-----+---------------------------+------------+--------+
- * | CMD | \pUser[.Instance][@Realm] | cipher len | cipher |
- * +-----+---------------------------+------------+--------+
- * where cipher is the following encrypted using the session key:
- * +---------------+---------------+----------------------------+
- * | \pOldPassword | \pNewPassword | padding to 8 byte multiple |
- * +---------------+---------------+----------------------------+
- */
- clen = strlen( oldpwsave ) + strlen( newpw ) + 2;
- if ( clen % 8 != 0 ) {
- len = clen / 8;
- clen = 8 * ( len + 1 );
- }
- xpp.XPP.cbSize = name[ 0 ] + 2 + clen + sizeof( short );
- if (( buf = NewPtrClear( xpp.XPP.cbSize )) == NULL ) {
- if ( !already_connected ) DisposPtr( xpp.LOGIN.afpSCBPtr );
- DisposDialog( dlp );
- SetPort( saveport );
- doalert( ALRT_LOCALERR );
- return;
- }
- p = xpp.XPP.cbPtr = buf;
- *p++ = AFP_AFSCHANGEPW;
- bcopy( name, p, name[ 0 ] + 1 );
- p += name[ 0 ] + 1;
- bcopy( (char *)&clen, p, sizeof( short ));
- p += sizeof( short );
- q = p;
- len = *p++ = strlen( oldpwsave );
- bcopy( oldpwsave, p, len );
- p += len;
- len = *p++ = strlen( newpw );
- bcopy( newpw, p, len );
- p += len;
- des_key_sched( sesskey, ks );
- des_pcbc_encrypt( q, q, clen, ks, &sesskey, DES_ENCRYPT );
-
- xpp.XPP.rbPtr = 0;
- xpp.XPP.rbSize = NULL;
- rc = ASPUserCommand( &xpp, true );
- if ( rc == noErr ) {
- rc = wait_for_completion( &xpp );
- }
- bzero( oldpwsave, strlen( oldpwsave ));
- bzero( newpw, strlen( newpw ));
- cmd_result = xpp.XPP.cmdResult;
- success = ( rc == 0 && cmd_result == 0 );
-
- /*
- * if we weren't connected before, send logout command (whether we
- * succeeded or not!)
- */
- if ( !already_connected ) {
- buf[ 0 ] = afpLogout;
- xpp.XPP.cbSize = 1;
- if ( AFPCommand( &xpp, true ) == noErr ) {
- wait_for_completion( &xpp );
- }
- DisposPtr( xpp.LOGIN.afpSCBPtr );
- }
-
- DisposPtr( buf );
-
- if ( !success ) {
- if ( rc == 0 && cmd_result == afpCallNotSupported ) {
- doalert( ALRT_SETPWNOTSUPP );
- } else if ( rc == 0 && cmd_result == afpUserNotAuth ) {
- doalert( ALRT_OLDPWERR );
- } else {
- doalert( ALRT_SETPWERR );
- }
- DisposDialog( dlp );
- continue;
- }
- }
-
- ParamText( name, NULL, NULL, NULL );
- DisposDialog( dlp );
- SetPort( saveport );
- doalert( ALRT_SETPWOK );
- return;
- }
-
-
- DialogPtr
- setpwdialog( name, oldpw, newpw )
- char *name; /* P-string */
- char *oldpw, *newpw; /* must be each MAXPASSWDLEN + 1 in size */
- {
- GrafPtr saveport;
- DialogPtr dlp;
- TEPtr tep;
- Boolean ok_enabled;
- Handle hdl;
- Rect r;
- Str255 ps;
- short item, type, oldpwlen, newpwlen, newpwlen1, passwds_entered;
- struct passwd_info passwds[ 3 ];
- char newpwconfirm[ MAXPASSWDLEN + 1 ];
-
- GetPort( &saveport );
- ParamText( name, NULL, NULL, NULL );
- placewindow( 'DLOG', SETPW_DLOG );
- if (( dlp = GetNewDialog( SETPW_DLOG, (Ptr)NULL, (WindowPtr)-1 )) == NULL ) {
- doalert( ALRT_LOCALERR );
- return( NULL );
- }
- SetPort( dlp );
- passwds_entered = 0;
- ok_enabled = false;
- enablebutton( dlp, DLOG_OK, false, true );
- oldpwlen = newpwlen = 0;
- passwds[ 0 ].pwinfo_passwd = oldpw;
- passwds[ 0 ].pwinfo_dlogitem = DLOG_OLDPW;
- passwds[ 1 ].pwinfo_passwd = newpw;
- passwds[ 1 ].pwinfo_dlogitem = DLOG_NEWPW;
- passwds[ 0 ].pwinfo_maxlen = passwds[ 1 ].pwinfo_maxlen = MAXPASSWDLEN;
- passwds[ 2 ].pwinfo_passwd = NULL;
- *newpw = *oldpw = *newpwconfirm = '\0';
- ((WindowPeek)dlp)->refCon = (char *)passwds;
- passwds_entered = 0;
-
- while( passwds_entered < 2 ) {
- do {
- ModalDialog( (ModalFilterProcPtr)passwdfilter, &item );
-
- tep = *(((DialogPeek)dlp)->textH);
- if ( ((DialogPeek)dlp)->editField == DLOG_OLDPW - 1 ) {
- oldpwlen = tep->teLength;
- } else {
- newpwlen = tep->teLength;
- }
- if ( ok_enabled && ( newpwlen < MINPASSWDLEN || oldpwlen < MINPASSWDLEN )) {
- enablebutton( dlp, DLOG_OK, false, true );
- ok_enabled = false;
- } else if ( !ok_enabled && ( newpwlen >= MINPASSWDLEN &&
- oldpwlen >= MINPASSWDLEN )) {
- enablebutton( dlp, DLOG_OK, true, true );
- ok_enabled = true;
- }
-
- } while ( item != DLOG_OK && item != DLOG_CANCEL );
-
- if ( item == DLOG_CANCEL ) {
- DisposDialog( dlp );
- SetPort( saveport );
- return( NULL );
- }
-
- if ( ++passwds_entered == 1 ) {
- newpwlen1 = newpwlen;
- newpwlen = 0;
- GetDItem( dlp, DLOG_NEWPW_TEXT, &type, &hdl, &r );
- SetIText( hdl, "\pReenter New Password:" );
- *newpwconfirm = '\0';
- GetDItem( dlp, DLOG_NEWPW, &type, &hdl, &r );
- SetIText( hdl, "\p" );
- SelIText( dlp, DLOG_NEWPW, 0, 1 );
- GetDItem( dlp, DLOG_OLDPW, &type, &hdl, &r );
- type = statText;
- SetDItem( dlp, DLOG_OLDPW, type, hdl, &r );
- r.top -= 4;
- r.left -= 4;
- r.bottom += 4;
- r.right += 4;
- EraseRect( &r );
- InvalRect( &r );
- passwds[ 1 ].pwinfo_passwd = newpwconfirm;
- DrawDialog( dlp );
- enablebutton( dlp, DLOG_OK, false, true );
- ok_enabled = false;
- } else {
- oldpw[ oldpwlen ] = '\0';
- newpw[ newpwlen1 ] = '\0';
- newpwconfirm[ newpwlen ] = '\0';
- GetDItem( dlp, DLOG_NEWPW_TEXT, &type, &hdl, &r );
- SetIText( hdl, "\p New Password:" );
-
- if ( strcmp( newpw, newpwconfirm ) != 0 ) {
- doalert( ALRT_PWMISMATCH );
- passwds[ 1 ].pwinfo_passwd = newpw;
- *oldpw = *newpw = '\0';
- oldpwlen = newpwlen = 0;
- GetDItem( dlp, DLOG_OLDPW, &type, &hdl, &r );
- SetIText( hdl, "\p" );
- type = editText;
- SetDItem( dlp, DLOG_OLDPW, type, hdl, &r );
- GetDItem( dlp, DLOG_NEWPW, &type, &hdl, &r );
- SetIText( hdl, "\p" );
- SelIText( dlp, DLOG_OLDPW, 0, 0 );
- passwds_entered = 0;
- enablebutton( dlp, DLOG_OK, false, true );
- ok_enabled = false;
- }
- }
- }
- HideDItem( dlp, DLOG_OK );
- HideDItem( dlp, DLOG_CANCEL );
- return( dlp );
- }
-
-
- short
- lookup_address( obj, type, zone, addrp )
- char *obj; /* p-string */
- char *type; /* p-string */
- char *zone; /* p-string */
- AddrBlock *addrp;
- {
- /*
- * do an NBP Lookup on obj/type/zone, return result in addrp (non-zero return code if error)
- * note: AppleTalk must be loaded (open .XPP) before calling this routine
- */
- EntityName en;
- ATNBPRecHandle abhdl;
- short rc, count;
- char *buf;
-
- bcopy( obj, en.objStr, obj[ 0 ] + 1 );
- bcopy( type, en.typeStr, type[ 0 ] + 1 );
- bcopy( zone, en.zoneStr, zone[ 0 ] + 1 );
- if (( abhdl = (ATNBPRecHandle)NewHandle( sizeof( ATNBPRec ))) == NULL ||
- ( buf = NewPtr( 256 )) == NULL ) {
- doalert( ALRT_LOCALERR );
- return( -1 );
- }
- HLock( (Handle)abhdl );
- (*abhdl)->nbpEntityPtr = &en;
- (*abhdl)->nbpBufPtr = buf;
- (*abhdl)->nbpBufSize = 256;
- (*abhdl)->nbpDataField = 1;
- (*abhdl)->nbpRetransmitInfo.retransInterval = 10; /* a little over a second */
- (*abhdl)->nbpRetransmitInfo.retransCount = 5;
- rc = NBPLookup( abhdl, false );
- count = (*abhdl)->nbpDataField;
- if ( rc == noErr && count == 1 ) {
- rc = NBPExtract( buf, count, 1, &en, addrp );
- }
-
- HUnlock( (Handle)abhdl );
- DisposPtr( buf );
- DisposHandle( (Handle)abhdl );
- if ( rc != noErr || count != 1) {
- doalert( ALRT_REMOTEERR );
- return( -1 );
- }
-
- return( 0 );
- }
-
-
- short
- get_server_status( iorefnum, addr, iconhdlp, supports_setpwp )
- short iorefnum; /* from .XPP open */
- AddrBlock addr;
- Handle *iconhdlp;
- Boolean *supports_setpwp;
- {
- /*
- * do an ASP get status network call to server at "addr" and return handle to the server's
- * icon (if available)
- * note: AppleTalk must be loaded (open .XPP) before calling this routine
- */
- XPPPrmBlk xpp;
- char *buf;
- short off, flags;
-
- if (( buf = NewPtr( 1000 )) == NULL ) {
- doalert( ALRT_LOCALERR );
- return( -1 );
- }
-
- xpp.ioRefNum = iorefnum;
- xpp.aspTimeout = 3;
- xpp.aspRetry = 3;
- bcopy( (char *)&addr, (char *)&xpp.cbSize, sizeof( long ));
- xpp.rbPtr = buf;
- xpp.rbSize = 1000;
- if ( ASPGetStatus( (XPPParmBlkPtr)&xpp, false ) != noErr ) {
- doalert( ALRT_REMOTEERR );
- DisposPtr( buf );
- return( -1 );
- }
-
- bcopy( buf + 6, (char *)&off, sizeof( short ));
- if ( off != 0 ) {
- *iconhdlp = NewHandle( 128 );
- HLock( *iconhdlp );
- bcopy( buf + off, (char *)**iconhdlp, 128 );
- HUnlock( *iconhdlp );
- } else {
- *iconhdlp == NULL;
- }
- bcopy( buf + 8, (char *)&flags, sizeof( short ));
- *supports_setpwp = flags & AFPSRVRINFO_PASSWD;
- DisposPtr( buf );
- return( 0 );
- }
-
-
- short
- get_sesskey( srefnum, sesskey )
- short srefnum;
- des_cblock sesskey;
- {
- /*
- * retrieve the session key from res. file
- * return non-zero if can't get the key)
- */
- Handle hdl;
-
- if (( hdl = Get1Resource( 'skey', srefnum )) == NULL ||
- SizeResource( hdl ) != 8 ) {
- return( -1 );
- }
- HLock( hdl );
- BlockMove( *hdl, sesskey, sizeof( des_cblock ));
- HUnlock( hdl );
- ReleaseResource( hdl );
- return( 0 );
- }
-
-
- void
- enablebutton( dp, button, enable, frame )
- DialogPtr dp;
- short button;
- Boolean enable, frame;
- {
- PenState pstate;
- short type;
- Handle hdl;
- Rect r;
-
- GetPenState( &pstate );
- GetDItem( dp, button, &type, &hdl, &r );
- if ( enable ) {
- PenPat( qd.black );
- type &= ~itemDisable;
- HiliteControl( (ControlHandle)hdl, 0 );
- } else {
- PenPat( qd.gray );
- type |= itemDisable;
- HiliteControl( (ControlHandle)hdl, 255 );
- }
- SetDItem( dp, button, type, hdl, &r );
- if ( frame ) {
- InsetRect( &r, -4, -4 );
- PenSize( 3, 3 );
- FrameRoundRect( &r, 16, 16 );
- }
- SetPenState( &pstate );
- }
-
-
- void
- doalert( alert )
- short alert;
- {
- InitCursor();
- placewindow( 'ALRT', alert );
- NoteAlert( alert, (ModalFilterProcPtr)NULL );
- }
-
-
- void
- lncase( q, n )
- char *q;
- int n;
- {
- for ( ; *q && n > 0; n--, q++ ) {
- if ( isupper( *q )) {
- *q = tolower( *q );
- }
- }
- }
-
-
- void
- placewindow( rtype, rid )
- ResType rtype;
- short rid;
- /*
- * set "rtype", "rid" window rectangle to be "alert" position (centered, 1/3 showing above & below)
- */
- {
- Handle hdl;
- Rect *rp;
- short left, top;
-
- if (( hdl = GetResource( rtype, rid)) != NULL ) {
- rp = (Rect*) *hdl;
- left = ( qd.screenBits.bounds.right - ( rp->right - rp->left)) / 2;
-
- top = ( qd.screenBits.bounds.bottom - ( rp->bottom - rp->top)) / 3;
-
- if ( top < 41 ) { /* magic number to allow for window border & */
- top = 41; /* menu bar height */
- }
-
- rp->right += left - rp->left;
- rp->left = left;
- rp->bottom += top - rp->top;
- rp->top = top;
- }
- }
-
- void
- mysetup_A5( globalmem, newA5p )
- Ptr globalmem;
- long *newA5p;
- {
- *newA5p = (long)globalmem + A5Size() - 32;
- A5Init( *newA5p );
- }
-
-
- void
- myrestore_A5( oldA5 )
- long oldA5;
- {
- SetA5( oldA5 );
- }
-
-
- void
- mysetup_QD( oldA5 )
- {
- /*
- * copy QuickDraw globals from old A5 space to new A5 space
- */
- BlockMove( (Ptr) (*((long *)oldA5) + sizeof( GrafPtr ) - QDSIZE), (Ptr)&qd, QDSIZE );
- }
-
-
-