/*****************************************************************************/
/*
                                 Auth.h
*/
/*****************************************************************************/

#ifndef AUTH_H_LOADED
#define AUTH_H_LOADED 1

#include "wasd.h"

/* some storage maximums */
#define  AUTH_MAX_DIGEST_RESPONSE      32
#define  AUTH_MAX_PASSWORD_LENGTH      31
#define  AUTH_MAX_REALM_GROUP_LENGTH   32
#define  AUTH_MAX_REALM_DESCR_LENGTH  127
#define  AUTH_MAX_USERNAME_LENGTH      47  /* for X509 fingerprints */
#define  AUTH_MAX_HTA_USERNAME_LENGTH  15  /* MUST remain at 15 */
#define  AUTH_MAX_FULLNAME_LENGTH      31
#define  AUTH_MAX_EMAIL_LENGTH        127
#define  AUTH_MAX_CONTACT_LENGTH      127
#define  AUTH_MAX_REALM_PARAM_LENGTH  127
#define  AUTH_MAX_COOKIE_CACHE         32

#define  AUTH_LOGIN_COOKIE_NAME  "WASDlgn"

/* password minimum (when changing in HTADMIN.C) */
#define  AUTH_MIN_PASSWORD 6

/* maximum number of VMS identifiers in array */
#define  AUTH_MIN_VMS_IDENTIFIERS 64
#define  AUTH_MAX_VMS_IDENTIFIERS 1024

/* size of static storage allocated for sys$create_user_profile() use */
#define AUTH_CREATE_USER_PROFILE_SIZE 2048

/* constants used to identify authorization schemes */
#define  AUTH_SCHEME_BASIC    0x00000001
#define  AUTH_SCHEME_DIGEST   0x00000002
#define  AUTH_SCHEME_X509     0x00000003
#define  AUTH_SCHEME_RFC1413  0x00000004
#define  AUTH_SCHEME_NO401    0x00000005

/* constants for bits for flags in HTA database */
#define  AUTH_FLAG_GET         0x00000001
#define  AUTH_FLAG_HEAD        0x00000002
#define  AUTH_FLAG_POST        0x00000004
#define  AUTH_FLAG_PUT         0x00000008
#define  AUTH_FLAG_DELETE      0x00000010
#define  AUTH_FLAG_CONNECT     0x00000020
#define  AUTH_FLAG_HTTPS_ONLY  0x20000000
#define  AUTH_FLAG_MANAGER     0x40000000
#define  AUTH_FLAG_ENABLED     0x80000000

#define  AUTH_READWRITE_ACCESS  HTTP_METHOD_CONNECT | \
                                HTTP_METHOD_DELETE | \
                                HTTP_METHOD_GET | \
                                HTTP_METHOD_HEAD | \
                                HTTP_METHOD_POST | \
                                HTTP_METHOD_PUT

#define  AUTH_READONLY_ACCESS   HTTP_METHOD_GET | \
                                HTTP_METHOD_HEAD

#define  AUTH_WRITEONLY_ACCESS  HTTP_METHOD_POST | \
                                HTTP_METHOD_PUT

#define  AUTH_REALM_ACME         "ACME"
#define  AUTH_REALM_EXTERNAL     "EXTERNAL"
#define  AUTH_REALM_FAIL         "-FAIL-"
#define  AUTH_REALM_NONE         "NONE"
#define  AUTH_REALM_PROMISCUOUS  "PROMISCUOUS"
#define  AUTH_REALM_RFC1413      "RFC1413"
#define  AUTH_REALM_SKELKEY      "SKELKEY"
#define  AUTH_REALM_VMS          "VMS"
#define  AUTH_REALM_WORLD        "WORLD"
#define  AUTH_REALM_X509         "X509"

#define  AUTH_SOURCE_FAIL          1
#define  AUTH_SOURCE_NONE          2
#define  AUTH_SOURCE_WORLD         3
#define  AUTH_SOURCE_EXTERNAL      4
#define  AUTH_SOURCE_VMS           5
#define  AUTH_SOURCE_ID            6
#define  AUTH_SOURCE_ACME          7
#define  AUTH_SOURCE_LIST          8
#define  AUTH_SOURCE_DIR_LIST      9
#define  AUTH_SOURCE_HTA          10
#define  AUTH_SOURCE_DIR_HTA      11
#define  AUTH_SOURCE_WASD_ID      12
#define  AUTH_SOURCE_AGENT        13
#define  AUTH_SOURCE_X509         14
#define  AUTH_SOURCE_RFC1413      15
#define  AUTH_SOURCE_HOST         16
#define  AUTH_SOURCE_PROMISCUOUS  17
#define  AUTH_SOURCE_SKELKEY      18

