/*****************************************************************************/ /* SesolaCGI.c Secure Sockets Layer CGI variables. VERSION HISTORY --------------- 15-MAR-2020 MGD add SSL_TLS_ALPN variable for ALPN protocol list 23-JUL-2016 MGD use SSL_SESSION_get_id() instead of ->session_id.. 27-SEP-2015 MGD SesolaCgiVariablesExtension() document X509 extensions 28-JUL-2013 MGD add Apache SSL_TLS_SNI variable for SNI server name 21-OCT-2001 MGD rework SESOLA.C */ /*****************************************************************************/ #ifdef WASD_VMS_V7 #undef _VMS__V6__SOURCE #define _VMS__V6__SOURCE #undef __VMS_VER #define __VMS_VER 70000000 #undef __CRTL_VER #define __CRTL_VER 70000000 #endif /* standard C header files */ #include #include #include #include /* VMS related header files */ #include #include /* application header files */ #define SESOLA_REQUIRED #include "Sesola.h" #define WASD_MODULE "SESOLACGI" /***************************************/ #ifdef SESOLA /* secure sockets layer */ /***************************************/ /********************/ /* external storage */ /********************/ #ifdef DBUG extern BOOL Debug; #else #define Debug 0 #endif extern char ErrorSanityCheck[], SoftwareID[]; extern BIO *SesolaBioMemPtr; extern WATCH_STRUCT Watch; /*****************************************************************************/ /* Generate appropriate SSL-related CGI variables. Called from CgiGenerateVariables(). */ int SesolaCgiGenerateVariables ( REQUEST_STRUCT *rqptr, int VarType ) { static $DESCRIPTOR (NumberFaoDsc, "!UL\0"); int status, KeySize; char String [512]; char *cptr; $DESCRIPTOR (StringDsc, String); SESOLA_STRUCT *sesolaptr; SSL *SslPtr; SSL_CIPHER *CipherPtr; X509 *ServerCertPtr; /*********/ /* begin */ /*********/ if (WATCHMOD (rqptr, WATCH_MOD_SESOLA)) WatchThis (WATCHITM(rqptr), WATCH_MOD_SESOLA, "SesolaCgiGenerateVariables() !UL", VarType); if (!(sesolaptr = SesolaRequestSesolaPtr (rqptr))) return (SS$_NORMAL); SslPtr = sesolaptr->SslPtr; CipherPtr = SSL_get_current_cipher (SslPtr); ServerCertPtr = SSL_get_certificate (SslPtr); status = SS$_NORMAL; if (sesolaptr->ClientCertPtr) { if (rqptr->rqAuth.ClientCertFingerprintPtr && rqptr->rqAuth.ClientCertFingerprintPtr[0]) status = CgiVariable (rqptr, "AUTH_X509_FINGERPRINT", rqptr->rqAuth.ClientCertFingerprintPtr, VarType); if (VMSok (status)) if (rqptr->rqAuth.ClientCertIssuerPtr && rqptr->rqAuth.ClientCertIssuerPtr[0]) status = CgiVariable (rqptr, "AUTH_X509_ISSUER", rqptr->rqAuth.ClientCertIssuerPtr, VarType); if (VMSok (status)) if (rqptr->rqAuth.ClientCertSubjectPtr && rqptr->rqAuth.ClientCertSubjectPtr[0]) status = CgiVariable (rqptr, "AUTH_X509_SUBJECT", rqptr->rqAuth.ClientCertSubjectPtr, VarType); if (VMSok (status)) { cptr = (char*)SSL_CIPHER_get_name (CipherPtr); status = CgiVariable (rqptr, "AUTH_X509_CIPHER", cptr, VarType); } if (VMSok (status)) { KeySize = SSL_CIPHER_get_bits (CipherPtr, NULL); sys$fao (&NumberFaoDsc, 0, &StringDsc, KeySize); status = CgiVariable (rqptr, "AUTH_X509_KEYSIZE", String, VarType); } } if (VMSok (status)) { BIO_reset (SesolaBioMemPtr); switch (rqptr->rqPathSet.SSLCGIvar) { case SESOLA_CGI_VAR_APACHE_MOD_SSL : case SESOLA_CGI_VAR_APACHE_MOD_SSL_CLIENT : case SESOLA_CGI_VAR_APACHE_MOD_SSL_EXTENS : case SESOLA_CGI_VAR_APACHE_MOD_SSL_OID : status = SesolaCgiVariablesApacheModSsl (rqptr, VarType); break; case SESOLA_CGI_VAR_PURVEYOR : status = SesolaCgiVariablesPurveyor (rqptr, VarType); break; } BIO_reset (SesolaBioMemPtr); } return (status); } /*****************************************************************************/ /* Generate some Apache mod_SSL style CGI variables. */ int SesolaCgiVariablesApacheModSsl ( REQUEST_STRUCT *rqptr, int VarType ) { static char HexDigits [] = "0123456789abcdef"; static $DESCRIPTOR (NumberFaoDsc, "!UL\0"); int cnt, status, AlgKeySize, ObjNid, UseKeySize; char *cptr, *sptr, *zptr, *CurrentRecordPtr; char CertFingerprint [64], String [512], VariableName [64], VariableValue [256]; $DESCRIPTOR (StringDsc, String); $DESCRIPTOR (VariableNameDsc, VariableName); SESOLA_STRUCT *sesolaptr; SSL *SslPtr; SSL_CIPHER *CipherPtr; SSL_SESSION *SessionPtr; X509 *ClientCertPtr, *ServerCertPtr; ASN1_OBJECT *Asn1Ptr; /*********/ /* begin */ /*********/ if (WATCHMOD (rqptr, WATCH_MOD_SESOLA)) WatchThis (WATCHITM(rqptr), WATCH_MOD_SESOLA, "SesolaCgiVariablesApacheModSsl()"); sesolaptr = SesolaRequestPtr (rqptr); SslPtr = sesolaptr->SslPtr; SessionPtr = SSL_get_session (SslPtr); CipherPtr = SSL_get_current_cipher (SslPtr); ServerCertPtr = SSL_get_certificate (SslPtr); if (!SessionPtr || !CipherPtr || !ServerCertPtr) { if (WATCHMOD (rqptr, WATCH_MOD_SESOLA)) WatchThis (WATCHITM(rqptr), WATCH_MOD_SESOLA, "!&X !&X !&X", SessionPtr, CipherPtr, ServerCertPtr); ErrorNoticed (rqptr, SS$_BUGCHECK, ErrorSanityCheck, FI_LI); return (SS$_BUGCHECK); } /***************/ /* basic stuff */ /***************/ if (VMSnok (status = CgiVariable (rqptr, "HTTPS", "true", VarType))) return (status); if (VMSnok (status = CgiVariable (rqptr, "SSL_PROTOCOL", (char*)SSL_get_version(SslPtr), VarType))) return (status); cptr = SSL_SESSION_get_id (SessionPtr, &cnt); zptr = (sptr = String) + sizeof(String)-1; if (cnt) { while (cnt--) { if (sptr >= zptr) break; *sptr++ = HexDigits[(*cptr >> 4) & 0x0f]; if (sptr >= zptr) break; *sptr++ = HexDigits[*cptr++ & 0x0f]; } *sptr = '\0'; if (VMSnok (status = CgiVariable (rqptr, "SSL_SESSION_ID", String, VarType))) return (status); } cptr = (char*)SSL_CIPHER_get_name (CipherPtr); if (VMSnok (status = CgiVariable (rqptr, "SSL_CIPHER", cptr, VarType))) return (status); UseKeySize = SSL_CIPHER_get_bits(CipherPtr, &AlgKeySize); /* same as "mod_SSL" v2.5 */ if (UseKeySize < 56) if (VMSnok (status = CgiVariable (rqptr, "SSL_CIPHER_EXPORT", "true", VarType))) return (status); sys$fao (&NumberFaoDsc, 0, &StringDsc, UseKeySize); if (VMSnok (status = CgiVariable (rqptr, "SSL_CIPHER_USEKEYSIZE", String, VarType))) return (status); sys$fao (&NumberFaoDsc, 0, &StringDsc, AlgKeySize); if (VMSnok (status = CgiVariable (rqptr, "SSL_CIPHER_ALGKEYSIZE", String, VarType))) return (status); if (VMSnok (status = CgiVariable (rqptr, "SSL_VERSION_INTERFACE", APACHE_MOD_SSL_VERSION_INTERFACE, VarType))) return (status); if (VMSnok (status = CgiVariable (rqptr, "SSL_VERSION_LIBRARY", (char*)OpenSSL_version(OPENSSL_VERSION), VarType))) return (status); if (sesolaptr->SNIServerName[0]) if (VMSnok (status = CgiVariable (rqptr, "SSL_TLS_SNI", sesolaptr->SNIServerName, VarType))) return (status); if (sesolaptr->ALPNok) if (VMSnok (status = CgiVariable (rqptr, "SSL_TLS_ALPN", sesolaptr->ALPNok, VarType))) return (status); /****************/ /* client stuff */ /****************/ if (ClientCertPtr = sesolaptr->ClientCertPtr) { sys$fao (&NumberFaoDsc, 0, &StringDsc, X509_get_version(ClientCertPtr)+1); if (VMSnok (status = CgiVariable (rqptr, "SSL_CLIENT_M_VERSION", String, VarType))) return (status); i2a_ASN1_INTEGER (SesolaBioMemPtr, X509_get_serialNumber(ClientCertPtr)); BIO_gets (SesolaBioMemPtr, String, sizeof(String)); if (VMSnok (status = CgiVariable (rqptr, "SSL_CLIENT_M_SERIAL", String, VarType))) return (status); X509_NAME_oneline (X509_get_subject_name(ClientCertPtr), String, sizeof(String)); if (VMSnok (status = CgiVariable (rqptr, "SSL_CLIENT_S_DN", String, VarType))) return (status); sptr = VariableName; for (cptr = "SSL_CLIENT_S_DN_"; *cptr; *sptr++ = *cptr++); for (;;) { cptr = SesolaCertParseDn (String, NULL); if (!cptr) break; if (*cptr == '/') cptr++; zptr = (sptr = VariableName+16) + sizeof(VariableName)-17; while (*cptr && *cptr != '=' && sptr < zptr) *sptr++ = *cptr++; if (!*cptr) break; cptr++; *sptr = '\0'; zptr = (sptr = VariableValue) + sizeof(VariableValue)-1; while (*cptr && sptr < zptr) *sptr++ = *cptr++; *sptr = '\0'; if (VMSnok (status = CgiVariable (rqptr, VariableName, VariableValue, VarType))) return (status); } X509_NAME_oneline (X509_get_issuer_name(ClientCertPtr), String, sizeof(String)); if (VMSnok (status = CgiVariable (rqptr, "SSL_CLIENT_I_DN", String, VarType))) return (status); sptr = VariableName; for (cptr = "SSL_CLIENT_I_DN_"; *cptr; *sptr++ = *cptr++); for (;;) { cptr = SesolaCertParseDn (String, NULL); if (!cptr) break; if (*cptr == '/') cptr++; zptr = (sptr = VariableName+16) + sizeof(VariableName)-17; while (*cptr && *cptr != '=' && sptr < zptr) *sptr++ = *cptr++; if (!*cptr) break; cptr++; *sptr = '\0'; zptr = (sptr = VariableValue) + sizeof(VariableValue)-1; while (*cptr && sptr < zptr) *sptr++ = *cptr++; *sptr = '\0'; if (VMSnok (status = CgiVariable (rqptr, VariableName, VariableValue, VarType))) return (status); } ASN1_UTCTIME_print (SesolaBioMemPtr, X509_get_notBefore(ClientCertPtr)); BIO_gets (SesolaBioMemPtr, String, sizeof(String)); if (VMSnok (status = CgiVariable (rqptr, "SSL_CLIENT_V_START", String, VarType))) return (status); ASN1_UTCTIME_print (SesolaBioMemPtr, X509_get_notAfter(ClientCertPtr)); BIO_gets (SesolaBioMemPtr, String, sizeof(String)); if (VMSnok (status = CgiVariable (rqptr, "SSL_CLIENT_V_END", String, VarType))) return (status); X509_ALGOR_get0 (&Asn1Ptr, NULL, NULL, X509_get0_tbs_sigalg(ClientCertPtr)); ObjNid = OBJ_obj2nid (Asn1Ptr); if (VMSnok (status = CgiVariable (rqptr, "SSL_CLIENT_A_SIG", ObjNid == NID_undef ? "UNKNOWN" : (char*)OBJ_nid2ln(ObjNid), VarType))) return (status); X509_PUBKEY_get0_param (&Asn1Ptr, NULL, 0, NULL, X509_get_X509_PUBKEY(ClientCertPtr)); ObjNid = OBJ_obj2nid (Asn1Ptr); if (VMSnok (status = CgiVariable (rqptr, "SSL_CLIENT_A_KEY", ObjNid == NID_undef ? "UNKNOWN" : (char*)OBJ_nid2ln(ObjNid), VarType))) return (status); } #if APACHE_MOD_SSL_SERVER_CERT /* This variable is larger than can be support in a DCL symbol. It can be support in a CGIplus variable stream, but I imagine has a limited range of uses and so is not generated by default. */ if (VarType == CGI_VARIABLE_STREAM) { PEM_write_bio_X509(SesolaBioMemPtr, ClientCertPtr); BIO_read (SesolaBioMemPtr, String, sizeof(String)); if (VMSnok (status = CgiVariable (rqptr, "SSL_CLIENT_CERT", String, VarType))) return (status); } #endif /****************/ /* server stuff */ /****************/ if (rqptr->rqPathSet.SSLCGIvar != SESOLA_CGI_VAR_APACHE_MOD_SSL_CLIENT) { sys$fao (&NumberFaoDsc, 0, &StringDsc, X509_get_version(ServerCertPtr)+1); if (VMSnok (status = CgiVariable (rqptr, "SSL_SERVER_M_VERSION", String, VarType))) return (status); i2a_ASN1_INTEGER (SesolaBioMemPtr, X509_get_serialNumber(ServerCertPtr)); BIO_gets (SesolaBioMemPtr, String, sizeof(String)); if (VMSnok (status = CgiVariable (rqptr, "SSL_SERVER_M_SERIAL", String, VarType))) return (status); X509_NAME_oneline (X509_get_subject_name(ServerCertPtr), String, sizeof(String)); if (VMSnok (status = CgiVariable (rqptr, "SSL_SERVER_S_DN", String, VarType))) return (status); sptr = VariableName; for (cptr = "SSL_SERVER_S_DN_"; *cptr; *sptr++ = *cptr++); for (;;) { cptr = SesolaCertParseDn (String, NULL); if (!cptr) break; if (*cptr == '/') cptr++; zptr = (sptr = VariableName+16) + sizeof(VariableName)-17; while (*cptr && *cptr != '=' && sptr < zptr) *sptr++ = *cptr++; if (!*cptr) break; cptr++; *sptr = '\0'; zptr = (sptr = VariableValue) + sizeof(VariableValue)-1; while (*cptr && sptr < zptr) *sptr++ = *cptr++; *sptr = '\0'; if (VMSnok (status = CgiVariable (rqptr, VariableName, VariableValue, VarType))) return (status); } X509_NAME_oneline (X509_get_issuer_name(ServerCertPtr), String, sizeof(String)); if (VMSnok (status = CgiVariable (rqptr, "SSL_SERVER_I_DN", String, VarType))) return (status); sptr = VariableName; for (cptr = "SSL_SERVER_I_DN_"; *cptr; *sptr++ = *cptr++); for (;;) { cptr = SesolaCertParseDn (String, NULL); if (!cptr) break; if (*cptr == '/') cptr++; zptr = (sptr = VariableName+16) + sizeof(VariableName)-17; while (*cptr && *cptr != '=' && sptr < zptr) *sptr++ = *cptr++; if (!*cptr) break; cptr++; *sptr = '\0'; zptr = (sptr = VariableValue) + sizeof(VariableValue)-1; while (*cptr && sptr < zptr) *sptr++ = *cptr++; *sptr = '\0'; if (VMSnok (status = CgiVariable (rqptr, VariableName, VariableValue, VarType))) return (status); } ASN1_UTCTIME_print (SesolaBioMemPtr, X509_get_notBefore(ServerCertPtr)); BIO_gets (SesolaBioMemPtr, String, sizeof(String)); if (VMSnok (status = CgiVariable (rqptr, "SSL_SERVER_V_START", String, VarType))) return (status); ASN1_UTCTIME_print (SesolaBioMemPtr, X509_get_notAfter(ServerCertPtr)); BIO_gets (SesolaBioMemPtr, String, sizeof(String)); if (VMSnok (status = CgiVariable (rqptr, "SSL_SERVER_V_END", String, VarType))) return (status); X509_ALGOR_get0 (&Asn1Ptr, NULL, NULL, X509_get0_tbs_sigalg(ServerCertPtr)); ObjNid = OBJ_obj2nid (Asn1Ptr); if (VMSnok (status = CgiVariable (rqptr, "SSL_SERVER_A_SIG", ObjNid == NID_undef ? "UNKNOWN" : (char*)OBJ_nid2ln(ObjNid), VarType))) return (status); X509_PUBKEY_get0_param (&Asn1Ptr, NULL, 0, NULL, X509_get_X509_PUBKEY(ServerCertPtr)); ObjNid = OBJ_obj2nid (Asn1Ptr); if (VMSnok (status = CgiVariable (rqptr, "SSL_SERVER_A_KEY", ObjNid == NID_undef ? "UNKNOWN" : (char*)OBJ_nid2ln(ObjNid), VarType))) return (status); #if APACHE_MOD_SSL_SERVER_CERT /* This variable is larger than can be support in a DCL symbol. It can be support in a CGIplus variable stream, but I imagine has a limited range of uses and so is not generated by default. */ if (VarType == CGI_VARIABLE_STREAM) { PEM_write_bio_X509(SesolaBioMemPtr, ServerCertPtr); BIO_read (SesolaBioMemPtr, String, sizeof(String)); if (VMSnok (status = CgiVariable (rqptr, "SSL_SERVER_CERT", String, VarType))) return (status); } #endif } /*******************/ /* X509 extensions */ /*******************/ if (rqptr->rqPathSet.SSLCGIvar == SESOLA_CGI_VAR_APACHE_MOD_SSL_CLIENT || rqptr->rqPathSet.SSLCGIvar == SESOLA_CGI_VAR_APACHE_MOD_SSL_EXTENS || rqptr->rqPathSet.SSLCGIvar == SESOLA_CGI_VAR_APACHE_MOD_SSL_OID) SesolaCgiVariablesExtension (rqptr, VarType); return (SS$_NORMAL); } /*****************************************************************************/ /* Generate some Purveyor style SSL-related CGI variables. */ int SesolaCgiVariablesPurveyor ( REQUEST_STRUCT *rqptr, int VarType ) { static $DESCRIPTOR (NumberFaoDsc, "!UL\0"); int status, KeySize; char String [512]; char *cptr; $DESCRIPTOR (StringDsc, String); SESOLA_STRUCT *sesolaptr; SSL *SslPtr; SSL_CIPHER *CipherPtr; SSL_SESSION *SessionPtr; X509 *ServerCertPtr; /*********/ /* begin */ /*********/ if (WATCHMOD (rqptr, WATCH_MOD_SESOLA)) WatchThis (WATCHITM(rqptr), WATCH_MOD_SESOLA, "SesolaCgiVariablesPurveyor()"); sesolaptr = SesolaRequestPtr (rqptr); SslPtr = sesolaptr->SslPtr; SessionPtr = SSL_get_session (SslPtr); CipherPtr = SSL_get_current_cipher (SslPtr); ServerCertPtr = SSL_get_certificate (SslPtr); if (!SessionPtr || !CipherPtr || !ServerCertPtr) { if (WATCHMOD (rqptr, WATCH_MOD_SESOLA)) WatchThis (WATCHITM(rqptr), WATCH_MOD_SESOLA, "!&X !&X !&X", SessionPtr, CipherPtr, ServerCertPtr); ErrorNoticed (rqptr, SS$_BUGCHECK, ErrorSanityCheck, FI_LI); return (SS$_BUGCHECK); } cptr = (char*)SSL_CIPHER_get_name (CipherPtr); if (VMSnok (status = CgiVariable (rqptr, "SSL_CIPHER", cptr, VarType))) return (status); KeySize = SSL_CIPHER_get_bits (CipherPtr, NULL); sys$fao (&NumberFaoDsc, 0, &StringDsc, KeySize); if (VMSnok (status = CgiVariable (rqptr, "SSL_CIPHER_KEYSIZE", String, VarType))) return (status); if (!sesolaptr->ClientCertPtr) { if (VMSnok (status = CgiVariable (rqptr, "SSL_CLIENT_CA", "NONE", VarType))) return (status); if (VMSnok (status = CgiVariable (rqptr, "SSL_CLIENT_DN", "NONE", VarType))) return (status); } else { X509_NAME_oneline (X509_get_issuer_name(sesolaptr->ClientCertPtr), String, sizeof(String)); if (VMSnok (status = CgiVariable (rqptr, "SSL_CLIENT_CA", String, VarType))) return (status); X509_NAME_oneline (X509_get_subject_name(sesolaptr->ClientCertPtr), String, sizeof(String)); if (VMSnok (status = CgiVariable (rqptr, "SSL_CLIENT_DN", String, VarType))) return (status); } if (rqptr->RemoteUser[0] && rqptr->rqAuth.SourceRealm == AUTH_SOURCE_X509) cptr = "TRUE"; else cptr = "FALSE"; if (VMSnok (status = CgiVariable (rqptr, "SSL_CLIENT_AUTHENTICATED", cptr, VarType))) return (status); if (VMSnok (status = CgiVariable (rqptr, "SECURITY_STATUS", "SSL", VarType))) return (status); X509_NAME_oneline (X509_get_issuer_name(ServerCertPtr), String, sizeof(String)); if (VMSnok (status = CgiVariable (rqptr, "SSL_SERVER_CA", String, VarType))) return (status); X509_NAME_oneline (X509_get_subject_name(ServerCertPtr), String, sizeof(String)); if (VMSnok (status = CgiVariable (rqptr, "SSL_SERVER_DN", String, VarType))) return (status); if (VMSnok (status = CgiVariable (rqptr, "SSL_VERSION", (char*)SSL_get_version(SslPtr), VarType))) return (status); return (SS$_NORMAL); } /*****************************************************************************/ /* Generate X509 extension CGI variables. */ int SesolaCgiVariablesExtension ( REQUEST_STRUCT *rqptr, int VarType ) { /* see also SesolaCertExtensions() */ static char *ShortHand [] = { "X509V3_SUBJECT_ALTERNATIVE_NAME", "X509V3_SAN", "X509V3_SUBJECT_ALTERNATIVE_NAME_USERPRINCIPALNAME", "X509V3_SAN_UPN", "X509V3_SUBJECT_ALTERNATIVE_NAME_RFC822NAME", "X509V3_SAN_822", NULL }; int cnt, idx, status; char *aptr, *cptr, *sptr, *zptr; char NameValue [256+2048]; SESOLA_STRUCT *sesolaptr; SSL *SslPtr; X509 *CertPtr; /*********/ /* begin */ /*********/ if (WATCHMOD (rqptr, WATCH_MOD_SESOLA)) WatchThis (WATCHITM(rqptr), WATCH_MOD_SESOLA, "SesolaCgiVariablesExtension()"); sesolaptr = SesolaRequestPtr (rqptr); if (rqptr->rqPathSet.SSLCGIvar == SESOLA_CGI_VAR_APACHE_MOD_SSL_CLIENT) cnt = 1; else cnt = 2; for (; cnt; cnt--) { sptr = NameValue; if (cnt == 2) { /* server certificate extensions */ SslPtr = sesolaptr->SslPtr; CertPtr = SSL_get_certificate (SslPtr); for (cptr = "SSL_SERVER_E_"; *cptr; *sptr++ = *cptr++); } else { /* client certificate extensions */ if (!(CertPtr = sesolaptr->ClientCertPtr)) break; for (cptr = "SSL_CLIENT_E_"; *cptr; *sptr++ = *cptr++); } if (rqptr->rqPathSet.SSLCGIvar == SESOLA_CGI_VAR_APACHE_MOD_SSL_OID) SesolaCertExtension (CertPtr, "OID"); else SesolaCertExtension (CertPtr, NULL); while (cptr = SesolaCertExtension (NULL, NULL)) { zptr = (sptr = NameValue+13) + sizeof(NameValue)-14; while (*cptr && sptr < zptr) *sptr++ = *cptr++; *sptr = '\0'; if (VMSnok (status = CgiVariable (rqptr, NameValue, NULL, VarType))) return (status); } for (idx = 0; ShortHand[idx]; idx += 2) { if (cptr = SesolaCertExtension (NULL, ShortHand[idx])) { while (*cptr && *cptr != '=') cptr++; zptr = (sptr = NameValue+13) + sizeof(NameValue)-14; for (aptr = ShortHand[idx+1]; *aptr && sptr < zptr; *sptr++ = *aptr++); while (*cptr && sptr < zptr) *sptr++ = *cptr++; *sptr = '\0'; if (VMSnok (status = CgiVariable (rqptr, NameValue, NULL, VarType))) return (status); } } } return (SS$_NORMAL); } /*****************************************************************************/ /* For compilations without SSL these functions provide LINKage stubs for the rest of the HTTPd modules, allowing for just recompiling the Sesola module to integrate the SSL functionality. */ /*********************/ #else /* not SESOLA */ /*********************/ /* external storage */ extern WATCH_STRUCT Watch; SesolaCgiGenerateVariables ( REQUEST_STRUCT *rqptr, int VarType ) { int status; /*********/ /* begin */ /*********/ if (WATCHMOD (rqptr, WATCH_MOD_SESOLA)) WatchThis (WATCHITM(rqptr), WATCH_MOD_SESOLA, "SesolaCgiGenerateVariables()"); if (VMSnok (status = CgiVariable (rqptr, "SECURITY_STATUS", "NONE", VarType))) return (status); return (SS$_NORMAL); } /************************/ #endif /* ifdef SESOLA */ /************************/ /*****************************************************************************/