home *** CD-ROM | disk | FTP | other *** search
- /* -*- 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
- */
-
- #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;
- }
-
-