/*****************************************************************************/ #ifdef COMMENTS_WITH_COMMENTS /* Login.c THE GNU GENERAL PUBLIC LICENSE APPLIES DOUBLY TO ANYTHING TO DO WITH AUTHENTICATION AND AUTHORIZATION! This package is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 2 of the License, or any later version. > This package is distributed in the hope that it will be useful, > but WITHOUT ANY WARRANTY; without even the implied warranty of > MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the > GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. DESCRIPTION ----------- This module provides the core of a soyMAIL autogenous (inherent, internal) authentication system. It does so by accepting username and password form field values from a login page and authenticating these credentials using internal code. Once authenticated it propagates the username/password strings from request to request, along with some other credential maintenance data, so that the client can be transparently re-authenticated periodically to keep the session valid. Obviously propagating sensitive data such as passwords around over a network has it's dangers. With normal HTTP authorization fields this happens all the time (the credentials are base-64 encoded but not encrypted making them trivial to discover). This is why it is best for such transactions to occur using SSL. Certainly with SYSUAF based authentication you would imagine this to be mandatory. So it shouldn't be a real issue as far as the transaction goes but such information also shouldn't be trivially recovered from either the HTML or other browser source, or from cookie content. Hence soyMAIL encrypts the credential data using the RC4 algorithm and a minimum 192 bit key (24 characters) supplied from site configuration. This makes it non-trivial to recover such data. Also, when soyMAIL is logged-out the content of those credentials are removed from the browser. The best-case would be to authenticate every request. This would obviously generate some significant authentication load on a busy system. Therefore to reduce this potential load soyMAIL only authenticates periodically, at initial login (obviously) and then every five minutes by default, although this is configurable. Requests during the interim have the credentials unencrypted and provided they pass sanity checks by soyMAIL the username is used for that request. Sessions are also tracked for idle time. If more than this period occurs between successive requests soyMAIL will present the login page and require reauthentication. (See IDLE SESSION TIMEOUT below.) Idle time is one hour by default but is configurable. This might be considered relatively inconvenient when about to [send] a message composed some time ago but by using cookies, once re-authenticated, automatically (see below), or manually, return to the previous page and continue with the refreshed cookie content. To effectively disable idle timeouts set it to something large (e.g. 30000000 seconds - ~1 year :-) Careful though, it's a U**x integer time and will overflow easily! RC4 ENCRYPTION -------------- I am certainly not a cryptography specialist so be sure to take anything (and everything) I say here with a large pinch of salt! RC4 is a very commonly deployed, efficient and arguably safe-enough encryption scheme. http://en.wikipedia.org/wiki/Rc4 While not necessarily authoritative the above reference states: "In cryptography, RC4 (also known as ARC4 or ARCFOUR) is the most widely-used software stream cipher and is used in popular protocols such as Secure Sockets Layer (SSL) (to protect Internet traffic) ... While remarkable in its simplicity, RC4 falls short of the high standards of security set by cryptographers ... However, some systems based on RC4 are secure enough for practical use." And into that latter category soyMAIL (hopefully) falls. Keep your browser secure while in use and [logout] to clear the actual encrypted content when appropriate. To assist in keeping the credential encryption secure ensure the SOYMAIL_CONFIG file is protected for general access and ensure the [login-secret] string used for the encryption key contains a whole range of characters. soyMAIL insists this key is at least 24 characters in length. An *example* key might be [login-secret] aic84+-[QsfOPa,dk;'12ndjve64_90mhd43m*2$ The secret can be modified at any time but consider that client sessions currently in-progress will require to re-login the next time they access soyMAIL. For implementation detail see module RC4.C The encrypted data is additionally base-64 encoded to make it suitable for character-oriented schemes such as HTTP cookies. CREDENTIALS COOKIE ------------------ Some mechanism for conveying the login credentials from request to request was required. This is often done via a form field or request query string component, either directly or as a 'session ID' of some description. This involves the explicit inclusion of such a field with every form or request query string generated by the application. It effectively can be hidden in a form but must appear obvious in GET request query strings (and as a consequence is included in access logs). It was decided due to the above disadvantages to use HTTP cookies. For all their issues and the disdain in which they are held by some they are an effective and transparent mechanism for providing state information of all sorts with HTTP requests and so have become the chosen mechanism for soyMAIL autogenous authentication. Don't like them? Well use server-configured HTTP authorization! INTERNAL COOKIE STRUCTURE ------------------------- The cookie value is a base-64 encoded, RC4-encrypted series of null-terminated ASCII strings, along with a couple of fixed, single-byte fields. Some strings represent numbers, others text. When a cookie value is generated the data strings are preceded by a variable-length, ASCII hexadecimal number (generated from a binary time component). This serves to add some quasi-indeterminate data to the mix and results in startlingly different encrypted/encoded cookie values each time one is generated (and is therefore perhaps of benefit to encryption security through an obfuscation factor). Following the hex number is a single, non-zero byte, indicating the cookie structure version, and used to detect possible future changes to the structure, then a single character, either 'L' or 'C' to differentiate the following two structures: 1) The 'login' cookie; used during the login process. After the hexadecimal data is an 'L' and then a number representing the count of the login attempts. The second string contains either the username of any previous session, or is empty. This is used to determine whether the new login is for the same user as any previous session, and so if the login count should be used to return to the last relevant page in the browser history. One of these might look something like, plain and encrypted/encoded (where \0 are the null-terminators, and \1 the current version byte): D2B45\0\1L1\0DANIEL\0 OqycxO8ffs1lPBqIZEHLlg== 2) The 'credentials' cookie; used once logged-in to maintain the session and provide the credentials for periodic revalidation. Following the hexadecimal number is a 'C'. Then a decimal number, the U**x time in seconds, after which the session is considered idle. Following that another decimal number, the U**x time in seconds, after which the session credentials are revalidated against the authentication source. Following these are four strings; the IP address of the client (from CGI variable REMOTE_ADDR), any alias user name supplied during login (or '*' to indicate none), the authenticated (usually VMS) username, and the supplied password. A credentials cookie looks something like, plain and encrypted/encoded: 51F0A88\0\1C1160471530\01160467960\0192.168.1.2\0*\0DANIEL\0PASSWORD\0 SZX9Lf8uefaXl3fsAzazonP0mV6pTa6hWg296nb/EnE8rIxdH4Lxj1KBWrCmfOVZtrdQnnBUisZmP It should be emphasised that the credential data is transmitted and stored encrypted. It is only plain data when being handled internally by soyMAIL. LOGIN PAGE ---------- The core content of the login page is supplied via a file, by default [.THEME]LOGIN.HTML, though the configuration directive [login-page] can specify an alternative. If a local customisation is undertaken it is suggested to copy the default to say something like [.THEME]_LOGIN.HTML and modify and configure that. This approach offers considerable flexibility in providing language-specific and site-specific information at the point of soyMAIL login. DO NOT CHANGE anything like form field names, etc. Only the markup! ACME AUTHENTICATOR ------------------ The Authentication and Credentials Management Extensions (ACME) subsystem provides authentication and persona-based credential services. Applications use these services to enforce authentication policies defined by ACME agents running in the context of the ACME_SERVER process. Note that there are some behavioural differences between the ACME and SYSUAF authenticators. Only for VMS V7.3 or later. Relies on the image being INSTALLed with /AUTHPRIVILEGE=(IMPERSONATE) so that it can use $ACMW. SYSUAF AUTHENTICATOR -------------------- On platforms that do not support ACME a composite authenticator is provided using $SCAN_INTRUSION and $GETUAI. This implementation checks for disusered flag, etc., primary password, password expiry (primary and secondary). It also checks and maintains the intrusion database. Every effort has been made to ensure this authenticator is robust but no guarantees. Note that there are some behavioural differences between the ACME and SYSUAF authenticators. The SYSUAF authenticator is a much simpler (and incomplete) implementation in comparison to ACME. I'd much rather rely on an Engineering maintained service such as $ACM! But it's there is you want it. Relies on the image being INSTALLed with /AUTHPRIVILEGE=(SECURITY) so that it can use $SCAN_INTRUSION. PASSWORD CHANGE --------------- soyMAIL provides configurable password change. Both the ACME and SYSUAF authenticators can perform this. The change can be triggered by password expiry or the presence of a '[x] change password' checkbox on the login page. Obviously ACME is going to provide a more robust function. The SYSUAF based password change attempts to allow for all the wrinkles basic password maintenance provides (character and password length restrictions, etc.) but provides no dictionary checking, password history, etc. ENABLING PASSWORD MODIFIFICATION ON PLATFORMS THAT DON'T SUPPORT ACME SHOULD NOT BE DONE LIGHTLY. The ortha pruvides no garruntees!! The configuration directive should be set to the default change page [login-change-page] SOYMAIL_THEME:CHANGE.HTML or, as with the login page, to a local customisation of the default [login-change-page] SOYMAIL_THEME:_CHANGE.HTML AGENT AUTHENTICATOR ------------------- If the [login-agent] configuration directive exists then it activates an external authentication DCL procedure within a subprocess. The DCL procedure must be specified following an '@' symbol and must have execute permission for the scripting account. For example: [login-agent] @cgi-bin:[000000]soymail_authage.com Optional parameters can be provided as part of the configuration directive: [login-agent] @cgi-bin:[000000]soymail_authage.com "param1" "PARAM2" When activated the procedure has a further three parameters appended to any supplied in the above configuration directive; "", "" and "", to be used in the authentication processing. The procedure should exit with any success status (e.g. SS$_NORMAL) to indicate successful authentication or any error status (e.g. SS$_NOPRIV) to indicate authentication failure. To indicate the credentials are OK but they do not allow access return SS$_CONTROLO (a success status). This is a (very simple) example. $ SET ON $ OK = 1 $ NOPRIV = 36 $ P1 = F$EDIT(P1,"UPCASE") $ IF P1 .EQS. "CURLY" .AND. P2 .EQS. "JeromE" THEN EXIT OK $ IF P1 .EQS. "LARRY" .AND. P2 .EQS. "lOUIs" THEN EXIT OK $ IF P1 .EQS. "MOE" .AND. P2 .EQS. "harrY" THEN EXIT OK $ EXIT NOPRIV This would probably be more like a working one. $ SET ON $ SOYAUTH = "$location:SOYAUTH.EXE" $ SOYAUTH "''P1'" "''P2'" "''P3'" $ EXIT $STATUS This is a(nother very simple) example showing an autogenous authorization agent denying access to the path /noaccess/ using a SS$_CONTROLO exit status. $ SET ON $ OK = 1 $ NOPRIV = 36 $ CONTROLO = 1545 $ P1 = F$EDIT(P1,"UPCASE") $ IF P1 .EQS. "CURLY" .AND. P2 .EQS. "JeromE" THEN GOTO ISOK $ IF P1 .EQS. "LARRY" .AND. P2 .EQS. "lOUIs" THEN GOTO ISOK $ IF P1 .EQS. "MOE" .AND. P2 .EQS. "harrY" THEN GOTO ISOK $ EXIT NOPRIV $ ISOK: $ IF WWW_PATH_INFO .EQS. "/noaccess/" THEN EXIT CONTROLO $ EXIT OK See further comments under AUTHORIZED PUBLIC ACCESS in CONFIG.C. LOGIN ALIAS ----------- For autogenous authentication the configuration directive [login-alias] allows the user-supplied 'username' strings to be mapped to other strings before being authenticated. An example use might be using the user email address, or local mailbox name, as the 'username' and mapping that to a VMS username before authenticating against the SYSUAF. The alias mapping is performed using a case-insensitive match. The format is one alias mapping per line. [login-alias] Mark.Daniel/DANIEL Fred.Bloggs/BLOGGS If a match is not made and no mapping has occurred the default (drop-through) behaviour is to use the original user-supplied 'username' string and so in the above configuration both "Mark.Daniel" and "DANIEL" would authenticate against the DANIEL account, "Fred.Bloggs" and "BLOGGS" against BLOGGS. Of course any other supplied username could also authenticate directly using the username. To prevent any other than an aliased username being used for authentication conclude the list with "*/-". [login-alias] Mark.Daniel/DANIEL Fred.Bloggs/BLOGGS */- In the above example only "Mark.Daniel" and "Freg.Bloggs" can be supplied to allow authentication. The (somewhat redundant) mapping "*/*" will explicitly direct authentication to occur using the supplied 'username' (the default drop-through behaviour anyway). IDLE SESSION TIMEOUT -------------------- What is required is to save the *entire* state of a request being processed by soyMAIL. That way, if a session requires re-authentication, the session can be continued in a non-disruptive and transparent fashion. This has proved particularly problematic (thanks to Bill Korendyk testing and discovering limitations with the initial approach). Originally soyMAIL would use JavaScript and the browser history object to return to the page immediately preceding the (re-)login page. Unfortunately some browsers (Firefox at least) somehow did not restore the content of edited