#define  HTA_DIRECTORY     "HT_AUTH:"
#define  HTA_FILE_TYPE     ".$HTA"
#define  HTL_FILE_TYPE     ".$HTL"
#define  AUTH_AGENT_PATH   "/cgiauth-bin/"

/* bogus VMS status codes (errors), these can be passed back and detected */
#define  AUTH_DENIED_BY_FAIL      0x0fffff1a
#define  AUTH_DENIED_BY_GROUP     0x0fffff2a
#define  AUTH_DENIED_BY_HOSTNAME  0x0fffff3a
#define  AUTH_DENIED_BY_HOUR      0x0fffff4a
#define  AUTH_DENIED_BY_LOGIN     0x0fffff5a
#define  AUTH_DENIED_BY_LOGOUT    0x0fffff6a
#define  AUTH_DENIED_BY_NOCACHE   0x0fffff7a
#define  AUTH_DENIED_BY_OTHER     0x0fffff8a
#define  AUTH_DENIED_BY_PROTOCOL  0x0fffff9a
#define  AUTH_DENIED_BY_USERNAME  0x0fffffaa
#define  AUTH_DENIED_BY_REDIRECT  0x0fffffba
#define  AUTH_PENDING             0x0fffffca

/* identifier names controlling SYSUAF authentication with /SYSUAF=ID */
#define  AUTH_HTTPS_ONLY_VMS_ID        "WASD_HTTPS_ONLY"
#define  AUTH_NIL_ACCESS_VMS_ID        "WASD_NIL_ACCESS"
#define  AUTH_PASSWORD_CHANGE_VMS_ID   "WASD_PASSWORD_CHANGE"
#define  AUTH_PROXY_ACCESS_VMS_ID       "WASD_PROXY_ACCESS"

/* identifier names controlling SYSUAF authentication with /SYSUAF=WASD */
#define  AUTH_WASD__GROUP_VMS_ID  "WASD_VMS__"
#define  AUTH_WASD_HTTPS_VMS_ID   "WASD_VMS_HTTPS"
#define  AUTH_WASD_PWD_VMS_ID     "WASD_VMS_PWD"
#define  AUTH_WASD_WRITE_VMS_ID   "WASD_VMS_RW"
#define  AUTH_WASD_READ_VMS_ID    "WASD_VMS_R"

/* when formatting can string */
#define  AUTH_CAN_FORMAT_SHORT  0
#define  AUTH_CAN_FORMAT_LONG   1
#define  AUTH_CAN_FORMAT_HTML   2

#define AUTH_HTA_VERSION 0x01

#define AUTH_DIR_NOT_CONFIGURED "DIRECTORY:[NOT.CONFIGURED]!"

#define HTTPD_VERIFY "/httpd/-/verify/"

/**************/
/* structures */
/**************/

/*
   Store these structures naturally-aligned on AXP.
   Uses a bit more storage but makes access as efficient as possible.
*/

#ifndef __VAX
#   pragma member_alignment __save
#   pragma member_alignment
#endif


typedef struct AuthHtaRecordStruct AUTH_HTAREC;

/* record structure of on-disk HTA database */
struct AuthHtaRecordStruct
{
   char  UserName [AUTH_MAX_HTA_USERNAME_LENGTH+1];
   char  FullName [AUTH_MAX_FULLNAME_LENGTH+1];
   char  Email [AUTH_MAX_EMAIL_LENGTH+1];
   int  UserNameLength;
   unsigned long  Flags;
   unsigned long  HashedPwd [2];
   unsigned char  A1DigestLoCase [16];
   unsigned char  A1DigestUpCase [16];
   int  ChangeCount;
   unsigned long  LastChangeBinTime [2];
   int  AccessCount;
   unsigned long  LastAccessBinTime [2];
   int  FailureCount;
   unsigned long  LastFailureBinTime [2];
   unsigned long  AddedBinTime [2];
   char  Contact [AUTH_MAX_CONTACT_LENGTH+1];
   char  FillTo512Bytes [115];
   unsigned char  DatabaseVersion;
};


typedef struct AuthConfigStruct AUTH_CONFIG_META;

/* this structure is essentially unused for authorization configuration */
struct AuthConfigStruct
{
   unsigned long  Reserved;
};


#define AUTH_REALM_RECORD_TYPE 1

typedef struct AuthRealmRecordStruct AUTH_REALM;

