Exemple #1
0
PUBLIC int HTMIME_contentType (HTRequest * request, HTResponse * response,
			       char * token, char * value)
{
    char * field;
    if ((field = HTNextField(&value)) != NULL) {

	/* Get the Content-Type */
        char *lc = field;
	while ((*lc = TOLOWER(*lc))) lc++; 
	HTResponse_setFormat(response, HTAtom_for(field));

	/* Get all the parameters to the Content-Type */
	{
	    char * param;
	    while ((field = HTNextField(&value)) != NULL &&
		   (param = HTNextField(&value)) != NULL) {
		lc = field;
		while ((*lc = TOLOWER(*lc))) lc++;
		lc = param;
		while ((*lc = TOLOWER(*lc))) lc++;
		HTResponse_addFormatParam(response, field, param);
	    }
	}
    }
    return HT_OK;
}
Exemple #2
0
PUBLIC int HTMIME_cacheControl (HTRequest * request, HTResponse * response,
				char * token, char * value)
{
    /*
    **  Walk through the set of cache-control directives and add them to the
    **  response association list for cache control directives
    */
    char * name_val;
    while ((name_val = HTNextPair(&value)) != NULL) {
	char * name = HTNextField(&name_val);
	char * val = HTNextField(&name_val);
	if (name) HTResponse_addCacheControl(response, name, val ? val : "");
    }
    return HT_OK;
}
Exemple #3
0
/*
**	Find the next s-expression token from a string of characters.
**	We return the name of this expression and the param points to the
**	parameters. 
**
**	NOTE: The string has been mutilated by '/0's
*/
char* HTNextSExp (char** exp, char** param)
{
    char* p = *exp;
    char* name = NULL;
    if (!exp || !*exp) return NULL;
    while (*p && isspace((int) *p)) p++;		/* Strip leading white space */
    if (!*p) {
	*exp = p;
	return NULL;					   	 /* No field */
    }
    if (*p == '{') {					     /* Open bracket */
	int cnt = 1;
	/*
	**  Look for name of this expression. If we find a token then search
	**  for the rest of the expression and remove the end '}'
	*/
	p++;
	if ((name = HTNextField(&p)) == NULL) return NULL;
	while (*p && isspace((int) *p)) p++;
	*param = p;
	while (*p) {
	    if (*p == '{') cnt++;
	    if (*p == '}') cnt--;
	    if (!cnt) {
		*p = '\0';
		break;
	    }
	    p++;
	}
    }
    return name;
}
Exemple #4
0
PUBLIC int HTMIME_contentLength (HTRequest * request, HTResponse * response,
				 char * token, char * value)
{
    char * field;
    if ((field = HTNextField(&value)) != NULL)
        HTResponse_setLength(response, atol(field));
    return HT_OK;
}
Exemple #5
0
PUBLIC int HTMIME_contentRange (HTRequest * request, HTResponse * response,
				char * token, char * value)
{
    char * field;
    if ((field = HTNextField(&value)))
	HTResponse_addRange(response, field, value);
    return HT_OK;
}
Exemple #6
0
PUBLIC char * HTResponse_etag (HTResponse * me)
{
    if (me && me->headers) {
        char * value = HTAssocList_findObject(me->headers, "etag");
        char * etag = HTNextField(&value);
        return etag;
    }
    return NULL;
}
Exemple #7
0
PUBLIC int HTMIME_authenticate (HTRequest * request, HTResponse * response,
				char * token, char * value)
{    
    char * scheme = HTNextField(&value);
    if (scheme) {
	HTResponse_addChallenge(response, scheme, value);
	HTResponse_setScheme(response, scheme);
    }
    return HT_OK;
}
Exemple #8
0
PUBLIC int HTMIME_contentTransferEncoding (HTRequest * request, HTResponse * response,
					   char * token, char * value)
{
    char * field;
    if ((field = HTNextField(&value)) != NULL) {
        char *lc = field;
	while ((*lc = TOLOWER(*lc))) lc++;
	HTResponse_setContentTransferEncoding(response, HTAtom_for(field));
    }
    return HT_OK;
}
Exemple #9
0
/*
**	Scan the request line for METHOD, URI and VERSION
**	Returns:	HT_OK		if 1.x request and OK
**			HT_LOADED     	if 0.9 request and OK
**			HT_ERROR	if invalid request line
*/
PRIVATE int ParseRequest (HTStream * me)
{
    HTRequest * client = HTList_firstObject(me->http->clients);
    char * line = HTChunk_data(me->buffer);
    char * method_str = HTNextField(&line);
    char * request_uri = HTNextField(&line);
    char * version_str = HTNextField(&line);
    HTMethod method;

    /* Check if method is allowed */
    if (!method_str || (method = HTMethod_enum(method_str))==METHOD_INVALID) {
        HTRequest_addError(client, ERR_FATAL, NO, HTERR_NOT_ALLOWED,
                           NULL, 0, "ParseRequest");
        return HT_ERROR;
    }
    HTRequest_setMethod(client, method);

    /* Find an anchor for the request URI */
    if (request_uri) {
        char * uri = HTParse(request_uri, "file:", PARSE_ALL);
        HTRequest_setAnchor(client, HTAnchor_findAddress(uri));
        HT_FREE(uri);
    } else {
        HTRequest_addError(client, ERR_FATAL, NO, HTERR_BAD_REQUEST,
                           NULL, 0, "ParseRequest");
        return HT_ERROR;
    }

    /* Get ready to get the rest of the request */
    if (version_str) {
        me->target = HTStreamStack(WWW_MIME_HEAD,
                                   HTRequest_debugFormat(client),
                                   HTRequest_debugStream(client),
                                   client, NO);
        return HT_OK;
    } else {
        HTRequest_addError(client, ERR_FATAL, NO, HTERR_BAD_VERSION,
                           NULL, 0, "ParseRequest");
        return HT_ERROR;
    }
}
Exemple #10
0
PUBLIC int HTMIME_connection (HTRequest * request, HTResponse * response,
			      char * token, char * value)
{
    /*
    **  Walk through the set of connection directives and add them to the
    **  response association list for connection directives
    */
    char * name_val;
    while ((name_val = HTNextPair(&value)) != NULL) {
	char * name = HTNextField(&name_val);
	char * val = HTNextField(&name_val);

	/*
	**  If we have a name then look if it is concerning persistent
	**  connections. If so, then we handle it here, otherwise we leave it
	**  to somebody else by simply adding it to the list of connection
	**  tokens.
	*/
	if (name) {
	    HTNet * net = HTRequest_net(request);
	    HTHost * host = HTNet_host(net);
	    if (!strcasecomp(name, "close")) {			 /* HTTP/1.1 */
		HTTRACE(STREAM_TRACE, "MIMEParser.. Close received...\n");
		HTHost_setCloseNotification(host, YES);
	    } else if (!strcasecomp(name, "keep-alive")) {       /* HTTP/1.0 */

		/*
		**  In case this is an HTTP/1.1 server sending keep-alive then
		**  ignore it.
		*/
		if (HTHost_version(host) < HTTP_11) {
		    HTNet_setPersistent(net, YES, HT_TP_SINGLE);
		    HTTRACE(STREAM_TRACE, "MIMEParser.. HTTP/1.0 Keep Alive\n");
		} else 
		    HTTRACE(STREAM_TRACE, "MIMEParser.. HTTP/1.0 Keep Alive ignored\n");
	    } else
		HTResponse_addConnection(response, name, val ? val : "");
	}
    }
    return HT_OK;
}
Exemple #11
0
/*
**	Content MD5
*/
PUBLIC char * HTAnchor_md5 (HTParentAnchor * me)
{
    if (me) {
	if (me->content_md5)
	    return *me->content_md5 ? me->content_md5 : NULL;
	if (me->headers) {
	    char * value = HTAssocList_findObject(me->headers, "content-md5");
	    char * md5;
	    if ((md5 = HTNextField(&value))) StrAllocCopy(me->content_md5,md5);
	    return me->content_md5;
	}
    }
    return NULL;
}
Exemple #12
0
/*
**	Title
*/
PUBLIC const char * HTAnchor_title  (HTParentAnchor * me)
{
    if (me) {
	if (me->title)
	    return *me->title ? me->title : NULL;
	if (me->headers) {
	    char * value = HTAssocList_findObject(me->headers, "title");
	    char * title;
	    if ((title = HTNextField(&value))) StrAllocCopy(me->title, title);
	    return me->title;
	}
    }
    return NULL;
}
Exemple #13
0
/*
**	Derived from
*/
PUBLIC char * HTAnchor_derived (HTParentAnchor * me)
{
    if (me) {
	if (me->derived_from)
	    return *me->derived_from ? me->derived_from : NULL;
	if (me->headers) {
	    char * value = HTAssocList_findObject(me->headers, "derived-from");
	    char * derived_from;
	    if ((derived_from = HTNextField(&value)))
		StrAllocCopy(me->derived_from, derived_from);
	    return me->derived_from;
	}
    }
    return NULL;
}
Exemple #14
0
/*
**	Version
*/
PUBLIC char * HTAnchor_version (HTParentAnchor * me)
{
    if (me) {
	if (me->version)
	    return *me->version ? me->version : NULL;
	if (me->headers) {
	    char * value = HTAssocList_findObject(me->headers, "version");
	    char * version;
	    if ((version = HTNextField(&value)))
		StrAllocCopy(me->version, version);
	    return me->version;
	}
    }
    return NULL;
}
Exemple #15
0
/*
**	Entity Tag
*/
PUBLIC char * HTAnchor_etag (HTParentAnchor * me)
{
    if (me) {
	if (me->etag)
	    return *me->etag ? me->etag : NULL;
	if (me->headers) {
	    char * value = HTAssocList_findObject(me->headers, "etag");
	    char * etag;
	    if ((etag = HTNextField(&value))) StrAllocCopy(me->etag, etag);
	    return me->etag;
	}
    }

    return me ? me->etag : NULL;
}
Exemple #16
0
/*
**	Content Language
*/
PUBLIC HTList * HTAnchor_language (HTParentAnchor * me)
{
    if (me) {
	if (me->content_language == NULL && me->headers) {
	    char * value = HTAssocList_findObject(me->headers, "content-language");
	    char * field;
	    if (!me->content_language) me->content_language = HTList_new();
	    while ((field = HTNextField(&value)) != NULL) {
		char * lc = field;
		while ((*lc = TOLOWER(*lc))) lc++;
		HTList_addObject(me->content_language, HTAtom_for(field));
	    }
	}
	return me->content_language;
    }
    return NULL;
}
Exemple #17
0
/*
**	Allowed methods	(Allow)
*/
PUBLIC HTMethod HTAnchor_allow (HTParentAnchor * me)
{
    if (me) {
	if (me->allow == 0 && me->headers) {
	    char * value = HTAssocList_findObject(me->headers, "allow");
	    char * field;

	    /*
	    **  We treat methods allowed on this object as case insensitive
	    **  in case we receive the information over the net - that is -
	    **  in the Allow header.
	    */
	    while ((field = HTNextField(&value)) != NULL) {
		HTMethod new_method;
		if ((new_method = HTMethod_enum(field)) != METHOD_INVALID)
		    me->allow |= new_method;
	    }
	}
	return me->allow;
    }	
    return METHOD_INVALID;
}
Exemple #18
0
/*
 * This function parses the authentication tokens from
 * the server when the server is requesting HTTP digest
 * authentication.  The tokens are required to generate
 * a valid authentication response in future HTTP
 * requests.
 */
