The solution:
Since O4W systems are already “in the wild” with clear-text passwords stored in the O4WPERMS table, the 1.0→1.1 O4WUpgrade process will:
The user maintenance screen has been modified to comply with the ideas above:
The O4W Login process has been modified to comply with the ideas above:
The default login authorization routine (O4WI_AUTHORIZE) has been modified to accept _3_ parameters: the username, the hashed value sent by the browser, and the current time value;
O4WI_AUTHORIZE will now:
If the two values match, the user is authorized to proceed;
Developers who specify their own custom authorization routines (via the O4WCONFIG record) will continue to be passed 2 parameters (the username and the UNENCRYPTED password);
Developers who wish to use the encryption routines to make their systems secure, but who still wish to have a custom authorization routine, may do so by creating an authorization routine whose name ends in “ENCRYPT” (ie, “MYCUSTOMPROC_ENCRYPT”). If the authorization routine’s name ends in “ENCRYPT”, O4W’s login process will instruct the browser to encrypt the password, and send that authorization routine the same 3 parameters as O4WI_AUTHORIZE.
New utility function: O4WI_ENCRYPT
The O4WI_ENCRYPT routine takes up to 3 parameters; the first 2 are mandatory, the last one is optional:
FUNCTION O4WI_ENCRYPT(param1, param2 {, param3})
It performs a “hash” on the first two parameters, and then (optionally) hashes that value with the third parameter;
This function is used by the O4WI_AUTHORIZE and O4WUPGRADE routines to generate and validate the hashed value, and could be used by a developer’s custom authorization routine that also used encrypted values;
This function relies on an updated RTI_MD5 to perform an “hmac sha1” hash
New O4WQUALIFYEVENT event: ENCRYPT
The O4WQUALIFYEVENT function has been enhanced to support a new ‘event’, “ENCRYPT”:
O4WQUALIFYEVENT(“<sourceID>”, “ENCRYPT”, “<targetID>”, “<hash_param1>” {, “<hash_param2>”})
<sourceID> and <targetID> are the O4W IDs of the field to encrypt and destination for the hash, respectively;
<hash_param1> is the O4W ID or literal string (enclosed in quotes) to use when hashing the <sourceID>
<hash_param2>, if specified, is the O4W ID or literal string (enclosed in quotes) to use when hashing the hash generated in the previous step
Specifying this event will generate a script that, when the contents of the <sourceID> control have been modified, and the control has “lost focus”, will hash the value stored in the <sourceID> control against the one or two other values, and store the result in the <targetID> control. In addition, it will change the value in the <sourceID> control to a known value, not related to its original value, so that the original entered value is never transmitted to the host
Example:
CASE EVENT _EQC ‘CREATE’ * … initial code …. O4WStore(“”, “myHash”, “myHash”) ;* the control where we’ll store the hashed result O4WPassword(“”, “”, “”, “ourPWD”, “ourPWD”) ;* the control where the user will type in the password O4WQualifyEvent(‘ourPWD’, ‘ENCRYPT’, ‘myHash’, ‘”b8291af880217262cc82965”’) ;* hash the value that’s been entered into ourPWD against the literal string and put the hashed value into myHash * … more code … CASE EVENT _EQC “CLICK” pwdHash = O4WGetValue(“myHash”) ;* hashed password value dummyPwd = O4WGetValue(“ourPWD”) ;* not used - always return “eNcRyPtEd” as the text * … validation code …
In practice, the <hash_param1> will usually be the “seed” value stored in the DICT O4WPERMS “SALT” record, field 2