/* in-memory realm authorization structure */
struct AuthRealmRecordStruct
{
   /* must be the first int in the structure */
   int  RecordType;

   BOOL  RealmProblem;

   int  GroupReadLength,   
        GroupWriteLength,   
        MetaConNumber,
        RealmLength,
        RealmDescriptionLength;

   unsigned long  AuthGroupCan,
                  AuthWorldCan,
                  GroupReadVmsIdentifier,
                  GroupWriteVmsIdentifier,
                  RealmVmsIdentifier,
                  SourceRealm,
                  SourceGroupRead,
                  SourceGroupWrite;

   char  *GroupReadPtr,
         *GroupWritePtr,
         *RealmPtr,
         *RealmAccessPtr,
         *RealmDescrPtr;
   /* string data is stored here and pointed to by above pointers */
};


#define AUTH_PATH_RECORD_TYPE 2

typedef struct AuthPathRecordStruct AUTH_PATH;

/* in-memory path authorization structure */
struct AuthPathRecordStruct
{
   /* must be the first int in the structure */
   int  RecordType;

   BOOL  FinalRule,
         NoCache,
         PathProblem,
         VmsUserProfile,
         VmsUserScriptAs;

   int  GroupRestrictListLength,
        MetaConNumber,
        PathLength,
        PathParameterLength,
        ProxyStringLength,
        WorldRestrictListLength;

   unsigned long  AuthGroupCan,
                  AuthWorldCan;

   char  *GroupRestrictListPtr,
         *PathPtr,
         *PathParameterPtr,
         *ProxyStringPtr,
         *WorldRestrictListPtr;

   /* storage for pre-compiled regular expression */
   regex_t  RegexPregPath;
};

#define AUTH_DEFAULT_CACHE_RECORD_MAX 32
#define AUTH_DEFAULT_CACHE_RECORD_SIZE 768
#define AUTH_DEFAULT_CACHE_RECORD_PROFILE_SIZE 1024

typedef struct AuthCacheRecordStruct AUTH_CREC;

/* in-memory user authentication cache structure */
struct AuthCacheRecordStruct
{
   BOOL  CaseLess,
         DetailsUpdated,
         HttpsOnly,
         NoCache,
         ProxyStringMapped,
         SysUafAuthenticated,
         SysUafCanChangePwd,
         SysUafNilAccess,
         VmsUserScriptAs;

   int  AccessCount,
        AuthUserCan,
        BasicCount,
        ConfigDirectoryLength,
        ConfigDirectoryOffset,
        DataBaseCount,
        DigestCount,
        FailureCount,
        FindRecordCount,
        GroupReadLength,
        GroupReadOffset,
        GroupWriteLength,
        GroupWriteOffset,
        LastAccessMinutesAgo,
        LastAccessSecondsAgo,
        LastAccessTickSecond,
        PathParameterLength,
        PathParameterOffset,
        ProxyUserNameLength,
        RealmLength,
        StorageNextOffset,
        UserDetailsLength,
        UserDetailsOffset,
        UserNameLength,
        VmsUserProfileLength,
        VmsUserProfileOffset;

   unsigned long  SourceRealm,
                  SourceGroupRead,
                  SourceGroupWrite,
                  UaiPrimeDays,
                  UaiNetworkAccessP,
                  UaiNetworkAccessS,
                  UaiRemoteAccessP,
                  UaiRemoteAccessS;

   unsigned long  LastAccessBinTime [2];

   char  *ConfigDirectory,
         *GroupWrite,
         *GroupRead,
         *PathParameter,
         *UserDetails,
         *VmsUserProfilePtr;

   char  DigestResponse [AUTH_MAX_DIGEST_RESPONSE+1],
         Password [AUTH_MAX_PASSWORD_LENGTH+1],
         ProxyUserName [AUTH_MAX_USERNAME_LENGTH+1],
         Realm [AUTH_MAX_REALM_GROUP_LENGTH+1],
         UserName [AUTH_MAX_USERNAME_LENGTH+1];

   /* variable length fields are stored from this point onwards */
   char  Storage [];
};


typedef struct AuthGblSecStruct AUTH_GBLSEC;

struct AuthGblSecStruct
{
   unsigned long  GblSecVersion,
                  GblSecLength;

   int  CacheHitCount,
        CacheMissCount,
        CacheRecordCount,
        CacheReuseCount,
        CacheTimeoutCount,
        LoginCookieCacheMax,
        LoginCookieCacheNext,
        LoginCookieCount;
   int  LoginCookieCache [AUTH_MAX_COOKIE_CACHE];
   unsigned long  SinceBinTime [2];