static EST_ERROR est_io_parse_auth_tokens (EST_CTX *ctx, char *hdr)
{
    int rv = EST_ERR_NONE;
    char *p = hdr;
    char *token = NULL;
    char *value = NULL;
    int diff;
    errno_t safec_rc;

    /*
     * header will come in with the basic or digest field still on the front.
     * skip over it.
     */

    token = HTNextField(&p);

    while ((token = HTNextField(&p))) {
        if (!est_strcasecmp_s(token, "realm")) {
            if ((value = HTNextField(&p))) {
                if (EOK != strncpy_s(ctx->realm, MAX_REALM, value, MAX_REALM)) {
                    rv = EST_ERR_INVALID_TOKEN;
                }
            } else {
                rv = EST_ERR_INVALID_TOKEN;
            }
        } else if (!est_strcasecmp_s(token, "nonce")) {
            if ((value = HTNextField(&p))) {
                if (EOK != strncpy_s(ctx->s_nonce, MAX_NONCE, value, MAX_NONCE)) {
                    rv = EST_ERR_INVALID_TOKEN;
                }                
            } else {
                rv = EST_ERR_INVALID_TOKEN;
            }
        } else if (!est_strcasecmp_s(token, "qop")) {
            if ((value = HTNextField(&p))) {

                if (value[0] == '\0') {
                    EST_LOG_WARN("Unsupported qop value: %s", value);
                } else {
                    safec_rc = memcmp_s(value, sizeof("auth"), "auth", sizeof("auth"), &diff);
                    if (safec_rc != EOK) {
                        EST_LOG_INFO("memcmp_s error 0x%xO\n", safec_rc);
                    }
                    if (diff && (safec_rc == EOK)) {
                        EST_LOG_WARN("Unsupported qop value: %s", value);
                    }
                }
            } else {
                rv = EST_ERR_INVALID_TOKEN;
            }
        } else if (!est_strcasecmp_s(token, "algorithm")) {
            if ((value = HTNextField(&p)) && est_strcasecmp_s(value, "md5")) {
                EST_LOG_ERR("Unsupported digest algorithm: %s", value);
                /*
                 **  We only support MD5 for the moment
                 */
                rv = EST_ERR_INVALID_TOKEN;
            }
        } else if (!est_strcasecmp_s(token, "error")) {
            if ((value = HTNextField(&p))) {
                if (EOK != strncpy_s(ctx->token_error, MAX_TOKEN_ERROR, value, MAX_TOKEN_ERROR)) {
                    rv = EST_ERR_INVALID_TOKEN;
                }
            } else {
                rv = EST_ERR_INVALID_TOKEN;
            }
        } else if (!est_strcasecmp_s(token, "error_description")) {
            if ((value = HTNextField(&p))) {
                if (EOK != strncpy_s(ctx->token_error_desc, MAX_TOKEN_ERROR_DESC, value, MAX_TOKEN_ERROR_DESC)) {
                    rv = EST_ERR_INVALID_TOKEN;
                }
            } else {
                rv = EST_ERR_INVALID_TOKEN;
            }
        } else {
            EST_LOG_WARN("Unsupported auth token ignored: %s", token);
        }

        if (rv == EST_ERR_INVALID_TOKEN) {
            memzero_s(ctx->s_nonce, MAX_NONCE+1);
            break;
        }   
    }
    return (rv);
}
Exemple #19
0
/*
 * This function parses the authentication tokens from
 * the server when the server is requesting HTTP digest
 * authentication.  The tokens are required to generate
 * a valid authentication response in future HTTP
 * requests.
 */
