/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- * * The contents of this file are subject to the Netscape Public License * Version 1.0 (the "NPL"); you may not use this file except in * compliance with the NPL. You may obtain a copy of the NPL at * http://www.mozilla.org/NPL/ * * Software distributed under the NPL is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL * for the specific language governing rights and limitations under the * NPL. * * The Initial Developer of this code under the NPL is Netscape * Communications Corporation. Portions created by Netscape are * Copyright (C) 1998 Netscape Communications Corporation. All Rights * Reserved. */ /* * Glue code to make PICS work in the client. This is just a thin * layer between the W3C code and our layout engine to digest PICS labels. * Coded by Lou Montulli */ #if defined(CookieManagement) #define TRUST_LABELS 1 #endif #include "xp.h" #include "cslutils.h" #include "csll.h" #include "csllst.h" #include "pics.h" #include "prefapi.h" #include "xpgetstr.h" #include "sechash.h" #include "base64.h" extern int XP_ALERT_PROMPT_JAVA_CAPIBILITIES_PASSWORD; extern int XP_ALERT_PROMPT_JAVA_CAPIBILITIES_PASSWORD_FAILED_ONCE; typedef struct { PICS_RatingsStruct * rs; XP_Bool rs_invalid; } ClosureData; PRIVATE StateRet_t target_callback(CSLabel_t *pCSLabel, CSParse_t * pCSParse, CSLLTC_t target, XP_Bool closed, void * pClosure) { char * ratingname; char * ratingstr; ClosureData *cd = (ClosureData *)pClosure; /* closed signifies that the parsing is done for that label */ if(!cd || !closed) return StateRet_OK; if(target == CSLLTC_SINGLE) { LabelOptions_t * lo = CSLabel_getLabelOptions(pCSLabel); if(lo) { if(lo->generic.state) { cd->rs->generic = TRUE; } if(lo->fur.value && !cd->rs->fur) { StrAllocCopy(cd->rs->fur, lo->fur.value); } } } else if(target == CSLLTC_RATING) { PICS_RatingsStruct *rating_struct = cd->rs; LabelOptions_t * lo = CSLabel_getLabelOptions(pCSLabel); ratingstr = CSLabel_getRatingStr(pCSLabel); ratingname = CSLabel_getRatingName(pCSLabel); if(ratingname) { LabelRating_t * label_rating; ServiceInfo_t * service_info; service_info = CSLabel_getServiceInfo(pCSLabel); if(service_info && !rating_struct->service) { rating_struct->service = XP_STRDUP(service_info->rating_service.value); } label_rating = CSLabel_getLabelRating(pCSLabel); if(label_rating) { double value; PICS_RatingValue *rating_value = XP_NEW_ZAP(PICS_RatingValue); value = label_rating->value.value; if(rating_value) { rating_value->value = label_rating->value.value; rating_value->name = XP_STRDUP(label_rating->identifier.value); if(rating_value->name) { /* insert it into the list */ XP_ListAddObject(rating_struct->ratings, rating_value); } else { /* error, cleanup */ XP_FREE(rating_value); } } } } } return StateRet_OK; } PRIVATE StateRet_t parse_error_handler(CSLabel_t * pCSLabel, CSParse_t * pCSParse, const char * token, char demark, StateRet_t errorCode) { return errorCode; } /* return NULL or ratings struct */ PUBLIC PICS_RatingsStruct * PICS_ParsePICSLable(char * label) { CSParse_t *CSParse_handle; ClosureData *cd; PICS_RatingsStruct *rs; CSDoMore_t status; if(!label) return NULL; cd = XP_NEW_ZAP(ClosureData); if(!cd) return NULL; rs = XP_NEW_ZAP(PICS_RatingsStruct); if(!rs) { XP_FREE(cd); return NULL; } rs->ratings = XP_ListNew(); cd->rs = rs; /* parse pics label using w3c api */ CSParse_handle = CSParse_newLabel(&target_callback, &parse_error_handler); if(!CSParse_handle) return NULL; do { status = CSParse_parseChunk(CSParse_handle, label, XP_STRLEN(label), cd); } while(status == CSDoMore_more); if(cd->rs_invalid) { PICS_FreeRatingsStruct(rs); rs = NULL; } XP_FREE(cd); CSParse_deleteLabel(CSParse_handle); return(rs); } PUBLIC void PICS_FreeRatingsStruct(PICS_RatingsStruct *rs) { if(rs) { PICS_RatingValue *rv; while((rv = XP_ListRemoveTopObject(rs->ratings)) != NULL) { XP_FREE(rv->name); XP_FREE(rv); } XP_FREE(rs); } } #define PICS_DOMAIN "browser.PICS." #define PICS_ENABLED_PREF PICS_DOMAIN"ratings_enabled" #define PICS_MUST_BE_RATED_PREF PICS_DOMAIN"pages_must_be_rated" #define PICS_DISABLED_FOR_SESSION PICS_DOMAIN"disable_for_this_session" #define PICS_REENABLE_FOR_SESSION PICS_DOMAIN"reenable_for_this_session" #define JAVA_SECURITY_PASSWORD "signed.applets.capabilitiesDB.password" Bool pics_ratings_enabled = FALSE; Bool pics_pages_must_be_rated_pref = FALSE; Bool pics_disabled_for_this_session = FALSE; int pics_violence_pref = 0; int pics_sexual_pref = 0; int pics_language_pref = 0; int pics_nudity_pref = 0; /* if TRUE the user can allow additional java and JS * capibilities. UniversalFileWrite, etc. */ Bool pics_java_capabilities_enabled = TRUE; int PR_CALLBACK pics_pref_change(const char *pref_name, void *closure) { XP_Bool bool_rv; if(!PREF_GetBoolPref(PICS_ENABLED_PREF, &bool_rv)) pics_ratings_enabled = bool_rv; if(!PREF_GetBoolPref(PICS_MUST_BE_RATED_PREF, &bool_rv)) pics_pages_must_be_rated_pref = bool_rv; if(!PREF_GetBoolPref(PICS_DISABLED_FOR_SESSION, &bool_rv)) { if(bool_rv) { pics_disabled_for_this_session = TRUE; PREF_SetBoolPref(PICS_DISABLED_FOR_SESSION, FALSE); } } if(!PREF_GetBoolPref(PICS_REENABLE_FOR_SESSION, &bool_rv)) { if(bool_rv) { pics_disabled_for_this_session = FALSE; PREF_SetBoolPref(PICS_REENABLE_FOR_SESSION, FALSE); } } return 0; } PRIVATE char * pics_hash_password(char *pw) { SECStatus status; unsigned char result[SHA1_LENGTH]; status = SHA1_HashBuf(result, (unsigned char *)pw, XP_STRLEN(pw)); if (status != SECSuccess) return NULL; return(BTOA_DataToAscii(result, SHA1_LENGTH)); } PUBLIC void PICS_Init(MWContext *context) { static XP_Bool first_time=TRUE; if(!first_time) { return; } else { char *password=NULL; first_time = FALSE; /* get the prefs */ pics_pref_change(PICS_DOMAIN, NULL); PREF_RegisterCallback(PICS_DOMAIN, pics_pref_change, NULL); /* check for security pref that password disables the enableing of * java permissions */ if(PREF_CopyCharPref(JAVA_SECURITY_PASSWORD, &password)) password = NULL; if(password && *password) { /* get prompt string from registry */ char *prompt_string = XP_GetString(XP_ALERT_PROMPT_JAVA_CAPIBILITIES_PASSWORD); char *user_password; char *hashed_password; prompt_again: /* prompt the user for the password */ user_password = FE_PromptPassword(context, prompt_string); /* ### one-way hash password */ if(user_password) { hashed_password = pics_hash_password(user_password); } else { hashed_password = NULL; } if(!hashed_password) { pics_java_capabilities_enabled = FALSE; } else if(!XP_STRCMP(hashed_password, password)) { pics_java_capabilities_enabled = TRUE; } else { XP_FREE(user_password); XP_FREE(hashed_password); prompt_string = XP_GetString(XP_ALERT_PROMPT_JAVA_CAPIBILITIES_PASSWORD_FAILED_ONCE); goto prompt_again; } XP_FREEIF(user_password); XP_FREEIF(hashed_password); } XP_FREEIF(password); } } PUBLIC XP_Bool PICS_CanUserEnableAdditionalJavaCapabilities(void) { return(pics_java_capabilities_enabled); } PUBLIC XP_Bool PICS_IsPICSEnabledByUser(void) { /* short circuit */ if(pics_disabled_for_this_session) return FALSE; return(pics_ratings_enabled); } PUBLIC XP_Bool PICS_AreRatingsRequired(void) { return pics_pages_must_be_rated_pref; } PRIVATE char * illegal_to_underscore(char *string) { char* ptr = string; if(!string) return NULL; if(!XP_IS_ALPHA(*ptr)) *ptr = '_'; for(ptr++; *ptr; ptr++) if(!XP_IS_ALPHA(*ptr) && !XP_IS_DIGIT(*ptr)) *ptr = '_'; return string; } PRIVATE char * lowercase_string(char *string) { char *ptr = string; if(!string) return NULL; for(; *ptr; ptr++) *ptr = XP_TO_LOWER(*ptr); return string; } #define PICS_URL_PREFIX "about:pics" /* returns a URL string from a RatingsStruct * that includes the service URL and rating info */ PUBLIC char * PICS_RStoURL(PICS_RatingsStruct *rs, char *cur_page_url) { char *rv; char *escaped_cur_page=NULL; if(cur_page_url) { escaped_cur_page = NET_Escape(cur_page_url, URL_PATH); if(!escaped_cur_page) return NULL; } rv = PR_smprintf("%s?Destination=%s", PICS_URL_PREFIX, escaped_cur_page ? escaped_cur_page : "none"); XP_FREE(escaped_cur_page); if(!rs || !rs->service) { StrAllocCat(rv, "&NO_RATING"); return(rv); } else { XP_List *list_ptr = rs->ratings; PICS_RatingValue *rating_value; char *escaped_service = NET_Escape(rs->service, URL_PATH); if(!escaped_service) return NULL; StrAllocCat(rv, "&Service="); StrAllocCat(rv, escaped_service); XP_FREE(escaped_service); while((rating_value = XP_ListNextObject(list_ptr)) != NULL) { char *add; char *escaped_name = NET_Escape( illegal_to_underscore(rating_value->name), URL_PATH); if(!escaped_name) { XP_FREE(rv); return NULL; } add = PR_smprintf("&%s=%f", escaped_name, rating_value->value); XP_FREE(escaped_name); StrAllocCat(rv, add); XP_FREE(add); } return rv; } XP_ASSERT(0); /* should never get here */ return NULL; } XP_List *pics_tree_ratings=NULL; PRIVATE void pics_add_rs_to_tree_ratings(PICS_RatingsStruct *rs) { char *path; if(!pics_tree_ratings) { pics_tree_ratings = XP_ListNew(); if(!pics_tree_ratings) return; } if(!rs->fur || !rs->generic) return; /* doesn't belong here */ /* make sure it's not in the list already */ if(PICS_CheckForValidTreeRating(rs->fur)) return; /* make sure the fur address smells like a URL and has * a real host name (at least two dots) * * reject "http://" or "http://www" */ if(!NET_URL_Type(rs->fur)) return; path = NET_ParseURL(rs->fur, GET_PATH_PART); /* if it has a path it's ok */ if(!path || !*path) { /* if it doesn't have a path it needs at least two dots */ char *ptr; char *hostname = NET_ParseURL(rs->fur, GET_HOST_PART); if(!hostname) return; if(!(ptr = XP_STRCHR(hostname, '.')) || !XP_STRCHR(ptr+1, '.')) { XP_FREE(hostname); XP_FREEIF(path); return; } XP_FREE(hostname); } XP_FREE(path); XP_ListAddObject(pics_tree_ratings, rs->fur); return; } PUBLIC XP_Bool PICS_CheckForValidTreeRating(char *url_address) { XP_List *list_ptr; char *valid_tree; if(!pics_tree_ratings) return FALSE; list_ptr = pics_tree_ratings; while((valid_tree = XP_ListNextObject(list_ptr))) { if(!XP_STRNCASECMP(url_address, valid_tree, XP_STRLEN(valid_tree))) return TRUE; } return FALSE; } /* returns TRUE if page should be censored * FALSE if page is allowed to be shown */ PUBLIC PICS_PassFailReturnVal PICS_CompareToUserSettings(PICS_RatingsStruct *rs, char *cur_page_url) { int32 int_pref; XP_Bool bool_pref; char * pref_prefix; char * pref_string=NULL; char * escaped_service; PICS_PassFailReturnVal rv = PICS_RATINGS_PASSED; XP_List *list_ptr; PICS_RatingValue *rating_value; if(!rs || !rs->service) { return PICS_NO_RATINGS; } #define PICS_SERVICE_DOMAIN PICS_DOMAIN"service." #define PICS_SERVICE_ENABLED "service_enabled" /* cycle through list of ratings and compare to the users prefs */ list_ptr = rs->ratings; pref_prefix = XP_STRDUP(PICS_SERVICE_DOMAIN); /* need to deal with bad characters */ escaped_service = XP_STRDUP(rs->service); escaped_service = illegal_to_underscore(escaped_service); escaped_service = lowercase_string(escaped_service); if(!escaped_service) return PICS_RATINGS_FAILED; StrAllocCat(pref_prefix, escaped_service); XP_FREE(escaped_service); if(!pref_prefix) return PICS_RATINGS_FAILED; /* verify that this type of rating system is enabled */ pref_string = PR_smprintf("%s.%s", pref_prefix, PICS_SERVICE_ENABLED); if(!pref_string) goto cleanup; if(!PREF_GetBoolPref(pref_string, &bool_pref)) { if(!bool_pref) { /* this is an unenabled ratings service */ rv = PICS_NO_RATINGS; XP_FREE(pref_string); goto cleanup; } } else { /* this is an unsupported ratings service */ rv = PICS_NO_RATINGS; XP_FREE(pref_string); goto cleanup; } XP_FREE(pref_string); while((rating_value = XP_ListNextObject(list_ptr)) != NULL) { /* compose pref lookup string */ pref_string = PR_smprintf("%s.%s", pref_prefix, illegal_to_underscore(rating_value->name)); if(!pref_string) goto cleanup; /* find the value in the prefs if it exists * if it does compare it to the value given and if * less than, censer the page. */ if(!PREF_GetIntPref(pref_string, &int_pref)) { if(rating_value->value > int_pref) { rv = PICS_RATINGS_FAILED; XP_FREE(pref_string); goto cleanup; } } XP_FREE(pref_string); } cleanup: XP_FREE(pref_prefix); /* make sure this rating applies to this page */ if(rs->fur) { if(XP_STRNCASECMP(cur_page_url, rs->fur, XP_STRLEN(rs->fur))) rv = PICS_NO_RATINGS; } if(rv == PICS_RATINGS_PASSED && rs->generic) { /* rating should apply to a whole tree, add to list */ pics_add_rs_to_tree_ratings(rs); } return rv; } #ifdef TRUST_LABELS /***************************************************************************/ /***************************************************************************/ /*********** TRUST.C at a latter time **********************************/ /********* break from here down into trust.c ****************************/ /***************************************************************************/ /***************************************************************************/ /* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- * * The contents of this file are subject to the Netscape Public License * Version 1.0 (the "NPL"); you may not use this file except in * compliance with the NPL. You may obtain a copy of the NPL at * http://www.mozilla.org/NPL/ * * Software distributed under the NPL is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL * for the specific language governing rights and limitations under the * NPL. * * The Initial Developer of this code under the NPL is Netscape * Communications Corporation. Portions created by Netscape are * Copyright (C) 1998 Netscape Communications Corporation. All Rights * Reserved. */ /* * This is another version of the thin layer between the W3C code - which * parses the PICS labels - and the HTTP parsing code, to digest PICS labels. * The original version was coded by Lou Montulli, this version by Paul Chek. * * This code is called when the HTTP header is being parsed and a PICS label * was found. * * The broad overview is: * 1. The PICS parsing engine parses the ENTIRE label creating structures and * lists of the different rating services and labels in the services. * 2. After the label is completely parsed we iterate thru the rating * services and the labels for each service to see if there are any trust * labels. * 3. If trust label are found they are added to the TrustList which is part * of the URL struct. * * The two main functions for the trust label processing are: * ProcessSingleLabel - this is where the parsing engine presents ONE label with * all its options and extensions. ProcessSingleLabel examines * the label and determines if it is a valid trust label. If * it is the label is added to the TrustList. This list * is the list of all trust labels. * * MatchCookieToLabel - here is where a cookie gets matched to a trust label. The * entire header for the response has been read. The * end-of-header processing is pulling out the "Set-Cookie" * entries. It has retrieved a cookie for processing. The * cookie processing code see that the user is processing * cookies using a script and inorder to fill out the cookie * properties for the script it has called MatchCookieToLabel * to see if there is a trust label associated with the cookie. * MatchCookieToLabel will look thru the trust_label list and * match the best label to the cookie. */ #include "xp.h" /* uncomment out these .h files when trust.c is seperated. #include "csllst.h" #include "cslutils.h" #include "csll.h" #include "pics.h" #include "prefapi.h" #include "xpgetstr.h" #include "sechash.h" #include "base64.h" */ #include "jscookie.h" #include "mkaccess.h" /* use #include "trust.h" when it is broken out of mkaccess.h */ #include "prlong.h" #ifdef _DEBUG #define HTTrace OutputDebugString #else #define HTTrace #endif #define PICS_VERSION 1.1 /* the version of PICS labels that this code expects */ CSLabel_callback_t ProcessService; CSLabel_callback_t ProcessLabel; CSLabel_callback_t ProcessSingleLabel; PRBool IsValidValue( FVal_t *Value, int MinValue, int MaxValue, int *TheValue ); PRBool IsExpired( DVal_t *Value, PRTime *ExpirationDate ); PRBool IsValidTrustService( char *ServiceName ); PRBool ISODateToLocalTime( DVal_t *Value, PRTime *LocalDate ); PRBool CheckOptions( LabelOptions_t *LabelOptions, PRTime *ExpirationDate ); PRBool IsLabelSigned( Extension_t *AExt ); PRBool IsSignatureValid( Extension_t *AExt, LabelOptions_t *LabelOptions ); extern int NET_SameDomain(char * currentHost, char * inlineHost); extern char * lowercase_string(char *string); extern char * illegal_to_underscore(char *string); /* THIS IS THE MASTER LIST OF TRUST LABELS. The labels stay on this list until they are matched to an incoming cookie. */ XP_List *TrustList = NULL; #ifdef _DEBUG /************** FOR DEBUGGINGG ***********************************/ #include "csparse.h" LabelTargetCallback_t targetCallback; StateRet_t trustCallback(CSLabel_t * pCSMR, CSParse_t * pCSParse, CSLLTC_t target, PRBool closed, void * pVoid) { #ifdef NOPE static int Total = 0; char space[256]; int change = closed ? -target : target; Total += change; sprintf( space, "(%2d:%3d)token-->|%s| %s %s \n", Total, closed ? -target : target, pCSParse->token->data, closed ? " ending" : "starting", pCSParse->pTargetObject->note ); sprintf(space, "%s %s (%d)\n", closed ? " ending" : "starting", pCSParse->pParseState->note, closed ? -target : target); HTTrace(space); if ( Total == 0 ) HTTrace( "All Done\n" ); #endif return StateRet_OK; } /* LLErrorHandler_t parseErrorHandler; */ StateRet_t trustErrorHandler(CSLabel_t * pCSLabel, CSParse_t * pCSParse, const char * token, char demark, StateRet_t errorCode) { char space[256]; sprintf(space, "%20s - %s: ", pCSParse->pTargetObject->note, pCSParse->currentSubState == SubState_X ? "SubState_X" : pCSParse->currentSubState == SubState_N ? "SubState_N" : pCSParse->currentSubState == SubState_A ? "SubState_A" : pCSParse->currentSubState == SubState_B ? "SubState_B" : pCSParse->currentSubState == SubState_C ? "SubState_C" : pCSParse->currentSubState == SubState_D ? "SubState_D" : pCSParse->currentSubState == SubState_E ? "SubState_E" : pCSParse->currentSubState == SubState_F ? "SubState_F" : pCSParse->currentSubState == SubState_G ? "SubState_G" : pCSParse->currentSubState == SubState_H ? "SubState_H" : "???"); HTTrace(space); switch (errorCode) { case StateRet_WARN_NO_MATCH: if (token) sprintf(space, "Unexpected token \"%s\".\n", token); else sprintf(space, "Unexpected lack of token.\n"); break; case StateRet_WARN_BAD_PUNCT: if (token) sprintf(space, "Unexpected punctuation |%c| after token \"%s\".\n", demark, token); else sprintf(space, "Unexpected punctuation |%c| \n", demark); break; case StateRet_ERROR_BAD_CHAR: sprintf(space, "Unexpected character \"%c\" in token \"%s\".\n", *pCSParse->pParseContext->pTokenError, token); break; default: sprintf(space, "Internal error: demark:\"%c\" token:\"%s\".\n", demark, token); break; } HTTrace(space); /* CSLabel_dump(pCSMR); HTTrace(pParseState->note); */ return errorCode; } /*************** END OF FOR DEBUGGINGG *********************************** */ #endif /*---------------------------------------------------------------------------------------------------- * Purpose: given the value part of a PICS label parse it and determine * if it is a valid trust label according to internet draft * draft-ietf-http-trust-state-mgt-02.txt * *---------------------------------------------------------------------------------------------------- */ PUBLIC void PICS_ExtractTrustLabel( URL_Struct *URL_s, char *value ) { CSParse_t * pCSParse = 0; CSDoMore_t status; #ifdef _DEBUG /* display the label for debug */ HTTrace( "\n" ); HTTrace( value ); HTTrace( "\n" ); #endif /* validate input args */ if ( !URL_s || !URL_s->address || !value || *value == '\0' ) return; /* parse the PICS label and extract the trust label information from it */ /* ignoring the other rating information. */ /* init the PICS parsing code */ #ifdef _DEBUG pCSParse = CSParse_newLabel( &trustCallback, &trustErrorHandler ); #else pCSParse = CSParse_newLabel( 0, 0 ); #endif if ( pCSParse ) { /* parse the label - the entire label is in value. So one call to parse chunk is all that is needed.*/ status = CSParse_parseChunk(pCSParse, value, XP_STRLEN(value), 0); /* was the parse sucessfull? */ if ( status == CSDoMore_done ) { /* yes - Iterate thru the services looking for valid trust labels. * the PICS label parsing code is set up to iterate thru the labels. * the hierarchy is: * Services * Labels * SingleLabels * Label Options * Label Ratings */ CSLabel_t * pCSLabel = CSParse_getLabel( pCSParse ); /* make sure the PICS version is correct */ if ( PICS_VERSION <= FVal_value(&CSLabel_getCSLLData(pCSLabel)->version) ) { /* iterate thru each of the service IDs in this label calling ProcessService for each*/ CSLabel_iterateServices( pCSLabel, ProcessService, NULL, 0, (void *)(URL_s->address)); /* IF there are valid trust labels in this PICS label they are added to */ /* the trust list at TrustList */ } } else { /* either there was a error parsing the label or the label wasnt complete. In either case ignore the label */ HTTrace( "Invalid label\n" ); } CSParse_deleteLabel(pCSParse); /* free the label parsing structures */ } } /*---------------------------------------------------------------------------------------------------- * Purpose: the call back to handle a single service ID * * *----------------------------------------------------------------------------------------------------*/ CSError_t ProcessService(CSLabel_t * pCSLabel, State_Parms_t * pParms, const char * identifier, void * szURL) { CSError_t ret = CSError_OK; if ( IsValidTrustService( CSLabel_getServiceName( pCSLabel ) ) ) { /* yes - passed the first test for trust labels, i.e. a valid trust service I dont care about any of the service level options at this point; but if I did I would use LabelOptions_t Opt = pServiceInfo->pLabelOptions to check them So iterate thru the labels which if they have the purpose, Recipients and identifiable ratings will be trust labels */ ret = CSLabel_iterateLabels(pCSLabel, ProcessLabel, pParms, 0, szURL); } else { /* if this is not a trust label but a regular PICS label it will usually fail the rating service. So this is an expected occurance. */ HTTrace( "ProcessService: invalid trust rating service\n" ); } return ret; } /*---------------------------------------------------------------------------------------------------- * Purpose: the call back to process a label and iterate thru the SingleLabels * * *----------------------------------------------------------------------------------------------------*/ CSError_t ProcessLabel(CSLabel_t * pCSLabel, State_Parms_t * pParms, const char * identifier, void * szURL) { return CSLabel_iterateSingleLabels(pCSLabel, ProcessSingleLabel, pParms, 0, szURL); } void TL_SetTrustAuthority( TrustLabel *ALabel, char *TrustAuthority ); void TL_SetByField( TrustLabel *ALabel, char *szBy ); void TL_SetURLField( TrustLabel *ALabel, char *szURL ); void TL_ProcessForAttrib( TrustLabel *ALabel, char *szFor); /*---------------------------------------------------------------------------------------------------- * Purpose: the call back get the options and the ratings for a single label. * Create a TrustLabel to contain the info about the label and put on the * the trust label list * * Input: * pCSLabel - current parsed label instance * szURL - the URL associated with this trust label * NOTES: * 1. If the same rating is seen twice in one single label, the first VALID instance is used. * * History: * 8/22/98 Paul Chek - switch recipient to support a range of values *---------------------------------------------------------------------------------------------------- */ CSError_t ProcessSingleLabel(CSLabel_t * pCSLabel, State_Parms_t * pParms, const char * identifier, void * szURL) { /* tracks the ratings I have seen */ #define HAVE_PURPOSE 0x1 #define HAVE_RECIPIENTS 0x2 #define HAVE_ID 0x4 typedef struct { char *szName; /* the full name of the rating */ int Min, Max; /* the valid ranges for the rating */ } ValidRating; /* the ratings I am interested in for a trust label */ ValidRating PurposeRating = { "purpose", 0, 5 }; ValidRating RecipientsRating = { "recipients", 0, 3 }; ValidRating IDRating = { "identifiable", 0, 1 }; CSError_t ret = CSError_OK; int PurposeRange = 0; /* bits corresponding to the purpose ranges seen */ int RecpRange = 0; int IDValue = 0; HTList * ranges; Range_t * pRange; int TempValue, MinValue, MaxValue; int i; TrustLabel *TheLabel; Extension_t *AExt; ExtensionData_t *AData; char *AName; PRBool bForgedLabel; /* march thru the ratings looking for purpose, Recipients and identification. When found save their values. */ int count = 0; if (!pCSLabel || !szURL ) { /* oops got a bad one */ ret = CSError_BAD_PARAM; } else { /* the current single label */ SingleLabel_t * pSingleLabel = CSLabel_getSingleLabel(pCSLabel); /* get the options */ LabelOptions_t *LabelOptions = pSingleLabel->pLabelOptions; PRTime ExpDate; /* the expiration date */ /* VALIDITY TESTS */ /* Has the expiration date passed - there must be an expiration date - sec 3.4.2 */ /* and these options are required "by", "generic", "on" - sec 3.1? */ if ( CheckOptions( LabelOptions, &ExpDate ) ) { /* yes - check the ratings for purpose, Recipients and ID */ /* get the Ratings list */ HTList *LabelRatings = pSingleLabel->labelRatings; LabelRating_t *Rating; PRBool bContinue = TRUE; short AllRatings = HAVE_PURPOSE | HAVE_RECIPIENTS | HAVE_ID; /* look thru all the ratings until I have the 3 required ratings */ while ( AllRatings != 0 && (Rating = (LabelRating_t *) HTList_nextObject(LabelRatings))) { /* is it the purpose rating? */ if ( (AllRatings & HAVE_PURPOSE) && !XP_STRCASECMP( SVal_value(&Rating->identifier), PurposeRating.szName)) { /* Was a single value given?? */ if ( IsValidValue( &Rating->value, PurposeRating.Min, PurposeRating.Max, &TempValue ) ) { PurposeRange = PurposeRange | ( 1 << TempValue ); AllRatings &= (~HAVE_PURPOSE ); /* Was a range or a list of values given?? */ } else if ( Rating->ranges ) { ranges = Rating->ranges; while ((pRange = (Range_t *) HTList_nextObject(ranges))) { MinValue = MaxValue = -1; if ( IsValidValue( &pRange->min, PurposeRating.Min, PurposeRating.Max, &MinValue ) ) { PurposeRange = PurposeRange | ( 1 << MinValue ); AllRatings &= (~HAVE_PURPOSE ); } if ( IsValidValue( &pRange->max, PurposeRating.Min, PurposeRating.Max, &MaxValue ) ) { /* if there was also a min value then set all the bits between the min and the max */ if ( 0 <= MinValue && MinValue <= MaxValue ) { for( i=MinValue; i<=MaxValue; i++ ) PurposeRange = PurposeRange | ( 1 << i ); } else { PurposeRange = PurposeRange | ( 1 << MaxValue ); } AllRatings &= (~HAVE_PURPOSE ); } } } /* is it the Recipients rating? */ } else if ( (AllRatings & HAVE_RECIPIENTS) && !XP_STRCASECMP(SVal_value(&Rating->identifier), RecipientsRating.szName)) { /* Was a single value given?? */ if ( IsValidValue( &Rating->value, RecipientsRating.Min, RecipientsRating.Max, &TempValue ) ) { RecpRange = RecpRange | ( 1 << TempValue ); AllRatings &= (~HAVE_RECIPIENTS ); /* Was a range or a list of values given?? */ } else if ( Rating->ranges ) { ranges = Rating->ranges; while ((pRange = (Range_t *) HTList_nextObject(ranges))) { MinValue = MaxValue = -1; if ( IsValidValue( &pRange->min, RecipientsRating.Min, RecipientsRating.Max, &MinValue ) ) { RecpRange = RecpRange | ( 1 << MinValue ); AllRatings &= (~HAVE_RECIPIENTS ); } if ( IsValidValue( &pRange->max, RecipientsRating.Min, RecipientsRating.Max, &MaxValue ) ) { /* if there was also a min value then set all the bits between the min and the max */ if ( 0 <= MinValue && MinValue <= MaxValue ) { for( i=MinValue; i<=MaxValue; i++ ) RecpRange = RecpRange | ( 1 << i ); } else { RecpRange = RecpRange | ( 1 << MaxValue ); } AllRatings &= (~HAVE_RECIPIENTS ); } } } /* is it the identifiable rating */ } else if ( (AllRatings & HAVE_ID) && !XP_STRCASECMP(SVal_value(&Rating->identifier), IDRating.szName)) { /* yes - is the range valid? */ if ( IsValidValue( &Rating->value, IDRating.Min, IDRating.Max, &IDValue ) ) { AllRatings &= (~HAVE_ID ); } } } /* end while ( AllRatings */ /* Did I get the required ratings? */ if ( !AllRatings ) { /* yes */ /*HTTrace( " Valid trust label: purpose = 0x%0x, ID = %d, recipients = %d\n", PurposeRange, IDValue, RecpRange ); */ /*HTTrace( " for: \"%s\" \n", SVal_value(&LabelOptions->fur)); */ /*HTTrace( " expires: %s\n", DVal_value( &LabelOptions->until ) ); */ TheLabel = TL_Construct(); /* allocate a net trust label */ if ( TheLabel ) { /* fill up the structure */ TheLabel->purpose = PurposeRange; TheLabel->ID = IDValue; TheLabel->recipients = RecpRange; TheLabel->ExpDate = ExpDate; TL_SetTrustAuthority( TheLabel, CSLabel_getServiceName( pCSLabel ) ); TL_SetByField( TheLabel, SVal_value(&LabelOptions->by) ); TL_SetURLField( TheLabel, szURL ); bForgedLabel = FALSE; /* if this is a generic label then set the isGeneric flag */ if ( BVal_value( &LabelOptions->generic ) ) TheLabel->isGeneric = TRUE; /* if there is a cookieinfo extension and it had a name(s) then save the name */ if ( LabelOptions->extensions ) { while( !bForgedLabel && (AExt = (Extension_t *)XP_ListNextObject( LabelOptions->extensions )) ) { /* is this an extension for cookie info? */ if ( IsValidTrustService( SVal_value(&AExt->url) ) ) { /* is there data attached to the extension - that is stuff besides the mandatory | optional and the URL */ if ( AExt->extensionData ) { /* yes copy the list to the trust label */ if ( !TheLabel->nameList ) TheLabel->nameList = XP_ListNew(); if ( TheLabel->nameList ) { while( (AData = (ExtensionData_t *)HTList_nextObject( AExt->extensionData ) ) ) { AName = XP_STRDUP( AData->text ); /* copy it */ XP_ListAddObjectToEnd( TheLabel->nameList, AName ); /* add it to the trust label list */ } } } /* Is this a digital signature extension?? */ } else if ( IsLabelSigned( AExt ) ) { /* Yes - the label is signed, I must now check if the signature is valid. If the signature is NOT valid then throw the label out. */ if ( IsSignatureValid( AExt, LabelOptions ) ) { /* the label is signed with a good signature */ TheLabel->isSigned = TRUE; } else { /* the label has a signature but the MIC on the label doesnt match the signature, so someone has fooled with the label */ bForgedLabel = TRUE; } } /* end of if ( IsValidTrustService */ } } /* Was the label forged?? */ if ( !bForgedLabel ) { /* seperate the path and domain out of the "for" label attribute */ TL_ProcessForAttrib( TheLabel, SVal_value(&LabelOptions->fur) ); /* add the trust label to the list of trust labels in this header */ if ( !TrustList ) { /* create the list */ TrustList = XP_ListNew(); } if ( TrustList ) { /* NOTE: this is the only place where trust label are added to the TrustList */ XP_ListAddObjectToEnd( TrustList, TheLabel ); HTTrace( " Valid trust label\n" ); } else { HTTrace( "ERROR in ProcessSingleLabel: unable to allocate the trust list\n" ); ret = CSError_APP; } } else { /* the label was forged - discard it */ HTTrace( "Forged label\n" ); TL_Destruct( TheLabel ); } } else { /* memory allocation problems */ HTTrace( "ERROR in ProcessSingleLabel: failed to allocate trust object\n" ); ret = CSError_APP; } } else { /* no not a valid trust label, not a big deal, keep goin */ HTTrace( " Label not a trust label - not all ratings present.\n" ); } } else { /* not a valid trust label - missing expiration date or for option */ HTTrace( " Label not a trust label - missing a required option\n" ); } /* if ( !IsExpired( LabelOptions */ } /* if (!pCSLabel || */ return ret; } /*---------------------------------------------------------------------------------------------------- * Purpose: determine if the value for a rating falls within the specified range * * ---------------------------------------------------------------------------------------------------- */ PRBool IsValidValue( FVal_t *Value, int MinValue, int MaxValue, int *TheValue ) { if ( FVal_initialized(Value) ) { /* NOTE: the conversion from a float to an int, since for trust labels we are */ /* only dealing with ints. */ *TheValue = (int)FVal_value(Value); if ( MinValue <= (*TheValue) && (*TheValue) <= MaxValue ) { return TRUE; } } return FALSE; } /*---------------------------------------------------------------------------------------------------- * Purpose: determine if the required label options are present. * * * returns: TRUE if all the required options are present * ExpDate - returns the label expiration date * * ---------------------------------------------------------------------------------------------------- */ PRBool CheckOptions( LabelOptions_t *LabelOptions, PRTime *ExpirationDate ) { PRBool Status = FALSE; /* According to the spec these options must be present: * "by", "gen", "for", "on" AND "exp" OR "until". AND the expiration date must * not have passed. */ if ( !IsExpired( &LabelOptions->until, ExpirationDate ) && /* expiration date */ SVal_initialized( &LabelOptions->fur ) && /* for option */ SVal_initialized( &LabelOptions->by ) && /* by option */ DVal_initialized( &LabelOptions->on ) && /* on option */ BVal_initialized( &LabelOptions->generic ) ) { /* generic option */ Status = TRUE; } return Status; } /*---------------------------------------------------------------------------------------------------- * Purpose: determine if the expiration date has passed. * * Note: * The PICS spec calls for only one form for the date, ISO 8601:1988 which is * YYYY.MM.DDTHH:MMSxxxx * where S = - or + * xxxx = four digit time zone offset * * returns * TRUE if the expiration date has PASSED or is not present * FALSE if the expiration date is AFTER now. * ---------------------------------------------------------------------------------------------------- */ PRBool IsExpired( DVal_t *Value, PRTime *ExpirationDate ) { PRTime CurrentTime; /* Has the expiration date been given?? */ if (DVal_initialized( Value ) ) { /* yes - is it before now? */ if ( ISODateToLocalTime( Value, ExpirationDate ) ) { /* get the exploded local time parameters */ CurrentTime = PR_Now(); /*HTTrace( "Cur Time = %s", ctime( &CurrentTime ) ); */ /*HTTrace( "Exp Time = %s", ctime( &ExpTime) ); */ if ( LL_CMP(CurrentTime,>,*ExpirationDate) ) { return TRUE; /* Expiration time has passed */ } else { return FALSE; /* Expiration time has NOT passed */ } } } return TRUE; } /*---------------------------------------------------------------------------------------------------- * Purpose: if the given service name is a valid trust service. * * Note: the valid trust services are stored in the user's preferences. * They are of the form "browser.trust.service.XXX.service_enabled" * where XXX is an escaped URL formed by coverting illegal preference characters to underscore * and lowercasing the string . * So the preference for the default trust service * "http: www.w3.org/PICS/systems/P3P-http-trust-state-01.rat" is * pref("browser.trust.service.http___www_w3_org_pics_systems_p3p_http_trust_state_01_rat.service_enabled", true); * * returns TRUE if the given service is a valid trust service * ----------------------------------------------------------------------------------------------------*/ PRBool IsValidTrustService( char *ServiceName ) { char *PrefName; char *escaped_service; PRBool bool_pref; if ( ServiceName && *ServiceName ) { /* Build the preference string - first escape the service name */ escaped_service = XP_STRDUP(ServiceName); escaped_service = illegal_to_underscore(escaped_service); escaped_service = lowercase_string(escaped_service); if(!escaped_service) return FALSE; /* create the preference string */ PrefName = XP_Cat( "browser.trust.service.", escaped_service, ".service_enabled", (char *)NULL ); XP_FREE(escaped_service); if ( PrefName ) { #ifndef FOR_PHASE2 #define FIRST_STR "browser.trust.service.http___www_w3_org_pics_systems_p3p_http_trust_state_01_rat.service_enabled" #define SECOND_STR "browser.trust.service.http___www_w3_org_pics_extensions_cookieinfo_1_0_html.service_enabled" if ( XP_STRCASECMP( PrefName, FIRST_STR ) == 0 || XP_STRCASECMP( PrefName, SECOND_STR ) == 0 ) { return TRUE; } else { return FALSE; } #else /* Now make sure the preference both exists and is enabled */ if(!PREF_GetBoolPref(PrefName, &bool_pref)) { /* the preference exists - this is a known rating service */ XP_FREE( PrefName ); return bool_pref; } else { /* the preference does not exist - this is an unknown rating service */ XP_FREE( PrefName ); return FALSE; } #endif } } return FALSE; } /*---------------------------------------------------------------------------------------------------- * Purpose: takes a parsed ISO date from the PICS label parser and converts * it to a local PRTime * * * returns * TRUE if the date is valid * FALSE if the date is not a valid ISO string * ---------------------------------------------------------------------------------------------------- */ PRBool ISODateToLocalTime( DVal_t *Value, PRTime *LocalDate ) { if (DVal_initialized( Value ) ) { /* the string was parsed into the different fields */ PRExplodedTime tm; XP_MEMSET( (void *)&tm, 0, sizeof( PRExplodedTime ) ); tm.tm_year = Value->year; tm.tm_month = Value->month - 1; tm.tm_mday = Value->day; tm.tm_hour = Value->hour; tm.tm_min = HTMIN(Value->minute, 59 ); /* the adjustment for GMT offset to the local time zone in seconds */ tm.tm_params.tp_gmt_offset = Value->timeZoneHours *3600 + Value->timeZoneMinutes * 60; *LocalDate = PR_ImplodeTime(&tm); return TRUE; } else { return FALSE; } } /*---------------------------------------------------------------------------------------------------- * Purpose: determine if path2 is a prefix of path1 * * returns - TRUE if it is *---------------------------------------------------------------------------------------------------- */ PRBool IsPrefix( char *path1, char *path2 ) { int i; if ( path1 && path2 ) { int len1 = XP_STRLEN( path1 ); int len2 = XP_STRLEN( path2 ); /* Is path2's length <= path1's length?? */ if ( len2 <= len1 ) { /* path1 characters must match path2 up to the length of path1 */ for ( i=0; iname_from_header, CookieData->path_from_header, CookieData->host_from_header, TheLabel ); } return Status; } /**************************************************************** * Purpose: The actual matching code. * This implements part of section 3.3.1 of the trust label spec dealing * with figuring out if a cookie and a trust label are "compatiable". * * TrustList - the list of trust labels to search * CookieName - the name of the cookie * CookiePath - the path for the cookie * CookieHost - the host for the cookie * * returns * TRUE if a matching trust label is found * FALSE if none found * TheLabel - ptr to the matching trust label * * * History: * Paul Chek - initial creation ****************************************************************/ PUBLIC PRBool MatchCookieToLabel2( char *CurURL, char *CookieName, char *CookiePath, char *CookieHost, TrustLabel **TheLabel ) { PRBool Status = FALSE; TrustLabel *ALabel; char *AName; PRBool bNameMatch; XP_List *TempList; TrustLabel *LastMatch = NULL; PRBool LastMatchNamed; XP_List *TempTrustList; /* make sure I have the data I need */ if ( CurURL && CookieName && CookiePath && CookieHost && !XP_ListIsEmpty( TrustList ) && TheLabel ) { /* look thru the list of trust labels for one to match this cookie */ /* First see if there is a named trust label that matches the cookie */ TempTrustList = TrustList; while( (ALabel = (TrustLabel *)XP_ListNextObject( TempTrustList )) ) { /* is this label for this URL? */ if ( XP_STRCASECMP( CurURL, ALabel->szURL ) == 0 ) { /* is this label for a specific cookie(s)?? */ bNameMatch = FALSE; if ( ALabel->nameList != NULL ) { /* yes - do the names match - CASE INSENSITIVE COMPARE ?? */ TempList = ALabel->nameList; /* always walk a list with a COPY of the list pointer */ while( (AName = (char *)XP_ListNextObject( TempList ) ) ) { if ( XP_STRCASECMP (AName, CookieName ) == 0 ) { /* this label has a cookie name and it matches the current cookie */ bNameMatch = TRUE; break; } } } /* do the domains match?? */ if ( NET_SameDomain( ALabel->domainName, CookieHost ) == 1 ) { /* the domains match - is this label a "Generic" label?? */ if ( ALabel->isGeneric ) { /* is the path from the label a prefix to the path in the cookie */ if ( IsPrefix( CookiePath, ALabel->path ) ) { /* this label matches this cookie -- is it the best match */ if ( !LastMatch ) { /* no previous match - take this one */ LastMatch = ALabel; LastMatchNamed = bNameMatch; } else { /* there was a previus match - is this one more specific?? Pick named over unnamed labels; pick non-generic over generic labels. So since the current label is GENERIC, if it is named AND the previous label is NOT named use the current label because it is a better match - named is better than not named. An implied test is if neither are named, since this is a GENERIC label then keep the previous label because it is either a better match or an equivalent match. */ if ( bNameMatch && (!LastMatchNamed) ) { LastMatch = ALabel; LastMatchNamed = bNameMatch; } } } } else { /* this is not a generic label - do the paths match exactly - CASE INSENSITIVE COMPARE ?? */ if ( XP_STRCASECMP( ALabel->path, CookiePath ) == 0 ) { /* this label matches this cookie -- is it the best match */ if ( !LastMatch ) { /* no previous match - take this one */ LastMatch = ALabel; LastMatchNamed = bNameMatch; } else { /* there was a previus match - is this one more specific?? Pick named over unnamed labels; pick non-generic over generic labels. So since the current label is NON-GENERIC, if it is named use it because it is either a better match or an equivalent match. If it is not named AND the previous label is not named then use the current label because it is either a better match or an equivalent match. */ if ( bNameMatch || (!LastMatchNamed) ) { /* both are named, the current label is non-generic, use it */ LastMatch = ALabel; LastMatchNamed = bNameMatch; } } } } /* end of if ( ALabel->isGeneric */ } /* end of if ( NET_SameDomain */ } /* end of if ( XP_STRNCASECMP( CurURL, */ } /* end of while( (ALabel */ } /* Was there a match?? */ if ( LastMatch ) { /* yes */ *TheLabel = LastMatch; return TRUE; } else { return FALSE; } } /*---------------------------------------------------------------------------------------------------- * Purpose: returns true if the user preference for supporting trust labels is * set to true. * * *---------------------------------------------------------------------------------------------------- */ PUBLIC PRBool IsTrustLabelsEnabled() { #ifndef FOR_PHASE2 return TRUE; #else static int bEnabled = -1; if ( bEnabled == -1 ) { /* on the first call get it from the preferences */ PREF_GetBoolPref("browser.PICS.trust_labels_enabled", &bEnabled); } return (PRBool)bEnabled; #endif } /*---------------------------------------------------------------------------------------------------- * Purpose: returns true if the given extension is the Digital Signature extension * *---------------------------------------------------------------------------------------------------- */ PRBool IsLabelSigned( Extension_t *AExt ) { return FALSE; /* not handling signed label right now */ } /*---------------------------------------------------------------------------------------------------- * Purpose: returns true if the given Digital Signature extension is a valid signature for * the given label. If this returns false then we have a forged label. * *---------------------------------------------------------------------------------------------------- */ PRBool IsSignatureValid( Extension_t *AExt, LabelOptions_t *LabelOptions ) { return TRUE; /* not handling signed label right now */ } /*\\//\\//\\//\\// "MEMBERS" OF THE TRUST LABEL "CLASS" \\//\\//\\//\\//\\//\\//\\//\\//\\// */ /*---------------------------------------------------------------------------------------------------- * Purpose: construct a Trust Label and init its members * * returns - the new initialized TrustLabel * ----------------------------------------------------------------------------------------------------*/ TrustLabel *TL_Construct() { TrustLabel *ALabel = NULL; ALabel = XP_ALLOC( sizeof(TrustLabel) ); if ( ALabel ) { ALabel->purpose = 0; ALabel->ID = 0; ALabel->recipients = 0; ALabel->szTrustAuthority = NULL; ALabel->isGeneric = FALSE; ALabel->isSigned = FALSE; #ifdef XP_MAC ALabel->ExpDate.hi = ALabel->ExpDate.lo = 0; #else ALabel->ExpDate = 0; #endif ALabel->signatory = NULL; ALabel->domainName = NULL; ALabel->path = NULL; ALabel->nameList = NULL; ALabel->szBy = NULL; ALabel->szURL = NULL; time(&ALabel->TimeStamp); /* second since 1970 */ } return ALabel; } /*---------------------------------------------------------------------------------------------------- * Purpose: destroy a TrustLabel freeing allocated memory * * ----------------------------------------------------------------------------------------------------*/ PUBLIC void TL_Destruct( TrustLabel *ALabel ) { char *AName; if ( ALabel ) { if ( ALabel->signatory ) XP_FREE( ALabel->signatory ); if ( ALabel->domainName ) XP_FREE( ALabel->domainName ); if ( ALabel->path ) XP_FREE( ALabel->path ); if ( ALabel->szTrustAuthority ) XP_FREE( ALabel->szTrustAuthority ); if ( ALabel->szBy ) XP_FREE( ALabel->szBy ); if ( ALabel->szURL ) XP_FREE( ALabel->szURL ); if ( ALabel->nameList ) { while( (AName = (char *)XP_ListRemoveEndObject( ALabel->nameList )) ){ XP_FREE( AName ); } /* now delete the list */ XP_ListDestroy( ALabel->nameList ); } XP_FREE( ALabel ); } } /*---------------------------------------------------------------------------------------------------- * Purpose: decompose the "for" label attribute into a domain and path * and save in the trust label * * ----------------------------------------------------------------------------------------------------*/ void TL_ProcessForAttrib( TrustLabel *ALabel, char *szFor) { char *p; if ( ALabel && szFor ) { /* for the domain - skip to the "//" to jump over the protocol, */ /* this is the beginning of the domain, then */ /* look for the first ":" or "/" to mark the end of the domain */ p = XP_STRCASESTR(szFor, "//"); if ( p == NULL ) { NET_SACopy( &ALabel->domainName, szFor); } else { NET_SACopy( &ALabel->domainName, p+2); } for(p=ALabel->domainName; *p != '\0' && *p != ':' && *p != '/'; p++); /* skip to end OR : or / */ /* for the path it starts where the domain stopped */ NET_SACopy( &ALabel->path, p ); *p = '\0'; /* terminate the domain name */ } } /*---------------------------------------------------------------------------------------------------- * Purpose: set the signatory for a signed label * * ----------------------------------------------------------------------------------------------------*/ void TL_SetSignatory( TrustLabel *ALabel, char *Signatory ) { if ( ALabel && Signatory ) { NET_SACopy( &ALabel->signatory, Signatory ); } } /*---------------------------------------------------------------------------------------------------- * Purpose: set the trust authority string * * ----------------------------------------------------------------------------------------------------*/ void TL_SetTrustAuthority( TrustLabel *ALabel, char *TrustAuthority ) { if ( ALabel && TrustAuthority ) { NET_SACopy( &ALabel->szTrustAuthority, TrustAuthority ); } } /*---------------------------------------------------------------------------------------------------- * Purpose: set the by field in the label from the "by" label option * * ----------------------------------------------------------------------------------------------------*/ void TL_SetByField( TrustLabel *ALabel, char *szBy ) { if ( ALabel && szBy ) { NET_SACopy( &ALabel->szBy, szBy ); } } /*---------------------------------------------------------------------------------------------------- * Purpose: set the URL field in the label * * ----------------------------------------------------------------------------------------------------*/ void TL_SetURLField( TrustLabel *ALabel, char *szURL ) { if ( ALabel && szURL ) { NET_SACopy( &ALabel->szURL, szURL ); } } #endif /* end of #ifdef TRUST_LABELS */