    /* authentication cache records are stored from this point onwards */
   char  CacheRecordPool [];
};

typedef struct AuthIdentStruct AUTH_IDENT;

struct AuthIdentStruct
{
   unsigned short  IdentChannel;

   char  ResponseString [128],
         RequestString [24];

   IO_SB  ConnectIOsb,
                  ReadIOsb,
                  WriteIOsb;

   REQUEST_STRUCT  *RequestPtr;
   REQUEST_AST  AuthAstFunction;
};

typedef struct AuthSysUafStruct AUTH_SYSUAF;

struct AuthSysUafStruct
{
   unsigned long  UaiFlags,
                  UaiPrimeDays,
                  UaiNetworkAccessP,
                  UaiNetworkAccessS,
                  UaiRemoteAccessP,
                  UaiRemoteAccessS,
                  UaiUic,
                  UserNameLength;

   unsigned long  HashedPwd [2],
                  UaiExpBinTime [2],
                  UaiPriv [2],
                  UaiPwd [2],
                  UaiPwd2 [2],
                  UaiPwdDateBinTime [2],
                  UaiPwd2DateBinTime [2],
                  UaiPwdLifeBinTime [2];

   unsigned short  UaiSalt;

   unsigned char  UaiEncrypt;

   char  UaiOwner [1+31+1],
         UserName [15+1];

   /* this should be plenty of space */
   VMS_ITEM_LIST3  UaiItemList [32];
};

typedef struct AuthAcmeStruct AUTH_ACME;

struct AuthAcmeStruct
{
   int  MappingAcmeNameLength,
        MappedVmsUserNameLength,
        TargetDoiNameLength;

   char  MappingAcmeName [32+1],  /* ACME$K_MAXCHAR_DOI_NAME */
         MappedVmsUserName [AUTH_MAX_USERNAME_LENGTH+1],
         TargetDoiName [32+1];  /* ACME$K_MAXCHAR_DOI_NAME */

   /* the SYS$ACM() IO status block is a little different to the norm! */
   unsigned long  AcmIOsb [4];

   /*
      Want to keep ILE3 definitions out of here for backward compatbility.
      The equivalent to ILE3 and 16 items is ample for what we need.
   */
   VMS_ITEM_LIST3  AcmItemList [16];
};

#ifndef __VAX
#   pragma member_alignment __restore
#endif

/***********************/
/* function prototypes */
/***********************/

/*** AUTH.C prototypes ***/

Authorize (REQUEST_STRUCT*, char*, int, char*, int, REQUEST_AST);
AuthorizeRealm (REQUEST_STRUCT*);
AuthorizeRealmCheck (REQUEST_STRUCT*);
AuthorizeWasdId (REQUEST_STRUCT*);
AuthorizeGroupWrite (REQUEST_STRUCT*);
AuthorizeGroupWriteCheck (REQUEST_STRUCT*);
AuthorizeGroupRead (REQUEST_STRUCT*);
AuthorizeGroupReadCheck (REQUEST_STRUCT*);
int AuthorizeGuaranteeAccess (REQUEST_STRUCT*, char*);
AuthorizeFinal (REQUEST_STRUCT*);
AuthorizeResponse (REQUEST_STRUCT*);
AuthorizeNoCache (REQUEST_STRUCT*);

char* AuthCanString (unsigned long, int);
int AuthClientHostGroup (REQUEST_STRUCT*, char*);
int AuthDoAuthorization (REQUEST_STRUCT*);
int AuthParseAuthorization (REQUEST_STRUCT*);
char* AuthSourceString (char*, unsigned long);
int AuthVerifyPassword (REQUEST_STRUCT*);
AuthWatchCheck (REQUEST_STRUCT*, char*, char*, int);

/*** AUTHACME.C prototypes ***/

AuthAcmeVerifyUser (REQUEST_STRUCT*);
AuthAcmeVerifyUserAst (REQUEST_STRUCT*);
AuthAcmeChangePassword (REQUEST_STRUCT*, char*, char*);
AuthAcmeChangePasswordAst (REQUEST_STRUCT*);

/*** AUTHAGENT.C prototypes ***/

AuthAgentBegin (REQUEST_STRUCT*, char*, REQUEST_AST);
AuthAgentCallout (REQUEST_STRUCT*);
AuthAgentCalloutResponseError (REQUEST_STRUCT*);

/*** AUTHHTA.C prototypes ***/