static EST_ERROR est_io_parse_auth_tokens (EST_CTX *ctx, char *hdr)
{
    int rv = EST_ERR_NONE;
    char *p = hdr;
    char *token = NULL;
    char *value = NULL;

    /*
     * header will come in with the basic or digest field still on the front.
     * skip over it.
     */
    token = HTNextField(&p);
    
    while ((token = HTNextField(&p))) {
        if (!strcasecmp(token, "realm")) {
            if ((value = HTNextField(&p))) {
                strncpy(ctx->realm, value, MAX_REALM);
            } else {
                rv = EST_ERR_INVALID_TOKEN;
            }
        } else if (!strcasecmp(token, "nonce")) {
            if ((value = HTNextField(&p))) {
                strncpy(ctx->s_nonce, value, MAX_NONCE);
            } else {
                rv = EST_ERR_INVALID_TOKEN;
            }
        } else if (!strcasecmp(token, "qop")) {
            if ((value = HTNextField(&p))) {
                if (strcmp(value, "auth")) {
                    EST_LOG_WARN("Unsupported qop value: %s", value);
                }
            } else {
                rv = EST_ERR_INVALID_TOKEN;
            }
        } else if (!strcasecmp(token, "algorithm")) {
            if ((value = HTNextField(&p)) && strcasecmp(value, "md5")) {
                EST_LOG_ERR("Unsupported digest algorithm: %s", value);
                /*
                **  We only support MD5 for the moment
                */
                rv = EST_ERR_INVALID_TOKEN;
            }
        } else if (!strcasecmp(token, "error")) {
            if ((value = HTNextField(&p))) {
                if (!strncpy(ctx->token_error, value, MAX_TOKEN_ERROR)) {
                    rv = EST_ERR_INVALID_TOKEN;
                }
            } else {
                rv = EST_ERR_INVALID_TOKEN;
            }
        } else if (!strcasecmp(token, "error_description")) {
            if ((value = HTNextField(&p))) {
                if (!strncpy(ctx->token_error_desc, value, MAX_TOKEN_ERROR_DESC)) {
                    rv = EST_ERR_INVALID_TOKEN;
                }
            } else {
                rv = EST_ERR_INVALID_TOKEN;
            }
        } else {
            EST_LOG_WARN("Unsupported auth token ignored: %s", token);
        }
        
        if (rv == EST_ERR_INVALID_TOKEN) {
            memset(ctx->s_nonce, 0, MAX_NONCE);
            break;
        }   
    }
    return (rv);
}
Exemple #20
0
/*	Load one line of configuration
**	------------------------------
**
**	Call this, for example, to load a X resource with config info.
**
** returns	0 OK, < 0 syntax error.
*/
PUBLIC int HTSetConfiguration ARGS1(CONST char *, config)
{
    HTRuleOp op;
    char * line = NULL;
    char * pointer = line;
    char *word1, *word2, *word3;
    float quality, secs, secs_per_byte;
    int status;
    
    StrAllocCopy(line, config);
    {
	char * p = strchr(line, '#');	/* Chop off comments */
	if (p) *p = 0;
    }
    pointer = line;
    word1 = HTNextField(&pointer);
    if (!word1) {
    	free(line);
	return 0;
    } ;	/* Comment only or blank */

    word2 = HTNextField(&pointer);
    word3 = HTNextField(&pointer);

    if (!word2) {
	fprintf(stderr, "HTRule: Insufficient operands: %s\n", line);
	free(line);
	return -2;	/*syntax error */
    }

    if (0==strcasecomp(word1, "suffix") ||
	0==strcasecomp(word1, "addtype")) {
        char * encoding = HTNextField(&pointer);
	if (pointer) status = sscanf(pointer, "%f", &quality);
	else status = 0;
	HTAddType(word2,	word3,
				encoding ? encoding : "binary",
				status >= 1? quality : 1.0);

    } else if (0==strcasecomp(word1, "addencoding")) {
	if (pointer)
	    status = sscanf(pointer, "%f", &quality);
	else status = 0;
	HTAddEncoding(word2, word3,
		      status >= 1 ? quality : 1.0);

    } else if (0==strcasecomp(word1, "addlanguage")) {
	if (pointer)
	    status = sscanf(pointer, "%f", &quality);
	else status = 0;
	HTAddLanguage(word2, word3,
		      status >= 1 ? quality : 1.0);

    } else if (0==strcasecomp(word1, "presentation")) {
        if (pointer) status = sscanf(pointer, "%f%f%f",
			    &quality, &secs, &secs_per_byte);
        else status = 0;
	if (!HTConversions) HTConversions = HTList_new();
	HTSetPresentation(HTConversions, word2, word3,
		    status >= 1? quality 		: 1.0,
		    status >= 2 ? secs 			: 0.0,
		    status >= 3 ? secs_per_byte 	: 0.0 );

    } else {
	op =	0==strcasecomp(word1, "map")  ?	HT_Map
	    :	0==strcasecomp(word1, "pass") ?	HT_Pass
	    :	0==strcasecomp(word1, "fail") ?	HT_Fail
	    :					HT_Invalid;
	if (op==HT_Invalid) {
	    CTRACE(stderr, "HTRule: Bad rule `%s'\n", config);
	} else {  
	    HTAddRule(op, word2, word3);
	} 
    }
    free(line);
    return 0;
}
Exemple #21
0
/*	Load one line of configuration
**	------------------------------
**	Call this, for example, to load a X resource with config info.
**	Returns YES if line OK, else NO
*/
PUBLIC BOOL HTRule_parseLine (HTList * list, const char * config)
{
    HTRuleOp op;
    char * line = NULL;
    char * ptr;
    char * word1, * word2, * word3;
    int status;
    if (!config) return NO;
    if ((ptr = strchr(config, '#'))) *ptr = '\0';
    StrAllocCopy(line, config);				 /* Get our own copy */
    ptr = line;
    HTTRACE(APP_TRACE, "Rule Parse.. `%s\'\n" _ config ? config : "<null>");
    if ((word1 = HTNextField(&ptr)) == NULL) {		       /* Empty line */
	HT_FREE(line);
	return YES;
    }
    if ((word2 = HTNextField(&ptr)) == NULL) {
	HTTRACE(APP_TRACE, "Rule Parse.. Insufficient operands: `%s\'\n" _ line);
	HT_FREE(line);
	return NO;
    }
    word3 = HTNextField(&ptr);

    /* Look for things we recognize */
    if (!strcasecomp(word1, "addtype")) {
	double quality;
        char * encoding = HTNextField(&ptr);
	status = ptr ? sscanf(ptr, "%lf", &quality) : 0;
	HTBind_add(word2,				/* suffix */
		   word3,				/* type */
		   encoding ? encoding : "binary",	/* encoding */
		   NULL,				/* cte */
		   NULL,				/* language */
		   status >= 1? quality : 1.0);		/* quality */

    } else if (!strcasecomp(word1, "addencoding")) {
	double quality;
	status = ptr ? sscanf(ptr, "%lf", &quality) : 0;
	HTBind_addEncoding(word2, word3, status >= 1 ? quality : 1.0);

    } else if (!strcasecomp(word1, "addlanguage")) {
	double quality;
	status = ptr ? sscanf(ptr, "%lf", &quality) : 0;
	HTBind_addLanguage(word2, word3, status >= 1 ? quality : 1.0);

    } else if (!strcasecomp(word1, "presentation")) {
	HTList * converters = HTFormat_conversion();
	double quality, secs, secs_per_byte;
        status = ptr ? sscanf(ptr,"%lf%lf%lf",&quality,&secs,&secs_per_byte):0;
	HTPresentation_add(converters, word2, word3, NULL,
			   status >= 1 ? quality : 1.0,
			   status >= 2 ? secs : 0.0,
			   status >= 3 ? secs_per_byte : 0.0);

    } else if (!strcasecomp(word1, "proxy")) {
	HTProxy_add(word2, word3);
	
    } else if (!strcasecomp(word1, "noproxy")) {
	int port = 0;
        status = ptr ? sscanf(ptr, "%d", &port) : 0;
	HTNoProxy_add(word2, word3, port);

    } else if (!strcasecomp(word1, "gateway")) {
	HTGateway_add(word2, word3);

    } else {
	op =	0==strcasecomp(word1, "map")  ?	HT_Map
	    :	0==strcasecomp(word1, "pass") ?	HT_Pass
	    :	0==strcasecomp(word1, "fail") ?	HT_Fail
	    :					HT_Invalid;
	if (op == HT_Invalid) {
	    HTTRACE(APP_TRACE, "Rule Parse.. Bad or unknown: `%s'\n" _ config);
	} else
	    HTRule_add(list, op, word2, word3);
    }
    HT_FREE(line);
    return YES;
}
Exemple #22
0
int main (int argc, char ** argv)
{
    HTSQL *	sql = NULL;
    char *	sqlserver = DEFAULT_SQL_SERVER;
    char *	sqldb = DEFAULT_SQL_DB;
    char *	sqluser = DEFAULT_SQL_USER;
    char *	sqlpw = DEFAULT_SQL_PW;
    char *	cvsuser = DEFAULT_CVS_USER;
    time_t	cvsdate = -1;
    FILE * fin = stdin;
    char *	input_buffer[BUFSIZE];
    HTChunk *	loginfo = HTChunk_new(BUFSIZE);
    int		arg = 0;
    BOOL	create_db = YES;

    /* Initiate libwww */
    HTLibInit(APP_NAME, APP_VERSION);

    /* Scan command line for parameters */
    for (arg=1; arg<argc; arg++) {
        if (*argv[arg] == '-') {

            if (!strcmp(argv[arg], "-h") || !strcmp(argv[arg], "-?")) {
                VersionInfo();
                Cleanup(0, sql, loginfo);

            } else if (!strcmp(argv[arg], "-v")) {
                HTSetTraceMessageMask("q");

            } else if (!strcmp(argv[arg], "-nocreate")) {
                create_db = NO;

            } else if (!strncmp(argv[arg], "-sqldb", 5)) {
                sqldb = (arg+1 < argc && *argv[arg+1] != '-') ?
                        argv[++arg] : DEFAULT_SQL_DB;

            } else if (!strncmp(argv[arg], "-sqlpassword", 5)) {
                sqlpw = (arg+1 < argc && *argv[arg+1] != '-') ?
                        argv[++arg] : DEFAULT_SQL_PW;

            } else if (!strncmp(argv[arg], "-sqlserver", 5)) {
                sqlserver = (arg+1 < argc && *argv[arg+1] != '-') ?
                            argv[++arg] : DEFAULT_SQL_SERVER;

            } else if (!strncmp(argv[arg], "-sqluser", 5)) {
                sqluser = (arg+1 < argc && *argv[arg+1] != '-') ?
                          argv[++arg] : DEFAULT_SQL_USER;

            } else if (!strncmp(argv[arg], "-cvsuser", 5)) {
                cvsuser = (arg+1 < argc && *argv[arg+1] != '-') ?
                          argv[++arg] : DEFAULT_CVS_USER;

            } else if (!strncmp(argv[arg], "-cvsdate", 5)) {
                cvsdate = (arg+1 < argc && *argv[arg+1] != '-') ?
                          HTParseTime(argv[++arg], NULL, NO) : -1;

            } else {
                fprintf(stderr, "Bad Argument (%s)\n", argv[arg]);
            }
        } else {
            fprintf(stderr, "Bad Argument (%s)\n", argv[arg]);
        }
    }

    /* Get an SQL object */
    if ((sql = HTSQL_new(sqlserver, sqluser, sqlpw, 0)) == NULL)
        Cleanup(-1, sql, loginfo);

    /* Connect to the SQL server */
    if (HTSQL_connect(sql) != YES) Cleanup(-1, sql, loginfo);

    /* Select our database */
    if (HTSQL_selectDB(sql, sqldb) != YES) Cleanup(-1, sql, loginfo);

    /* Create our tables */
    if (create_db) createTables(sql, 0);

    /* Read the arguments from stdin */
    for (;;) {
        int status = fread(input_buffer, 1, BUFSIZE, fin);
        if (status < 0) Cleanup(-1, sql, loginfo);
        if (status == 0) break;
        HTChunk_putb(loginfo, (const char *) input_buffer, status);
    }

    /* Parse the input chunk */
    {
        char * ptr = HTChunk_data(loginfo);
        char * noop1 = HTNextField(&ptr);
        char * noop2 = HTNextField(&ptr);
        char * root = HTNextField(&ptr);
        char * operation = NULL;
        char * files = NULL;
        char * comment = NULL;
        int comment_id = -1;
        int user_id = -1;
        char * p, * q;
#ifdef HT_REENTRANT
        char *lasts;					     /* For strtok_r */
#endif

        /* Find shared log message and get id */
        if ((q = HTStrCaseStr(ptr, "\nLog Message:")) != NULL) {
            comment = q+14;
            *q = '\0';
        }
        if ((comment_id = add_comment(sql, comment)) < 0)
            Cleanup(-1, sql, loginfo);

        /* Add/find user and get id */
        if ((user_id = add_user(sql, cvsuser)) < 0)
            Cleanup(-1, sql, loginfo);

        /* For each operation, find the files involved */
        while ((q = HTStrCaseStr(ptr, " Files:")) != NULL) {

            /* Find the operation */
            files = q+9;
            for (p=q; p>HTChunk_data(loginfo) && *p && *p!='\n'; p--);
            p++;
            operation = HTNextField(&p);

            /* Find the next line */
            if ((q = strchr(files, '\n')) != NULL) {
                *q++ = '\0';
                ptr = q;
            }

            /* Create the query */
            if (operation && files && comment) {
                char * file;
                int location_id = -1;

#ifdef HT_REENTRANT
                if ((file = strtok_r(files, DELIMITERS, &lasts)) != NULL) {
#else
                if ((file = strtok(files, DELIMITERS)) != NULL) {
#endif /* HT_REENTRANT */
                    do {
                        char * path = NULL;
                        StrAllocMCopy(&path, root, "/", file, NULL);

                        /* Add/find location and get id */
                        if ((location_id = add_location(sql, path)) < 0) {
                            Cleanup(-1, sql, loginfo);
                            break;
                        }

#if 0
                        fprintf(stderr, "location: `%s\', user: `%s\', operation: `%s\', comment: `%s\'\n",
                                path, cvsuser, operation, comment);
#endif

                        /* Add log entry */
                        {
                            char buf[16384];
                            char * query = HTSQL_printf(buf, 16384, "insert into %s values (%u,%u,%T,%S,%u)",
                                                        DEFAULT_SQL_LOG_TABLE,
                                                        location_id,
                                                        user_id,
                                                        cvsdate,
                                                        operation,
                                                        comment_id);
                            if (HTSQL_query(sql, query) != YES) {
                                Cleanup(-1, sql, loginfo);
                                break;
                            }
                        }

                        HT_FREE(path);
#ifdef HT_REENTRANT
                    } while ((file = (char *) strtok_r(NULL, DELIMITERS, &lasts)) != NULL);
#else
                    }
                    while ((file = strtok(NULL, DELIMITERS)) != NULL);
#endif /* HT_REENTRANT */
                }
            }
        }
    }

    return 0;
}
Exemple #23
0
/*	Translate by rules					HTTranslate()
 *	------------------
 *
 *	The most recently defined rules are applied first.
 *
 * On entry,
 *	required	points to a string whose equivalent value is needed
 * On exit,
 *	returns		the address of the equivalent string allocated from
 *			the heap which the CALLER MUST FREE. If no translation
 *			occurred, then it is a copy of the original.
 * NEW FEATURES:
 *			When a "protect" or "defprot" rule is matched,
 *			a call to HTAA_setCurrentProtection() or
 *			HTAA_setDefaultProtection() is made to notify
 *			the Access Authorization module that the file is
 *			protected, and so it knows how to handle it.
 *								-- AL
 */
