Q: My code needs to set the password used by ARA/PPP, but I can't find any documentation on how the password works. How do I create a password resource?
A: The Open Transport ARA/PPP password for a given configuration is stored in the 'pass' resource of the "Remote Access Connections" file, which resides in the "Remote Access" preference folder. As of ARA version 2.0, the size of the 'pass' resource has been extended to 256 bytes.
The actual password data is encoded using the Data
Encryption Standard (DES) algorithm in Electronic Code Book
(ECB) Mode. The key schedule for the encryption is derived
from the first 56 bits (7 bytes) of the ARA/PPP
configurations user name.
Currently there is no Open Transport API for encoding the
ARA password. However, since the password is encoded using
ECB mode of DES, it is possible to use the
PassWordMunger function of the older Apple
Remote Access API to encode a modern ARA/PPP password.
To properly encode the password, you must first zero pad
the password data in a 256-byte buffer. Then, encode the
cleartext password 8 bytes at a time using the user name
string as a key, appending the result to the
'pass' resource until all 256 bytes are
processed. When you have completed this, zero out the first
byte of the 'pass' resource.
This process is illustrated in the following code
snippet, taken from the MoreNetworkSetup module of the DTS
MoreIsBetter library.
static OSStatus EncodeRemotePasswordARA(
ConstStr255Param userName,
ConstStr255Param password,
Str255 encodedPassword)
// Encodes a password using the ARA API.
{
OSStatus err;
TRemoteAccessPasswordMunger pb;
UInt8 chunkOfPassword[9];
ByteCount offset;
// Zero the encoded password buffer and copy the
// password (sans length byte) into it.
OTMemzero(encodedPassword, sizeof(Str255));
BlockMoveData(&password[1], encodedPassword, password[0]);
// Now walk through the password in chunks, copying
// a chunk into the chunkOfPassword buffer, encrypting
// that buffer with the ARA API, and then copying the
// buffer back out to the encrypted password.
// Note that the for loop increments offset by 8 each time.
for (offset = 0; offset < 256 ; offset += 8) {
// Copy a chunk of the password into chunkOfPassword.
BlockMoveData(encodedPassword + offset, &chunkOfPassword[1], 8);
chunkOfPassword[0] = 8;
// Setup the parameter block for a remote access API call.
pb.csCode = RAM_EXTENDED_CALL;
pb.resultStrPtr = nil;
pb.extendedType = (char*) REMOTEACCESSNAME;
pb.extendedCode = CmdRemoteAccess_PassWordMunger;
pb.userNamePtr = (UInt8 *) userName;
pb.passWordPtr = chunkOfPassword;
pb.reserved = 0;
err = PBRemoteAccess((TPRemoteAccessParamBlock) &pb, false);
if (err == noErr) {
err = pb.ioResult;
}
if (err == noErr) {
// Copy the encrypted chunk of password back out into
// encodedPassword.
BlockMoveData(&chunkOfPassword[1], encodedPassword + offset, 8);
} else {
break;
}
}
// Tidy up encoded password. Move the encrypted data up
// one byte and insert a zero length byte. Don't ask me
// why this is required, I didn't invent this scheme (-:
BlockMoveData(encodedPassword, encodedPassword + 1, sizeof(Str255) - 1);
encodedPassword[0] = 0;
return err;
}
|
Once you have processed the encoded the password, you can
set the actual 'pass' resource in a number of
ways:
- The preferred method is to use the Network Setup
API, which is part of Open Transport 2.0 included
with MacOS 8.5. The Network Setup SDK really is the
proper long-term solution to accessing the configuration
database. A good example of how to use this API can be
found in the DTS sample code
More
NetworkSetup.
- As an alternative, you can send an AppleEvent to
Network Setup Scripting to set the password for a
given configuration. This is described below.
Note: Version 1.0 of Network Setup
Scripting does not encode the password properly; use
version 1.0.2 or newer.
--setpassword("Configuration", "password")
on setpassword(configName, thePassword)
tell application "Network Setup Scripting"
open database
begin transaction
set password of Remote Access configuration
configName to thePassword
end transaction
close database
end tell
end setpassword
|
- As a last resort, your code could open and write into
the "Remote Access Connections" file directly. This
method is risky and I highly recommend against it. Since
ARA could open it at any time, you run the risk of
corrupting the file's resource map. There is also no
promise that the preference file data formats will not
change in the future.
At some point in the future, we hope that the Network
Setup API will provide an interface for encoding the
password. Until that happens, the above example should be
sufficient.
|