int AuthReadHtDatabase (REQUEST_STRUCT*, char*, BOOL);
int AuthAccessHtDatabase (REQUEST_STRUCT*, BOOL, char*, char*, 
                          AUTH_HTAREC*, AUTH_HTAREC*, AUTH_HTAREC*);

/*** AUTHHTL.C prototypes ***/

int AuthReadSimpleList (REQUEST_STRUCT*, char*, BOOL);

/*** AUTHCACHE.C prototypes ***/

int AuthUserResetRecord (char*, char*, char*);
int AuthCacheAddRecord (AUTH_CREC*, AUTH_CREC**);
int AuthCacheCheckLoginCookie (REQUEST_STRUCT*);
int AuthCacheEntry (AUTH_CREC*, AUTH_CREC*);
int AuthCacheFindRecord (AUTH_CREC*, AUTH_CREC**);
int AuthCacheInit ();
int AuthCachePurge (BOOL);
int AuthCacheReport (REQUEST_STRUCT*, REQUEST_AST);
AuthCacheRequestRecord (REQUEST_STRUCT*, AUTH_CREC**);
int AuthCacheResetLoginCookie (REQUEST_STRUCT*);
AuthCacheReset (REQUEST_STRUCT*, char*, char*);
int AuthCacheSetLoginCookie (REQUEST_STRUCT*);

/*** AUTHCONFIG.C prototypes ***/

int AuthConfigInit();
int AuthConfigIdentifier (char*, unsigned long*);
AuthConfigAddPath (META_CONFIG*,
                   BOOL, char*, BOOL, BOOL, char*, char*, char*, char*,
                   unsigned long, unsigned long, BOOL, BOOL, BOOL);
AuthConfigAddRealm (META_CONFIG*,
                    BOOL, char*, char*, unsigned long, unsigned long,
                    char*, unsigned long, unsigned long,
                    char*, unsigned long, unsigned long,
                    unsigned long, unsigned long);
int AuthConfigAddLine (META_CONFIG, char*);
int AuthConfigLoad (META_CONFIG**);
BOOL AuthConfigLoadCallBack (META_CONFIG*);
int AuthConfigOther();
char* AuthConfigParseProtectRule (REQUEST_STRUCT*, char*, int);
char* AuthConfigProxy (META_CONFIG*, char*);
int AuthConfigProxyMap (REQUEST_STRUCT*, AUTH_CREC*);
int AuthConfigRead (AUTH_CONFIG_META*);
int AuthConfigReadStatus (AUTH_CONFIG_META*, char*, ...);
int AuthConfigReport (REQUEST_STRUCT*, REQUEST_AST, BOOL, char*);
int AuthConfigReportNow (REQUEST_STRUCT*, META_CONFIG*, BOOL, char*);
int AuthConfigReportRule (REQUEST_STRUCT*, METACON_LINE*, BOOL, char*, int);
int AuthConfigSearch (REQUEST_STRUCT*, char*);
int AuthConfigUnLoad (META_CONFIG*);
AuthConfigUnloadLineData (void*);

/*** AUTHIDENT.C prototypes ***/

void AuthIdentBegin (REQUEST_STRUCT*, REQUEST_AST);
int AuthIdentCloseSocket (AUTH_IDENT*);
int AuthIdentEnd (AUTH_IDENT*);
int AuthIdentConnectAst (AUTH_IDENT*);
int AuthIdentReadAst (AUTH_IDENT*);
int AuthIdentReadTimeoutAst (AUTH_IDENT*);
int AuthIdentWriteAst (AUTH_IDENT*);

/*** AUTHVMS.C prototypes ***/

int AuthVmsGetUai (REQUEST_STRUCT*, char*);
AuthVmsChangePassword (REQUEST_STRUCT*, char*);
int AuthVmsCheckIdentifier (REQUEST_STRUCT*);
int AuthVmsCheckUserAccess (REQUEST_STRUCT*, char*, int);
int AuthVmsCheckWriteAccess (REQUEST_STRUCT*, char*, int);
int AuthVmsCreateHttpdProfile ();
int AuthVmsCreateUserProfile (REQUEST_STRUCT*);
int AuthVmsHoldsIdentifier (REQUEST_STRUCT*, char*, unsigned long);
int AuthVmsHoldsWasdGroupIdent (REQUEST_STRUCT*, char*);
int AuthVmsLoadIdentifiers (REQUEST_STRUCT*, unsigned long);
int AuthVmsVerifyUser (REQUEST_STRUCT*);
int AuthVmsVerifyPassword (REQUEST_STRUCT*);

#endif /* AUTH_H_LOADED */

/*****************************************************************************/