char *HTTranslate(const char *required)
{
    rule *r;
    char *current = NULL;
    char *msgtmp = NULL;
    const char *pMsg;
    int proxy_none_flag = 0;
    int permitredir_flag = 0;

    StrAllocCopy(current, required);

    HTAA_clearProtections();	/* Reset from previous call -- AL */

    for (r = rules; r; r = r->next) {
	char *p = r->pattern;
	int m = 0;		/* Number of characters matched against wildcard */
	const char *q = current;

	for (; *p && *q; p++, q++) {	/* Find first mismatch */
	    if (*p != *q)
		break;
	}

	if (*p == '*') {	/* Match up to wildcard */
	    m = strlen(q) - strlen(p + 1);	/* Amount to match to wildcard */
	    if (m < 0)
		continue;	/* tail is too short to match */
	    if (0 != strcmp(q + m, p + 1))
		continue;	/* Tail mismatch */
	} else
	    /* Not wildcard */ if (*p != *q)
	    continue;		/* plain mismatch: go to next rule */

	if (!rule_cond_ok(r))	/* check condition, next rule if false - kw */
	    continue;

	switch (r->op) {	/* Perform operation */

#ifdef ACCESS_AUTH
	case HT_DefProt:
	case HT_Protect:
	    {
		char *local_copy = NULL;
		char *p2;
		char *eff_ids = NULL;
		char *prot_file = NULL;

		CTRACE((tfp, "HTRule: `%s' matched %s %s: `%s'\n",
			current,
			(r->op == HT_Protect ? "Protect" : "DefProt"),
			"rule, setup",
			(r->equiv ? r->equiv :
			 (r->op == HT_Protect ? "DEFAULT" : "NULL!!"))));

		if (r->equiv) {
		    StrAllocCopy(local_copy, r->equiv);
		    p2 = local_copy;
		    prot_file = HTNextField(&p2);
		    eff_ids = HTNextField(&p2);
		}

		if (r->op == HT_Protect)
		    HTAA_setCurrentProtection(current, prot_file, eff_ids);
		else
		    HTAA_setDefaultProtection(current, prot_file, eff_ids);

		FREE(local_copy);

		/* continue translating rules */
	    }
	    break;
#endif /* ACCESS_AUTH */

	case HT_UserMsg:	/* Produce message immediately */
	    LYFixCursesOn("show rule message:");
	    HTUserMsg2((r->equiv ? r->equiv : "Rule: %s"), current);
	    break;
	case HT_InfoMsg:	/* Produce messages immediately */
	case HT_Progress:
	case HT_Alert:
	    LYFixCursesOn("show rule message:");	/* and fall through */
	case HT_AlwaysAlert:
	    pMsg = r->equiv ? r->equiv :
		(r->op == HT_AlwaysAlert) ? "%s" : "Rule: %s";
	    if (strchr(pMsg, '%')) {
		HTSprintf0(&msgtmp, pMsg, current);
		pMsg = msgtmp;
	    }
	    switch (r->op) {	/* Actually produce message */
	    case HT_InfoMsg:
		HTInfoMsg(pMsg);
		break;
	    case HT_Progress:
		HTProgress(pMsg);
		break;
	    case HT_Alert:
		HTAlert(pMsg);
		break;
	    case HT_AlwaysAlert:
		HTAlwaysAlert("Rule alert:", pMsg);
		break;
	    default:
		break;
	    }
	    FREE(msgtmp);
	    break;

	case HT_PermitRedir:	/* Set special flag */
	    permitredir_flag = 1;
	    CTRACE((tfp, "HTRule: Mark for redirection permitted\n"));
	    break;

	case HT_Pass:		/* Authorised */
	    if (!r->equiv) {
		if (proxy_none_flag) {
		    char *temp = NULL;

		    StrAllocCopy(temp, "NoProxy=");
		    StrAllocCat(temp, current);
		    FREE(current);
		    current = temp;
		}
		CTRACE((tfp, "HTRule: Pass `%s'\n", current));
		return current;
	    }
	    /* Else fall through ...to map and pass */

	case HT_Map:
	case HT_Redirect:
	case HT_RedirectPerm:
	    if (*p == *q) {	/* End of both strings, no wildcard */
		CTRACE((tfp, "For `%s' using `%s'\n", current, r->equiv));
		StrAllocCopy(current, r->equiv);	/* use entire translation */
	    } else {
		char *ins = strchr(r->equiv, '*');	/* Insertion point */

		if (ins) {	/* Consistent rule!!! */
		    char *temp = NULL;

		    HTSprintf0(&temp, "%.*s%.*s%s",
			       (int) (ins - r->equiv),
			       r->equiv,
			       m,
			       q,
			       ins + 1);
		    CTRACE((tfp, "For `%s' using `%s'\n",
			    current, temp));
		    FREE(current);
		    current = temp;	/* Use this */

		} else {	/* No insertion point */
		    char *temp = NULL;

		    StrAllocCopy(temp, r->equiv);
		    CTRACE((tfp, "For `%s' using `%s'\n",
			    current, temp));
		    FREE(current);
		    current = temp;	/* Use this */
		}		/* If no insertion point exists */
	    }
	    if (r->op == HT_Pass) {
		if (proxy_none_flag) {
		    char *temp = NULL;

		    StrAllocCopy(temp, "NoProxy=");
		    StrAllocCat(temp, current);
		    FREE(current);
		    current = temp;
		}
		CTRACE((tfp, "HTRule: ...and pass `%s'\n",
			current));
		return current;
	    } else if (r->op == HT_Redirect) {
		CTRACE((tfp, "HTRule: ...and redirect to `%s'\n",
			current));
		redirecting_url = current;
		HTPermitRedir = (BOOL) (permitredir_flag == 1);
		return (char *) 0;
	    } else if (r->op == HT_RedirectPerm) {
		CTRACE((tfp, "HTRule: ...and redirect like 301 to `%s'\n",
			current));
		redirecting_url = current;
		permanent_redirection = TRUE;
		HTPermitRedir = (BOOL) (permitredir_flag == 1);
		return (char *) 0;
	    }
	    break;

	case HT_UseProxy:
	    if (r->equiv && 0 == strcasecomp(r->equiv, "none")) {
		CTRACE((tfp, "For `%s' will not use proxy\n", current));
		proxy_none_flag = 1;
	    } else if (proxy_none_flag) {
		CTRACE((tfp, "For `%s' proxy server ignored: %s\n",
			current,
			NONNULL(r->equiv)));
	    } else {
		char *temp = NULL;

		StrAllocCopy(temp, "Proxied=");
		StrAllocCat(temp, r->equiv);
		StrAllocCat(temp, current);
		CTRACE((tfp, "HTRule: proxy server found: %s\n",
			NONNULL(r->equiv)));
		FREE(current);
		return temp;
	    }
	    break;

	case HT_Invalid:
	case HT_Fail:		/* Unauthorised */
	    CTRACE((tfp, "HTRule: *** FAIL `%s'\n", current));
	    FREE(current);
	    return (char *) 0;
	}			/* if tail matches ... switch operation */

    }				/* loop over rules */

    if (proxy_none_flag) {
	char *temp = NULL;

	StrAllocCopy(temp, "NoProxy=");
	StrAllocCat(temp, current);
	FREE(current);
	return temp;
    }

    return current;
}
Exemple #24
0
/*	Load one line of configuration
 *	------------------------------
 *
 *	Call this, for example, to load a X resource with config info.
 *
 * returns	0 OK, < 0 syntax error.
 */
int HTSetConfiguration(char *config)
{
    HTRuleOp op;
    char *line = NULL;
    char *pointer = line;
    char *word1;
    const char *word2;
    const char *word3;
    const char *cond_op = NULL;
    const char *cond = NULL;
    float quality, secs, secs_per_byte;
    int maxbytes;
    int status;

    StrAllocCopy(line, config);
    {
	char *p = strchr(line, '#');	/* Chop off comments */

	if (p)
	    *p = 0;
    }
    pointer = line;
    word1 = HTNextField(&pointer);
    if (!word1) {
	FREE(line);
	return 0;
    };				/* Comment only or blank */

    word2 = HTNextField(&pointer);

    if (0 == strcasecomp(word1, "defprot") ||
	0 == strcasecomp(word1, "protect"))
	word3 = pointer;	/* The rest of the line to be parsed by AA module */
    else
	word3 = HTNextField(&pointer);	/* Just the next word */

    if (!word2) {
	fprintf(stderr, "HTRule: %s %s\n", RULE_NEEDS_DATA, line);
	FREE(line);
	return -2;		/*syntax error */
    }

    if (0 == strcasecomp(word1, "suffix")) {
	char *encoding = HTNextField(&pointer);

	if (pointer)
	    status = sscanf(pointer, "%f", &quality);
	else
	    status = 0;
	HTSetSuffix(word2, word3,
		    encoding ? encoding : "binary",
		    status >= 1 ? quality : (float) 1.0);

    } else if (0 == strcasecomp(word1, "presentation")) {
	if (pointer)
	    status = sscanf(pointer, "%f%f%f%d",
			    &quality, &secs, &secs_per_byte, &maxbytes);
	else
	    status = 0;
	HTSetPresentation(word2, word3, NULL,
			  status >= 1 ? quality : 1.0,
			  status >= 2 ? secs : 0.0,
			  status >= 3 ? secs_per_byte : 0.0,
			  status >= 4 ? maxbytes : 0,
			  mediaCFG);

    } else if (0 == strncasecomp(word1, "htbin", 5) ||
	       0 == strncasecomp(word1, "bindir", 6)) {
	StrAllocCopy(HTBinDir, word2);	/* Physical /htbin location */

    } else if (0 == strncasecomp(word1, "search", 6)) {
	StrAllocCopy(HTSearchScript, word2);	/* Search script name */

    } else {
	op = 0 == strcasecomp(word1, "map") ? HT_Map
	    : 0 == strcasecomp(word1, "pass") ? HT_Pass
	    : 0 == strcasecomp(word1, "fail") ? HT_Fail
	    : 0 == strcasecomp(word1, "redirect") ? HT_Redirect
	    : 0 == strncasecomp(word1, "redirectperm", 12) ? HT_RedirectPerm
	    : 0 == strcasecomp(word1, "redirecttemp") ? HT_Redirect
	    : 0 == strcasecomp(word1, "permitredirection") ? HT_PermitRedir
	    : 0 == strcasecomp(word1, "useproxy") ? HT_UseProxy
	    : 0 == strcasecomp(word1, "alert") ? HT_Alert
	    : 0 == strcasecomp(word1, "alwaysalert") ? HT_AlwaysAlert
	    : 0 == strcasecomp(word1, "progress") ? HT_Progress
	    : 0 == strcasecomp(word1, "usermsg") ? HT_UserMsg
	    : 0 == strcasecomp(word1, "infomsg") ? HT_InfoMsg
	    : 0 == strcasecomp(word1, "defprot") ? HT_DefProt
	    : 0 == strcasecomp(word1, "protect") ? HT_Protect
	    : HT_Invalid;
	if (op == HT_Invalid) {
	    fprintf(stderr, "HTRule: %s '%s'\n", RULE_INCORRECT, config);
	} else {
	    switch (op) {
	    case HT_Fail:	/* never a or other 2nd parameter */
	    case HT_PermitRedir:
		cond_op = word3;
		if (cond_op && *cond_op) {
		    word3 = NULL;
		    cond = HTNextField(&pointer);
		}
		break;

	    case HT_Pass:	/* possibly a URL2 */
		if (word3 && (!strcasecomp(word3, "if") ||
			      !strcasecomp(word3, "unless"))) {
		    cond_op = word3;
		    word3 = NULL;
		    cond = HTNextField(&pointer);
		    break;
		}
		/* else fall through */
	    case HT_Map:	/* always a URL2 (or other 2nd parameter) */
	    case HT_Redirect:
	    case HT_RedirectPerm:
	    case HT_UseProxy:
		cond_op = HTNextField(&pointer);
		/* check for extra status word in "Redirect" */
		if (op == HT_Redirect && 0 == strcasecomp(word1, "redirect") &&
		    cond_op &&
		    strcasecomp(cond_op, "if") &&
		    strcasecomp(cond_op, "unless")) {
		    if (0 == strcmp(word2, "301") ||
			0 == strcasecomp(word2, "permanent")) {
			op = HT_RedirectPerm;
		    } else if (!(0 == strcmp(word2, "302") ||
				 0 == strcmp(word2, "303") ||
				 0 == strcasecomp(word2, "temp") ||
				 0 == strcasecomp(word2, "seeother"))) {
			CTRACE((tfp, "Rule: Ignoring `%s' in Redirect\n", word2));
		    }
		    word2 = word3;
		    word3 = cond_op;	/* cond_op isn't condition op after all */
		    cond_op = HTNextField(&pointer);
		}
		if (cond_op && *cond_op)
		    cond = HTNextField(&pointer);
		break;

	    case HT_Progress:
	    case HT_InfoMsg:
	    case HT_UserMsg:
	    case HT_Alert:
	    case HT_AlwaysAlert:
		cond_op = HTNextField(&pointer);
		if (cond_op && *cond_op)
		    cond = HTNextField(&pointer);
		if (word3) {	/* Fix string with too may %s - kw */
		    const char *cp = word3;
		    char *cp1, *cp2;

		    while ((cp1 = strchr(cp, '%'))) {
			if (cp1[1] == '\0') {
			    *cp1 = '\0';
			    break;
			} else if (cp1[1] == '%') {
			    cp = cp1 + 2;
			    continue;
			} else
			    while ((cp2 = strchr(cp1 + 2, '%'))) {
				if (cp2[1] == '\0') {
				    *cp2 = '\0';
				    break;
				} else if (cp2[1] == '%') {
				    cp1 = cp2;
				} else {
				    *cp2 = '?';		/* replace bad % */
				    cp1 = cp2;
				}
			    }
			break;
		    }
		}
		break;

	    default:
		break;
	    }
	    if (cond_op && cond && *cond && !strcasecomp(cond_op, "unless")) {
		cond_op = "unless";
	    } else if (cond_op && cond && *cond &&
		       !strcasecomp(cond_op, "if")) {
		cond_op = "if";
	    } else if (cond_op || cond) {
		fprintf(stderr, "HTRule: %s '%s'\n", RULE_INCORRECT, config);
		FREE(line);	/* syntax error, condition is a mess - kw */
		return -2;	/* NB unrecognized cond passes here - kw */
	    }
	    if (cond && !strncasecomp(cond, "redirected", strlen(cond))) {
		cond = "redirected";	/* recognized, canonical case - kw */
	    } else if (cond && strlen(cond) >= 8 &&
		       !strncasecomp(cond, "userspecified", strlen(cond))) {
		cond = "userspec";	/* also allow abbreviation - kw */
	    }
	    HTAddRule(op, word2, word3, cond_op, cond);
	}
    }
    FREE(line);
    return 0;
}
Exemple #25
0
/*
**	This function maintains backwards compatibility with the old 
**	environment variables and searches for the most common values:
**	http, ftp, news, wais, and gopher
*/
PUBLIC void HTProxy_getEnvVar (void)
{
    char buf[80];
    static const char *accesslist[] = {
	"http",
	"ftp",
	"news",
	"wais",
	"gopher",
	NULL
    };
    const char **access = accesslist;
    HTTRACE(PROT_TRACE, "Proxy....... Looking for environment variables\n");
    while (*access) {
	BOOL found = NO;
	char *gateway=NULL;
	char *proxy=NULL;

	/* Search for proxy gateways */
	if (found == NO) {
	    strcpy(buf, *access);
	    strcat(buf, "_proxy");
	    if ((proxy = (char *) getenv(buf)) && *proxy) {
		HTProxy_add(*access, proxy);
		found = YES;
	    }

	    /* Try the same with upper case */
	    if (found == NO) {
		char * up = buf;
		while ((*up = TOUPPER(*up))) up++;
		if ((proxy = (char *) getenv(buf)) && *proxy) {
		    HTProxy_add(*access, proxy);
		    found = YES;
		}
	    }
	}

	/* As a last resort, search for gateway servers */
	if (found == NO) {
	    strcpy(buf, "WWW_");
	    strcat(buf, *access);
	    strcat(buf, "_GATEWAY");
	    if ((gateway = (char *) getenv(buf)) && *gateway) {
		HTGateway_add(*access, gateway);
		found = YES;
	    }
	}
	++access;
    }

    /* Search for `noproxy' directive */
    {
	char *noproxy = getenv("no_proxy");
	if (noproxy && *noproxy) {
	    char *str = NULL;
	    char *strptr;
	    char *name;
	    StrAllocCopy(str, noproxy);		 /* Get copy we can mutilate */
	    strptr = str;
	    while ((name = HTNextField(&strptr)) != NULL) {
		char *portstr = strchr(name, ':');
		unsigned port=0;
		if (portstr) {
		    *portstr++ = '\0';
		    if (*portstr) port = (unsigned) atoi(portstr);
		}

		/* Register it for all access methods */
		HTNoProxy_add(name, NULL, port);
	    }
	    HT_FREE(str);
	}
    }
}