int register_database_type(pblock *pb, Session *sn, Request *rq)
{
    char *dbtype_str = pblock_findval(ACL_ATTR_DBTYPE, pb);
    char *parseFuncStr = pblock_findval(ACL_ATTR_PARSEFN, pb);
    ACLDbType_t dbtype = ACL_DBTYPE_INVALID;
    DbParseFn_t parseFunc;
    char err[BIG_LINE];
    NSErr_t *errp = 0;

    if (!dbtype_str || !*dbtype_str) {
	pblock_nvinsert("error", "dbtype is missing", pb);
	return REQ_ABORTED;
    }

    if (!parseFuncStr) {
	pblock_nvinsert("error", "parse function is missing", pb);
	return REQ_ABORTED;
    }

    parseFunc = (DbParseFn_t)func_find(parseFuncStr);

    if (!parseFunc) {
	sprintf(err, "Could map \"%s\" to a function", parseFunc);
	pblock_nvinsert("error", err, pb);
	return REQ_ABORTED;
    }

    ACL_REG(ACL_DbTypeRegister(errp, dbtype_str, parseFunc, &dbtype),
	    "Failed to register database type \"%s\"", dbtype_str);

    return REQ_PROCEED;
}
int
otype_changetype (pblock *pb, Session *sn, Request *rq)
{
    char * type = pblock_findval ("type", pb);

    rq->directive_is_cacheable = 1;

    if (type != NULL)
    {
        const char *if_type = pblock_findval ("if-type", pb);	

        if (if_type != NULL)
        {
            const char *ct_type = pblock_findval ("content-type", rq -> srvhdrs);

            if (ct_type != NULL 
                && !strcmp (if_type, ct_type))
            {
                pblock_nvreplace ("content-type", type, rq -> srvhdrs);
                return REQ_PROCEED;
            }
        }
        else
        {
            pblock_nvreplace ("content-type", type, rq -> srvhdrs);
            return REQ_PROCEED;
        }
    }

    return REQ_NOACTION;
}
int register_database_name(pblock *pb, Session *sn, Request *rq)
{
    char *dbtype_str = pblock_findval(ACL_ATTR_DBTYPE, pb);
    char *dbname = pblock_findval(ACL_ATTR_DBNAME, pb);
    char *url = pblock_findval(ACL_ATTR_DATABASE_URL, pb);
    ACLDbType_t dbtype = ACL_DBTYPE_INVALID;
    NSErr_t *errp = 0;
    PList_t plist = PListCreate(NULL, ACL_ATTR_INDEX_MAX, NULL, NULL);

    if (!dbtype_str || !*dbtype_str) {
	pblock_nvinsert("error", "dbtype is missing", pb);
	return REQ_ABORTED;
    }

    if (!dbname || !*dbname) {
	pblock_nvinsert("error", "database name is missing", pb);
	return REQ_ABORTED;
    }

    if (!url || !*url) {
	pblock_nvinsert("error", "database url is missing", pb);
	return REQ_ABORTED;
    }

    ACL_REG(ACL_DbTypeFind(errp, dbtype_str, &dbtype),
	    "Database type \"%s\" is not registered", dbtype_str);

    ACL_REG(ACL_DatabaseRegister(errp, dbtype, dbname, url, plist),
	    "Failed to register database \"%s\"", dbname);

    return REQ_PROCEED;
}
int otype_shtmlhacks(pblock *pb, Session *sn, Request *rq)
{
    char *path = pblock_findval("path", rq->vars);
    char *do_exec = pblock_findval("exec-hack", pb);
    int l;

    /* This is cachable- we always do the same thing based SOLELY
     * on the URI...
     */
    rq->directive_is_cacheable = 1;

    l = strlen(path);
    if((!strcasecmp(&path[l-4],".htm")) || (!strcasecmp(&path[l-5],".html"))) {
#ifdef XP_UNIX
        if(do_exec) {
            struct stat *fi = request_stat_path(NULL, rq);

            if(fi && (!(fi->st_mode & S_IXUSR)))
                return REQ_NOACTION;
        }
#endif /* XP_UNIX */
        param_free(pblock_remove("content-type", rq->srvhdrs));
        pblock_nvinsert("content-type", "magnus-internal/parsed-html",
                        rq->srvhdrs);
        return REQ_PROCEED;
    }
    return REQ_NOACTION;
}
int otype_imgswitch(pblock *pb, Session *sn, Request *rq)
{
    char *ct, *ua, *pa, *npath, *t;
    struct stat fi;
    pb_param *pp;

    /* This routine might be cacheable.  Lets check the objtype so
     * far to see if we are talking about an image file.  If this path
     * is not an image, we can go ahead and cache.
     */
    rq->directive_is_cacheable = 1;

    if(!(ct = pblock_findval("content-type", rq->srvhdrs)))
        return REQ_NOACTION;
    if(strncasecmp(ct, "image/", 6))
        return REQ_NOACTION;

    /* This routine is still running, so it must be an image we are
     * dealing with.  This is not cacheable since we need the user-agent
     * info to determine which file we return.
     */
    rq->directive_is_cacheable=0;

    /* In the absence of a capabilities header, use user-agent */
    if(request_header("user-agent", &ua, sn, rq) == REQ_ABORTED)
        return REQ_ABORTED;
    /* We want to be nice to proxies */
    if(request_header("proxy-agent", &pa, sn, rq) == REQ_ABORTED)
        return REQ_ABORTED;

    if((!ua) || pa || strstr(ua, "roxy"))
        return REQ_NOACTION;

    /* Look for jpeg if we're talking to mozilla and image is .gif */
    if((!strncasecmp(ua, "mozilla", 7)) && (!strcasecmp(ct, "image/gif"))) {
        npath = STRDUP(pblock_findval("path", rq->vars));
        if(!(t = strstr(npath, ".gif")))
            return REQ_NOACTION;
        t[1] = 'j'; t[2] = 'p'; t[3] = 'g';
        if(stat(npath, &fi) == -1) {
            FREE(npath);
            return REQ_NOACTION;
        }
        pp = pblock_find("path", rq->vars);
        FREE(pp->value);
        pp->value = npath;

        /* don't check return; it should work. */
        request_stat_path(npath, rq);

        pp = pblock_find("content-type", rq->srvhdrs);
        FREE(pp->value);
        pp->value = STRDUP("image/jpeg");

        return REQ_PROCEED;
    }
    return REQ_NOACTION;
}
/* Sigh. Another stupid pet trick that will get dropped on the floor */
int otype_htmlswitch(pblock *pb, Session *sn, Request *rq)
{
    char *ct, *ua, *pa, *npath, *t;
    struct stat fi;
    pb_param *pp;

    /* This routine might be cacheable.  Lets check the objtype so
     * far to see if we are talking about a text file.  If this path
     * is not a text, we can go ahead and cache.
     */
    rq->directive_is_cacheable = 1;

    if(!(ct = pblock_findval("content-type", rq->srvhdrs)))
        return REQ_NOACTION;
    if(strncasecmp(ct, "text/", 5))
        return REQ_NOACTION;

    /* This is still running, so it must be a text file we are
     * dealing with.  This is not cacheable since we need the user-agent
     * info to determine which file we return.
     */
    rq->directive_is_cacheable = 0;

    /* In the absence of a capabilities header, use user-agent */
    if(request_header("user-agent", &ua, sn, rq) == REQ_ABORTED)
        return REQ_ABORTED;
    /* We want to be nice to proxies */
    if(request_header("proxy-agent", &pa, sn, rq) == REQ_ABORTED)
        return REQ_ABORTED;

    if((!ua) || pa || strstr(ua, "roxy"))
        return REQ_NOACTION;

    /* Look for html3 if we're talking to mozilla and find HTML */
    if(util_is_mozilla(ua, "1", "1") && (!strcasecmp(ct, "text/html"))) {
        t = pblock_findval("path", rq->vars);
        npath = (char *) MALLOC(strlen(t) + 1 + 1);
        util_sprintf(npath, "%s3", t);
        if(stat(npath, &fi) == -1) {
            FREE(npath);
            return REQ_NOACTION;
        }
        pp = pblock_find("path", rq->vars);
        FREE(pp->value);
        pp->value = npath;

        /* don't check return; it should work. */
        request_stat_path(npath, rq);
        return REQ_PROCEED;
    }
    return REQ_NOACTION;
}
Beispiel #7
0
static int sendResponse(Session *sn, Request *rq, HTTPResponse *resp)
{
   pb_param *pb_entry;

   /*
    *	collect up the headers
    */
   pb_entry = pblock_remove(CONTENT_TYPE,rq->srvhdrs);			/* remove default */
   param_free(pb_entry);			/* aB. Need to free parameters we remove from pblocks !!! */
   st_perform(resp->headers,gethdr,rq);

   /*
    *	ensure a content length
    */
   if (pblock_findval(CONTENT_LENGTH, rq->srvhdrs) == NULL) {
      char length[64];
      util_itoa(resp->content_length,length);
      pblock_nvinsert(CONTENT_LENGTH,length, rq->srvhdrs);
   }

   protocol_status(sn, rq, resp->status, resp->statusMsg);

   if (protocol_start_response(sn, rq) == REQ_NOACTION) {
      WOLog(WO_ERR,"protocol_start_response() returned REQ_NOACTION (!?)");
      return REQ_PROCEED;
   }

   if (resp->content_length)
      if (net_write(sn->csd, resp->content, resp->content_length) == IO_ERROR) {
         WOLog(WO_ERR,"Failed to send content to client");
         return REQ_EXIT;
      }

         return REQ_PROCEED;
}
Beispiel #8
0
inline
static void cpyhdr(const char *key,pblock *pb,HTTPRequest *req,const char *wokey)
{
    const char *value = pblock_findval((char *)key, pb);
    if (value != NULL)
       req_addHeader(req, (wokey) ? wokey : key, value, 0);
}
/** **************************************************************************
 * Optional init. Can be used to set non-default value to purge_timeout.
 * Registered in netsite/lib/frame/httpd-fn.cpp
 * See: http://docs.sun.com/source/817-1835-10/npgmysaf.html#wp15421
 *
 * magnus.conf:
 *    Init fn="init-request-limits" timeout="300"
 *
 */
int init_request_limits(pblock *pb, Session *sn, Request *rq)
{
    char * param = pblock_findval(PURGE_TIMEOUT, pb);

    if (reqlimit_crit == NULL || hashtable == NULL) {
                                // "should never happen"
        pblock_nvinsert("error", "internal error", pb);
        return REQ_ABORTED;
    }

    if (!param) {
        pblock_nvinsert("error", XP_GetAdminStr(DBT_reqlimitNoTimeout), pb);
        return REQ_ABORTED;
    }

    purge_timeout = atoi(param);

    if (purge_timeout) {
        next_timeout = time(NULL) + purge_timeout;
        log_error(LOG_VERBOSE, "init-request-limits", sn, rq,
                  "purge timeout set to %ds", purge_timeout);

    } else {
         log_error(LOG_VERBOSE, "init-request-limits", sn, rq,
                   "purge timeout disabled.");
    }

    return REQ_PROCEED;
}
Beispiel #10
0
int nsapi_send(pblock *pb, Session *sn, Request *rq)
{
    char *query_string;
    char buffer[sizeof(HEADERS) + 204800 + 1];
    int filesize;
    unsigned int maxindex;
    unsigned int index;

    /* Get the query string, if any; check to see if an alternate
     * file size was specified.
     */
    if ( !(query_string = pblock_findval("query", rq->reqpb)) )
        filesize = FILE_SIZE;
    else {
        filesize = atoi(&(query_string[5]));
    }

    memcpy(&buffer, HEADERS, sizeof(HEADERS)-1);

    /* Generate the output */
    maxindex = sizeof(HEADERS) + filesize;
    for (index=sizeof(HEADERS); index < (maxindex); index++)
        /* generate random characters from A-Z */
#ifdef IRIX
        buffer[index] = rand_r() % 26 + 63;
#else
        buffer[index] = rand() %26 + 63;
#endif

    /* Send the output */
    if (net_write(sn->csd, buffer, sizeof(HEADERS)-1+filesize, 0) == IO_ERROR)
        return REQ_EXIT;

    return REQ_PROCEED;
}
static char* find_document_root_directive(httpd_objset *objset)
{
    // XXX Attempt to guess the document root by looking for the NameTrans
    // fn=document-root directive in obj.conf.  Note that we use the last
    // document-root directive's root parameter; earlier directives may have
    // been in less-specific objects or enclosed in <Client> tags.

    int countObjects = objset_get_number_objects(objset);
    int iObject;
    for (iObject = countObjects - 1; iObject >= 0; iObject--) {
        const httpd_object* object = objset_get_object(objset, iObject);
        const dtable* dir_table = object_get_directive_table(object, NSAPINameTrans);
        int countDirectives = directive_table_get_num_directives(dir_table);
        int iDirective;
        for (iDirective = countDirectives - 1; iDirective >= 0; iDirective--) {
            const directive* dir = directive_table_get_directive(dir_table, iDirective);
            const FuncStruct* fs = directive_get_funcstruct(dir);
            if (fs && fs->name && !strcmp(fs->name, "document-root")) { 
                char* docroot = pblock_findval("root", dir->param.pb);
                if (docroot)
                    return docroot;
            }
        }
    }

    return NULL;
}
static htaccess_context_s *
_htaccess_newctxt(pblock *pb, Session *sn, Request *rq)
{
    htaccess_context_s *ctxt = 
        (htaccess_context_s *) MALLOC(sizeof(htaccess_context_s));
    char *rhst = session_dns(sn);

    ctxt->pb = pb;
    ctxt->sn = sn;
    ctxt->rq = rq;

    ctxt->auth_type = NULL;
    ctxt->auth_name = NULL;
    ctxt->auth_pwfile = NULL;
    ctxt->auth_grpfile = NULL;
    ctxt->auth_authdb = 0;
    ctxt->auth_grplist = 0;
    ctxt->auth_grplfile = 0;
    ctxt->auth_grpllen = 0;
    ctxt->user_check_fn = NULL;
    ctxt->group_check_fn = NULL;

#ifdef AUTHNSDBFILE
    ctxt->auth_uoptr = 0;
    ctxt->auth_nsdb = 0;
#endif /* AUTHNSDBFILE */
    ctxt->auth_line = pblock_findval("authorization", rq->headers);

    ctxt->num_sec = 0;

    ctxt->remote_host = rhst;
    ctxt->remote_ip = pblock_findval("ip", sn->client);
    ctxt->remote_name = rhst ? rhst : ctxt->remote_ip;

    ctxt->access_name = pblock_findval("filename", pb);
    if(!ctxt->access_name)
        ctxt->access_name = DEFAULT_ACCESS_FNAME;

    ctxt->user[0] = '\0';
    ctxt->groupname[0] = '\0';

    ctxt->sec = htaccess_newsec();

    return ctxt;
}
int otype_typebyexp(pblock *pb, Session *sn, Request *rq) {
    char *exp = pblock_findval("exp", pb);
    char *path = pblock_findval("path", rq->vars);

    rq->directive_is_cacheable = 1;

    if(!exp) {
        log_error(LOG_MISCONFIG, "type-by-exp", sn, rq, 
                  XP_GetAdminStr(DBT_ntwincgiError14));
        return REQ_ABORTED;
    }

    if(!(WILDPAT_CMP(path, exp)))
        return otype_forcetype(pb, sn, rq);
    else {
        return REQ_NOACTION;
    }
}
int 
htaccess_evaluate(pblock *pb, Session *sn, Request *rq)
{
    char *p = pblock_findval("path", rq->vars);
    struct stat *finfo = request_stat_path(p, rq);
    int isdir = finfo && S_ISDIR(finfo->st_mode);

    /* some java servlets that are set in rules.properties don't set this */
    if(!pblock_findval("ntrans-base", rq->vars))
        return REQ_NOACTION;

    char *methstr = pblock_findval("method", rq->reqpb);
    int methnum;
    HttpMethodRegistry& registry = HttpMethodRegistry::GetRegistry();

    /* treat HEAD as a GET */
    if (!strcasecmp(methstr, "HEAD"))
        methnum = registry.HttpMethodRegistry::GetMethodIndex("GET");
    else
        methnum = registry.HttpMethodRegistry::GetMethodIndex(methstr);

    /* if it isn't a method we support, don't allow access */
    if (methnum == -1)
    {
        protocol_status(sn, rq, PROTOCOL_FORBIDDEN, NULL);
        return REQ_ABORTED;
    }

    switch(htaccess_evaluate_access(p, isdir, methnum, pb, sn, rq)) {
      case ACCESS_OK:
        return REQ_PROCEED;

      case ACCESS_FORBIDDEN:
      default:
        protocol_status(sn, rq, PROTOCOL_FORBIDDEN, NULL);
        log_error(LOG_SECURITY, "htaccess-find", sn, rq, 
                  "access of %s denied by server configuration.", p);
        /* fallthrough */

      case ACCESS_AUTHFAIL:
        /* the data structures will be set up by http_auth.c */
        return REQ_ABORTED;
    }
}
int set_default_database (pblock *pb, Session *sn, Request *rq)
{
    char *dbname = pblock_findval(ACL_ATTR_DBNAME, pb);
    NSErr_t *errp = 0;

    ACL_REG(ACL_DatabaseSetDefault(errp, dbname),
	    "Failed to set default method \"%s\"", dbname);

    return REQ_PROCEED;
}
int register_method (pblock *pb, Session *sn, Request *rq)
{
    char *method = pblock_findval(ACL_ATTR_METHOD, pb);
    ACLMethod_t t;
    NSErr_t *errp = 0;

    ACL_REG(ACL_MethodRegister (errp, method, &t),
	    "Failed to register method \"%s\"", method);

    return REQ_PROCEED;
}
int set_default_method (pblock *pb, Session *sn, Request *rq)
{
    char *method = pblock_findval(ACL_ATTR_METHOD, pb);
    NSErr_t *errp = 0;
    ACLMethod_t	t;

    ACL_REG(ACL_MethodFind(errp, method, &t),
	    "Method \"%s\" is not registered", method);

    ACL_MethodSetDefault(errp, t);

    return REQ_PROCEED;
}
Beispiel #18
0
/**
 * Migrate response status and headers from the subrequest to the
 * HttpServletResponse.
 */
static inline void j2eefilter_migrate_response(Request* sub_rq, J2EEFilterContext* context)
{
    if (context->forward) {
        if (sub_rq != context->parent_rq && !context->parent_rq->senthdrs) {
            // Pass status_num to HttpServletResponse.setStatus
            // XXX In NSAPI, SAFs always set the status code, even on success.
            // In Java land, however, Servlets only explicitly set the status
            // code for non-200 responses. To preserve the original error code
            // on <error-page> RequestDispatcher.forward calls, never call
            // HttpServletResponse.setStatus(200).
            if (sub_rq->status_num != 0 && sub_rq->status_num != 200) {
                context->env->CallVoidMethod(context->response, _response_setStatus, sub_rq->status_num);
                j2eefilter_store_throwable(context);
            }

            // Pass the contents of srvhdrs to the HttpServletResponse
            pblock *seen = pblock_create(PARAMETER_HASH_SIZE);
            for (int i = 0; i < sub_rq->srvhdrs->hsize; i++) {
                for (pb_entry *p = sub_rq->srvhdrs->ht[i]; p; p = p->next) {
                    // The NSAPI status code is stored in rq->srvhdrs but
                    // shouldn't be passed to the HttpServletResponse
                    if (!strcmp(p->param->name, "status"))
                        continue;

                    jstring jname = context->env->NewStringUTF(p->param->name);
                    j2eefilter_store_throwable(context);
                    jstring jvalue = context->env->NewStringUTF(p->param->value);
                    j2eefilter_store_throwable(context);

                    // Call setHeader for the first occurrence of a given name
                    // and addHeader for each subsequent occurrence
                    if (pblock_findval(p->param->name, seen)) {
                        context->env->CallVoidMethod(context->response, _response_addHeader, jname, jvalue);
                    } else {
                        pblock_nvinsert(p->param->name, "1", seen);
                        context->env->CallVoidMethod(context->response, _response_setHeader, jname, jvalue);
                    }
                    j2eefilter_store_throwable(context);

                    if (jname != NULL)
                        context->env->DeleteLocalRef(jname);
                    if (jvalue != NULL)
                        context->env->DeleteLocalRef(jvalue);
                }
            }
            pblock_free(seen);
        }

        context->forward = PR_FALSE;
    }
}
Beispiel #19
0
/*
 *	NameTrans:
 *
 *	format of obj.conf is:
 *		NameTrans from="some-dir" fn=WebObjectsNameTrans dir="app-dir" name="obj-name"
 *
 *	If 'some-dir' is found in the URI, then set the request's WebObjects
 *	application root to 'app-dir' and let the WebObjects object process
 *	the request.
 *
 */
NSAPI_PUBLIC
int WebObjectsNameTrans(pblock *pb, Session *sn, Request *rq)
{
   WOURLComponents wc;
   const char *from;
   const char *objName;
   const char *uripath;
   const char *approot;

   if (!adaptorEnabled)
      return REQ_NOACTION;

   dump_pb(pb,"nametrans.pb");					/* spew debug info */
           dump_pb(rq->vars,"nametrans.rq->vars");		/* spew debug info */

                   from = pblock_findval(PATHTRANS,pb);
                   uripath = pblock_findval("ppath",rq->vars);
                   objName = pblock_findval(OBJECTNAME,pb);
                   if ((from == NULL) || (uripath == NULL) || (objName == NULL))
                   return REQ_NOACTION;

                   if (strncmp(from,uripath,strlen(from)) == 0) {
                      /*
                       *	make sure this is a valid WebObjects(tm) URL
                       */
                      wc = WOURLComponents_Initializer;
                      if (WOParseApplicationName(&wc, uripath) != WOURLOK) /* bail now if something wierd */
                         return REQ_NOACTION;
                      pblock_nvinsert(OBJECTNAME,(char *)objName,rq->vars);

                      approot = pblock_findval(APPROOT,pb);
                      if (approot)
                         pblock_nvinsert(APPROOT,(char *)approot,rq->vars);
                      return REQ_PROCEED;
                   } else
                   return REQ_NOACTION;
}
Beispiel #20
0
char * get_post_assertion_data(Session *sn, Request *rq, char *url)
{
    int i = 0;
    char *body = NULL;
    int cl = 0;
    char *cl_str = NULL;

    /**
    * content length and body
    *
    * note: memory allocated in here should be released by
    * other function such as: "policy_unregister_post"
    */

    request_header("content-length", &cl_str, sn, rq);
    if(cl_str == NULL)
	    cl_str = pblock_findval("content-length", rq->headers);
    if(cl_str == NULL)
	    return body;
    if(PR_sscanf(cl_str, "%ld", &cl) == 1) {
        body =  (char *)malloc(cl + 1);
	if(body != NULL){
	    for (i = 0; i < cl; i++) {
	        int ch = netbuf_getc(sn->inbuf);
		if (ch==IO_ERROR || ch == IO_EOF) {
		    break;
	 	}	
		body[i] = ch;
	    }  

	    body[i] = '\0';
	}
    } else {
        am_web_log_error("Error reading POST content body");
    }

    am_web_log_max_debug("Read POST content body : %s", body);


    /**
    * need to reset content length before redirect, 
    * otherwise, web server will wait for serveral minutes
    * for non existant data
    */
    param_free(pblock_remove("content-length", rq->headers));
    pblock_nvinsert("content-length", "0", rq->headers);
    return body;

}
int register_module (pblock *pb, Session *sn, Request *rq)
{
    char *module = pblock_findval(ACL_ATTR_MODULE, pb);
    char *funcStr = pblock_findval(ACL_ATTR_MODULEFUNC, pb);
    AclModuleInitFunc func;
    NSErr_t *errp = 0;

    if (!funcStr || !*funcStr) {
	ereport(LOG_SECURITY, XP_GetAdminStr(DBT_initereport1));
	return REQ_ABORTED;
    }

    func = (AclModuleInitFunc)func_find(funcStr);

    if (!func) {
	ereport(LOG_SECURITY, XP_GetAdminStr(DBT_initereport2));
	return REQ_ABORTED;
    }

    ACL_REG(ACL_ModuleRegister (errp, module, func),
	          XP_GetAdminStr(DBT_initereport3), module);

    return REQ_PROCEED;
}
int service_dumpstats(pblock *pb, Session *sn, Request *rq)
{
    char *refresh, *refresh_val = NULL;

    /* See if client asked for automatic refresh in query string */
    if ((refresh = pblock_findval("query", rq->reqpb)) != NULL ) {
        if (!strncmp("refresh", refresh, 7)) {
             refresh_val = strchr(refresh, '=');
             if (refresh_val)
                 refresh_val++;
        }
    }

    param_free(pblock_remove("content-type", rq->srvhdrs));
    pblock_nvinsert("content-type", "text/plain", rq->srvhdrs);
    if (refresh_val)
        pblock_nvinsert("refresh", refresh_val, rq->srvhdrs);
    httpfilter_buffer_output(sn, rq, PR_TRUE);
    protocol_status(sn, rq, PROTOCOL_OK, NULL);
    protocol_start_response(sn,rq);

    PR_fprintf(sn->csd, PRODUCT_DAEMON_BIN" pid: %d\n", getpid());

    StatsHeaderNode *hdr = StatsManager::getHeader();

    if (!hdr) {
        PR_fprintf(sn->csd, "\nStatistics disabled\n");
        return REQ_PROCEED;
    }
    int rv = REQ_PROCEED;
#ifdef XP_WIN32
    rv = write_stats_dump(sn->csd, hdr);
#else
    if (hdr && (hdr->hdrStats.maxProcs == 1)) {
        rv = write_stats_dump(sn->csd, hdr);
    } else {
        StatsManager::serviceDumpStats(sn->csd, NULL);
    }
#endif
    return rv;
}
Beispiel #23
0
am_status_t get_header_value(pblock *pb, const char *header_name,
                             boolean_t isRequired, char **header_value,
                             boolean_t needCopy, char **header_value_copy)
{
    const char *thisfunc = "get_header_value()";
    am_status_t status = AM_SUCCESS;
    // From NSAPI guide:
    // The pointer returned is a pointer into the pblock. 
    // Do not FREE it. If you want to modify it, do a STRDUP 
    // and modify the copy.
    *header_value = pblock_findval(header_name, pb);
    if ((*header_value != NULL) && (strlen(*header_value) > 0 )) {
        am_web_log_debug("%s: %s = %s", thisfunc, header_name, *header_value);
    } else {
        *header_value = NULL;
        if (isRequired == B_TRUE) {
            am_web_log_error("%s: Could not get a value for header %s.", 
                             thisfunc, header_name);
            status = AM_FAILURE;
        } else {
            am_web_log_debug("%s: %s =", thisfunc,
                             header_name);
        }
    }
    // In case the header needs to be modified later in the code,
    // copy it in a variable that can be modified. This one must
    // be freed.
    if ((status == AM_SUCCESS) && (needCopy == B_TRUE) &&
        (*header_value != NULL))
    {
        *header_value_copy = strdup(*header_value);
        if (*header_value_copy == NULL) {
            am_web_log_debug("%s: Not enough memory to make "
                             "a copy of the %s header.",
                             thisfunc, header_name);
            status = AM_NO_MEMORY;
        }
    }
    return status;
}
NSAPI_PUBLIC char *conf_findGlobal(char *name)
{
    if (!conf_api_initialized) {
        log_ereport(LOG_VERBOSE, XP_GetAdminStr(DBT_confApiCallBeforeInit));
        return NULL;
    }

    char *rv = NULL;
    char *d = _lowercase(name);
    
    if (d) {
        // Mark directive as accessed
        if (globalsUnaccessed)
            param_free(pblock_remove(d, globalsUnaccessed));

        // Lookup directive
        rv = pblock_findval(d, conf_get_true_globals()->genericGlobals);

        FREE(d);
    }

    return rv;
}
Beispiel #25
0
static am_status_t set_header_attr_as_cookie(const char *values, void **args)
{
    Request *rq = NULL;
    am_status_t sts = AM_SUCCESS;
    char *cookie_header = NULL;
    char *new_cookie_header = NULL;

    if (args == NULL || args[0] == NULL || 
	values == NULL || values[0] == '\0') {
	sts = AM_INVALID_ARGUMENT;
    }
    else {
        rq = (Request *)args[0];
	cookie_header = pblock_findval("cookie", rq->headers);

	sts = am_web_set_cookie(cookie_header, values, &new_cookie_header);
	if (sts == AM_SUCCESS && new_cookie_header != NULL && 
		new_cookie_header != cookie_header) {
	    sts = set_header("cookie", new_cookie_header, args);
	    free(new_cookie_header);
	}
    }
    return sts;
}
Beispiel #26
0
/*
 * Function Name: validate_session_policy
 * This is the NSAPI directive funtion which gets called for each request
 * It does session validation and policy check for each request.
 * Input: As defined by a SAF
 * Output: As defined by a SAF
 */
NSAPI_PUBLIC int
validate_session_policy(pblock *param, Session *sn, Request *rq) {
    const char *thisfunc = "validate_session_policy()";
    char *dpro_cookie = NULL;
    am_status_t status = AM_SUCCESS;
    int  requestResult = REQ_ABORTED;
    int	 notifResult = REQ_ABORTED;
    const char *ruser = NULL;
    am_map_t env_parameter_map = NULL;
    am_policy_result_t result = AM_POLICY_RESULT_INITIALIZER;
    void *args[] = { (void *)rq };
    char *request_url = NULL;
    char *orig_req = NULL ;
    char *response = NULL;
    char *clf_req = NULL;
    char *server_protocol = NULL;
    void *agent_config = NULL;
    char *logout_url = NULL;
    char *uri_hdr = NULL;
    char *pathInfo_hdr = NULL;
    char *method_hdr = NULL;
    char *method = NULL;
    char *virtHost_hdr = NULL;
    char *query_hdr = NULL;
    char *query = NULL;
    char *protocol = "HTTP";
    const char *clientIP_hdr_name = NULL;
    char *clientIP_hdr = NULL;
    char *clientIP = NULL;
    const char *clientHostname_hdr_name = NULL;
    char *clientHostname_hdr = NULL;
    char *clientHostname = NULL;
    am_status_t cdStatus = AM_FAILURE;

    // check if agent is initialized.
    // if not initialized, then call agent init function
    // This needs to be synchronized as only one time agent
    // initialization needs to be done.

    if(agentInitialized != B_TRUE){
        //Start critical section
        crit_enter(initLock);
        if(agentInitialized != B_TRUE){
            am_web_log_debug("%s: Will call init.", thisfunc);
            init_at_request(); 
            if(agentInitialized != B_TRUE){
                am_web_log_error("%s: Agent is still not intialized",
                                 thisfunc);
                //deny the access
                requestResult =  do_deny(sn, rq, status);
                status = AM_FAILURE;
            } else {
                am_web_log_debug("%s: Agent intialized");
            }
        }
        //end critical section
        crit_exit(initLock);
    }
    if (status == AM_SUCCESS) {
        // Get the agent configuration
        agent_config = am_web_get_agent_configuration();
        // Dump the entire set of request headers
        if (am_web_is_max_debug_on()) {
            char *header_str = pblock_pblock2str(rq->reqpb, NULL);
            am_web_log_max_debug("%s: Headers: %s", thisfunc, header_str);
            system_free(header_str);
        }
    }
    // Get header values
    if (status == AM_SUCCESS) {
        status = get_header_value(rq->reqpb, REQUEST_URI,
                               B_TRUE, &uri_hdr, B_FALSE, NULL);
    }
    if (status == AM_SUCCESS) {
        status = get_header_value(rq->vars, PATH_INFO,
                               B_FALSE, &pathInfo_hdr, B_FALSE, NULL);
    }
    if (status == AM_SUCCESS) {
        status = get_header_value(rq->reqpb, REQUEST_METHOD,
                               B_TRUE, &method_hdr, B_TRUE, &method);
    }
    if (status == AM_SUCCESS) {
        status = get_header_value(rq->headers, "ampxy_host",
                               B_TRUE, &virtHost_hdr, B_FALSE, NULL);
    }
    if (status == AM_SUCCESS) {
        status = get_header_value(rq->reqpb, REQUEST_QUERY,
                               B_FALSE, &query_hdr, B_TRUE, &query);
    }
    if (security_active) {
        protocol = "HTTPS";
    }
    // Get the request URL
    if (status == AM_SUCCESS) {
        if (am_web_is_proxy_override_host_port_set(agent_config) == AM_FALSE) {
            status = am_web_get_request_url(virtHost_hdr, protocol,
                                            NULL, 0, uri_hdr, query,
                                            &request_url, agent_config);
            if(status == AM_SUCCESS) {
                am_web_log_debug("%s: Request_url: %s", thisfunc, request_url);
            } else {
                am_web_log_error("%s: Could not get the request URL. "
                                 "Failed with error: %s.",
                                 thisfunc, am_status_to_string(status));
            }
        }
    }
    if (status == AM_SUCCESS) {
        if (am_web_is_proxy_override_host_port_set(agent_config) == AM_TRUE) {
            const char *agent_host = am_web_get_agent_server_host(agent_config);
            int agent_port = am_web_get_agent_server_port(agent_config);
            if (agent_host != NULL) {
                char *temp = NULL;
                temp = replace_host_port(request_url, agent_host, agent_port,
                                         agent_config);
                if (temp != NULL) {
                    free(request_url);
                    request_url = temp;
                }
            }
            am_web_log_debug("%s: Request_url after overriding "
                             "host and port: %s",
                             thisfunc, request_url);
        }
    }
    if (status == AM_SUCCESS) {
        // Check for magic notification URL
        if (B_TRUE == am_web_is_notification(request_url, agent_config)) {
            am_web_free_memory(request_url);
            am_web_delete_agent_configuration(agent_config);
            if(query != NULL) {
                free(query);
                query = NULL;
            }
            if(method != NULL) {
                free(method);
                method = NULL;
            }
            return REQ_PROCEED;
        }
    }
    // Check if the SSO token is in the cookie header
    if (status == AM_SUCCESS) {
        requestResult = getISCookie(pblock_findval(COOKIE_HDR, rq->headers),
                                    &dpro_cookie, agent_config);
        if (requestResult == REQ_ABORTED) {
            status = AM_FAILURE;
        } else if (dpro_cookie != NULL) {
            am_web_log_debug("%s: SSO token found in cookie header.",
                             thisfunc);
        }
    }
    // Create the environment map
    if( status == AM_SUCCESS) {
        status = am_map_create(&env_parameter_map);
        if( status != AM_SUCCESS) {
            am_web_log_error("%s: Unable to create map, status = %s (%d)",
                   thisfunc, am_status_to_string(status), status);
        }
    }    
    // If there is a proxy in front of the agent, the user can set in the
    // properties file the name of the headers that the proxy uses to set
    // the real client IP and host name. In that case the agent needs
    // to use the value of these headers to process the request
    //
    // Get the client IP address header set by the proxy, if there is one
    if (status == AM_SUCCESS) {
        clientIP_hdr_name = am_web_get_client_ip_header_name(agent_config);
        if (clientIP_hdr_name != NULL) {
            status = get_header_value(rq->headers, clientIP_hdr_name,
                                    B_FALSE, &clientIP_hdr,
                                    B_FALSE, NULL);
        }
    }
    // Get the client host name header set by the proxy, if there is one
    if (status == AM_SUCCESS) {
        clientHostname_hdr_name = 
               am_web_get_client_hostname_header_name(agent_config);
        if (clientHostname_hdr_name != NULL) {
            status = get_header_value(rq->headers, clientHostname_hdr_name,
                                    B_FALSE, &clientHostname_hdr,
                                    B_FALSE, NULL);
        }
    }
    // If the client IP and host name headers contain more than one
    // value, take the first value.
    if (status == AM_SUCCESS) {
        if ((clientIP_hdr != NULL) || (clientHostname_hdr != NULL)) {
            status = am_web_get_client_ip_host(clientIP_hdr,
                                               clientHostname_hdr,
                                               &clientIP, &clientHostname);
        }
    }
    // Set the IP address and host name in the environment map
    if ((status == AM_SUCCESS) && (clientIP != NULL)) {
        status = am_web_set_host_ip_in_env_map(clientIP, clientHostname,
                                      env_parameter_map, agent_config);
    }
    // If the client IP was not obtained previously,
    // get it from the REMOTE_ADDR header.
    if ((status == AM_SUCCESS) && (clientIP == NULL)) {
        status = get_header_value(sn->client, REQUEST_IP_ADDR,
                               B_FALSE, &clientIP_hdr, B_TRUE, &clientIP);
    }
    // In CDSSO mode, check if the sso token is in the post data
    if( status == AM_SUCCESS) {
        if((am_web_is_cdsso_enabled(agent_config) == B_TRUE) &&
                   (strcmp(method, REQUEST_METHOD_POST) == 0))
        {
            if((dpro_cookie == NULL) && 
               (am_web_is_url_enforced(request_url, pathInfo_hdr,
                        clientIP, agent_config) == B_TRUE))
            {
                // Set original method to GET
                orig_req = strdup(REQUEST_METHOD_GET);
                if (orig_req != NULL) {
                    am_web_log_debug("%s: Request method set to GET.",
                                          thisfunc);
                } else {
                    am_web_log_error("%s: Not enough memory to ",
                                "allocate orig_req.", thisfunc);
                    status = AM_NO_MEMORY;
                }
                // Check if dpro_cookie is in post data
                if( status == AM_SUCCESS) {
                    response = get_post_assertion_data(sn, rq, request_url);
                    status = am_web_check_cookie_in_post(args, &dpro_cookie,
                                               &request_url,
                                               &orig_req, method, response,
                                               B_FALSE, set_cookie, 
                                               set_method, agent_config);
                    if( status == AM_SUCCESS) {
                        am_web_log_debug("%s: SSO token found in "
                                             "assertion.",thisfunc);
                    } else {
                        am_web_log_debug("%s: SSO token not found in "
                                   "assertion. Redirecting to login page.",
                                   thisfunc);
                        status = AM_INVALID_SESSION;
                    }
                }
                // Set back the original clf-request attribute
                if (status == AM_SUCCESS) {
                    int clf_reqSize = 0;
                    if ((query != NULL) && (strlen(query) > 0)) {
                        clf_reqSize = strlen(orig_req) + strlen(uri_hdr) +
                                      strlen (query) + strlen(protocol) + 4;
                    } else {
                        clf_reqSize = strlen(orig_req) + strlen(uri_hdr) +
                                      strlen(protocol) + 3;
                    }
                    clf_req = malloc(clf_reqSize);
                    if (clf_req == NULL) {
                        am_web_log_error("%s: Unable to allocate %i "
                                         "bytes for clf_req",
                                         thisfunc, clf_reqSize);
                        status = AM_NO_MEMORY;
                    } else {
                        memset (clf_req,'\0',clf_reqSize);
                        strcpy(clf_req, orig_req);
                        strcat(clf_req, " ");
                        strcat(clf_req, uri_hdr);
                        if ((query != NULL) && (strlen(query) > 0)) {
                            strcat(clf_req, "?");
                            strcat(clf_req, query);
                        }
                        strcat(clf_req, " ");
                        strcat(clf_req, protocol);
                        am_web_log_debug("%s: clf-request set to %s",
                                          thisfunc, clf_req);
                    }
                    pblock_nvinsert(REQUEST_CLF, clf_req, rq->reqpb);
                }
            } 
        }
    }
    // Check if access is allowed.
    if( status == AM_SUCCESS) {
        if (dpro_cookie != NULL) {
            am_web_log_debug("%s: SSO token = %s", thisfunc, dpro_cookie);
        } else {
            am_web_log_debug("%s: SSO token not found.", thisfunc);
        }
        status = am_web_is_access_allowed(dpro_cookie,
                                          request_url,
                                          pathInfo_hdr, method,
                                          clientIP,
                                          env_parameter_map,
                                          &result,
                                          agent_config);
        am_map_destroy(env_parameter_map);
    }
    switch(status) {
    case AM_SUCCESS:
        // Set remote user and authentication type
        ruser = result.remote_user;
        if (ruser != NULL) {
            pb_param *pbuser = pblock_remove(AUTH_USER_VAR, rq->vars);
            pb_param *pbauth = pblock_remove(AUTH_TYPE_VAR, rq->vars);
            if (pbuser != NULL) {
                param_free(pbuser);
            }
            pblock_nvinsert(AUTH_USER_VAR, ruser, rq->vars);
            if (pbauth != NULL) {
                param_free(pbauth);
            }
            pblock_nvinsert(AUTH_TYPE_VAR, AM_WEB_AUTH_TYPE_VALUE, rq->vars);
            am_web_log_debug("%s: access allowed to %s", thisfunc, ruser);
        } else {
            am_web_log_debug("%s: Remote user not set, "
                             "allowing access to the url as it is in not "
                             "enforced list", thisfunc);
        }

        if (am_web_is_logout_url(request_url,  agent_config) == B_TRUE) {
            (void)am_web_logout_cookies_reset(reset_cookie, args, agent_config);
        }
        // set LDAP user attributes to http header
        status = am_web_result_attr_map_set(&result, set_header, 
                                           set_cookie_in_response, 
                                           set_header_attr_as_cookie, 
                                           get_cookie_sync, args, agent_config);
        if (status != AM_SUCCESS) {
            am_web_log_error("%s: am_web_result_attr_map_set failed, "
                        "status = %s (%d)", thisfunc,
                        am_status_to_string(status), status);
            requestResult = REQ_ABORTED;
        } else {
            requestResult = REQ_PROCEED;
        }
        break;

    case AM_ACCESS_DENIED:
        am_web_log_debug("%s: Access denied to %s", thisfunc,
                    result.remote_user ? result.remote_user :
                    "******");
        requestResult = do_redirect(sn, rq, status, &result,
                                request_url, method, agent_config);
        break;

    case AM_INVALID_SESSION:
        if (am_web_is_cdsso_enabled(agent_config) == B_TRUE) {
            cdStatus = am_web_do_cookie_domain_set(set_cookie, args,
                                                   EMPTY_STRING,
                                                   agent_config);
            if(cdStatus != AM_SUCCESS) {
                am_web_log_error("%s: CDSSO reset cookie failed", thisfunc);
            }
        }
        am_web_do_cookies_reset(reset_cookie, args, agent_config);
        requestResult =  do_redirect(sn, rq, status, &result,
                                 request_url, method,
                                 agent_config);
        break;

    case AM_INVALID_FQDN_ACCESS:
        // Redirect to self with correct FQDN - no post preservation
        requestResult = do_redirect(sn, rq, status, &result,
                                request_url, method, agent_config);
        break;

    case AM_REDIRECT_LOGOUT:
        status = am_web_get_logout_url(&logout_url, agent_config);
        if(status == AM_SUCCESS)
        {
            do_url_redirect(sn,rq,logout_url);
        }
        else
        {
            requestResult = REQ_ABORTED;
            am_web_log_debug("validate_session_policy(): "
                             "am_web_get_logout_url failed. ");
        }
        break;

    case AM_INVALID_ARGUMENT:
    case AM_NO_MEMORY:
    default:
        am_web_log_error("validate_session_policy() Status: %s (%d)",
                          am_status_to_string(status), status);
        requestResult = REQ_ABORTED;
        break;
    }
    // Cleaning
    am_web_clear_attributes_map(&result);
    am_policy_result_destroy(&result);
    am_web_free_memory(dpro_cookie);
    am_web_free_memory(request_url);
    am_web_free_memory(logout_url);
    am_web_delete_agent_configuration(agent_config);
    if (orig_req != NULL) {
        free(orig_req);
        orig_req = NULL;
    }
    if (response != NULL) {
        free(response);
        response = NULL;
    }
    if (clf_req != NULL) {
        free(clf_req);
        clf_req = NULL;
    }
    if(query != NULL) {
        free(query);
        query = NULL;
    }
    if(method != NULL) {
        free(method);
        method = NULL;
    }
    if(clientIP != NULL) {
        am_web_free_memory(clientIP);
    }
    if(clientHostname != NULL) {
        am_web_free_memory(clientHostname);
    }
    am_web_log_max_debug("%s: Completed handling request with status: %s.",
                         thisfunc, am_status_to_string(status));

    return requestResult;
}
int register_attribute_getter (pblock *pb, Session *sn, Request *rq)
{
    char *method_str = pblock_findval(ACL_ATTR_METHOD, pb);
    char *attr = pblock_findval(ACL_ATTR_ATTRIBUTE, pb);
    char *funcStr = pblock_findval(ACL_ATTR_GETTERFN, pb);
    char *dbtype_str = pblock_findval(ACL_ATTR_DBTYPE, pb);
    char *position_str = pblock_findval(ACL_ATTR_POSITION, pb);
    ACLDbType_t dbtype = ACL_DBTYPE_ANY;
    ACLMethod_t method = ACL_METHOD_ANY;
    ACLAttrGetterFn_t func;
    char err[BIG_LINE];
    NSErr_t *errp = 0;
    int position = ACL_AT_END;

    if (method_str) {
	ACL_REG(ACL_MethodFind(errp, method_str, &method),
		"Method \"%s\" is not registered", method_str);
    }

    if (dbtype_str) {
	ACL_REG(ACL_DbTypeFind(errp, dbtype_str, &dbtype),
		"Database type \"%s\" is not registered", dbtype_str);
    }

    if (!attr || !*attr) {
	pblock_nvinsert("error", "Attribute name is missing", pb);
	return REQ_ABORTED;
    }

    if (!funcStr || !*funcStr) {
	pblock_nvinsert("error", "Attribute getter function name is missing", pb);
	return REQ_ABORTED;
    }

    if (!position_str) {
	if (!strcmp(position_str, "ACL_AT_FRONT")) position = ACL_AT_FRONT;
	else if (!strcmp(position_str, "ACL_AT_END")) position = ACL_AT_END;
	else if (!strcmp(position_str, "ACL_REPLACE_ALL")) position = ACL_REPLACE_ALL;
	else if (!strcmp(position_str, "ACL_REPLACE_MATCHING")) position = ACL_REPLACE_MATCHING;
	else {
	    sprintf(err, "Position attribute \"%s\" is not valid", position_str);
	    pblock_nvinsert("error", err, pb);
	    return REQ_ABORTED;
	}
    }

    func = (ACLAttrGetterFn_t)func_find((char *)funcStr);

    if (!func) {
	sprintf(err, "Could not map \"%s\" to a function", funcStr);
	pblock_nvinsert("error", err, pb);
	return REQ_ABORTED;
    }

    ACL_REG(ACL_AttrGetterRegister(errp, attr, func, method, dbtype, position,
                                   NULL),
	    "Failed to register attribute getter for %s",
	    attr);

    return REQ_PROCEED;
}
PRStatus FcgiParser::parseHttpHeader(CircularBuffer& to) {
    if(!waitingForDataParse)
        return PR_SUCCESS;

    const char *data = httpHeader.data();
    int len = httpHeader.length();
    PRUint8 flag = 0;
    while(len-- && flag < 2) {
        switch(*data) {
            case '\r':
                break;
            case '\n':
                flag++;
                break;
            default:
                flag = 0;
                break;
        }

        data++;
    }

    /*
     * Return (to be called later when we have more data)
     */

    if(flag < 2)
        return PR_SUCCESS;

    waitingForDataParse = PR_FALSE;
    Request *rq = request->getOrigRequest();

    pblock *authpb = NULL;
    if(fcgiRole == FCGI_AUTHORIZER) {
        authpb = pblock_create(rq->srvhdrs->hsize);
    }

    register int x ,y;
    register char c;
    int nh;
    char t[REQ_MAX_LINE];
    PRBool headerEnd = PR_FALSE;
    char* statusHeader = pblock_findval("status", rq->srvhdrs);
    char *next = const_cast<char *>(httpHeader.data());

    nh = 0;
    x = 0; y = -1;
 
    for(; !headerEnd;) {
        c = *(next++);
        switch(c) {
        case CR:
            // Silently ignore CRs
            break;

        case LF:
            if (x == 0) {
                headerEnd = PR_TRUE;
                break; 
            }

            t[x] = '\0';
            if(y == -1) {
                request->log(LOG_FAILURE,  "name without value: got line \"%s\"", t);
                return PR_FAILURE;
            }
            while(t[y] && isspace(t[y])) ++y;

            // Do not change the status header to 200 if it was already set
            // This would happen only if it were a cgi error handler
            // and so the status had been already set on the request
            // originally
            if (!statusHeader || // If we don't already have a Status: header
                PL_strcmp(t, "status") || // or this isn't a Status: header
                PL_strncmp(&t[y], "200", 3)) // or this isn't "Status: 200"
            {
                if(!PL_strcmp(t, "content-type")) {
                    pb_param* pParam = pblock_remove ( "content-type", rq->srvhdrs );
                    if ( pParam ) param_free ( pParam );
                }
                if(fcgiRole == FCGI_AUTHORIZER) {
                    pblock_nvinsert(t, &t[y], authpb);
                } else {
                    pblock_nvinsert(t, &t[y], rq->srvhdrs);
                } // !FCGI_AUTHORIZER
            }

            x = 0;
            y = -1;
            ++nh;
            break;

        case ':':
            if(y == -1) {
                y = x+1;
                c = '\0';
            }

        default:
            t[x++] = ((y == -1) && isupper(c) ? tolower(c) : c);

        }
    } // for

    if(fcgiRole == FCGI_AUTHORIZER) {
        if(parseAuthHeaders(authpb) != PR_SUCCESS) {
            pblock_free(authpb);
            return PR_FAILURE;
        }

        pblock_copy(authpb, rq->srvhdrs);
        pblock_free(authpb);

    } else {

        /*
         * We're done scanning the FCGI script's header output.  Now
         * we have to write to the client:  status, FCGI header, and
         * any over-read FCGI output.
         */
        char *s;
        char *l = pblock_findval("location", rq->srvhdrs);

        if((s = pblock_findval("status", rq->srvhdrs))) {
            if((strlen(s) < 3) ||
               (!isdigit(s[0]) || (!isdigit(s[1])) || (!isdigit(s[2])))) {
                s = NULL;
            }
            else {
              char ch = s[3];
              s[3] = '\0';
              int statusNum = atoi(s);
              s[3] = ch;

              rq->status_num = statusNum;
            }
        }

        if(!s) {
            if (l)
                pblock_nvinsert("url", l, rq->vars);
            protocol_status(request->getOrigSession(), request->getOrigRequest(), (l ? PROTOCOL_REDIRECT : PROTOCOL_OK), NULL);
        }
    }

    len = next - httpHeader.data();
    len = httpHeader.length() - len;

    if(len < 0)
        return PR_FAILURE;

    /*
     * Only send the body for methods other than HEAD.
     */
    if(!request->isHead()) {
        if(len > 0) {
            if(to.addData(next, len) != len)
                return PR_FAILURE;
        }
    }

    next = NULL;
    return PR_SUCCESS;
}
PRStatus FcgiParser::parseAuthHeaders(pblock *pb) {
    Request *rq = request->getOrigRequest();
    authHeaderPrefixLen = strlen(AUTH_HEADER_PREFIX);
    char *s;

    if(pb) {
        if((s = pblock_findval("status", pb))) {
            if((strlen(s) < 3) ||
               (!isdigit(s[0]) || (!isdigit(s[1])) || (!isdigit(s[2])))) {
                s = NULL;
            }
            else {
              char ch = s[3];
              s[3] = '\0';
              int statusNum = atoi(s);
              s[3] = ch;

              rq->status_num = statusNum;
              if(statusNum == 200)
                authorized = PR_TRUE;
            }
        }

        if(!authorized) {
            protocol_status(request->getOrigSession(), request->getOrigRequest(), PROTOCOL_UNAUTHORIZED, NULL);
        } else {
            //retain only the headers starting with "Varaiable-"
            for (int i = 0; i < pb->hsize; i++) {
                pb_entry *p = pb->ht[i];
                while (p) {
                    const char *name = PL_strdup(p->param->name);
                    const char *value = PL_strdup(p->param->value);

                    if (*name == 'v' && (!PL_strcmp(name, "variable-"))) {
                        pb_param *pparam = pblock_fr((char *)name, pb, PR_TRUE);
                        param_free(pparam);
                        name += authHeaderPrefixLen;   // remove the prefix from name
                        if(*name == 'r' && (!PL_strcmp(name, "remote_user"))) {
                            pblock_nvinsert("auth-user", value, rq->vars);
                        }
            if(*name == 'a' && (!PL_strcmp(name, "auth_type"))) {
                            pblock_nvinsert("auth-type", value, rq->vars);
                        }

                        pblock_nvinsert(name, value, rq->headers);
                    }

                   PL_strfree((char *)name);
                   PL_strfree((char *)value);

                   p = p->next;
                } //while
            } //for
        } //if

    } else {
        lastError = INVALID_HTTP_HEADER;
        request->log(LOG_FAILURE, GetString(DBT_invalid_response));
        return PR_FAILURE;
    }

    return PR_SUCCESS;
}
Beispiel #30
0
NSAPI_PUBLIC int web_agent_init(pblock *param, Session *sn, Request *rq)
{
    am_status_t status;
    int nsapi_status = REQ_PROCEED;
    char *temp_buf = NULL;
    char *agent_bootstrap_file = NULL;
    char *agent_config_file = NULL;

    initLock = crit_init();

    temp_buf = pblock_findval(DSAME_CONF_DIR, param);

    if (temp_buf != NULL) {
        agent_bootstrap_file = 
            system_malloc(strlen(temp_buf) + sizeof(AGENT_BOOTSTRAP_FILE));
        agent_config_file =
            system_malloc(strlen(temp_buf) + sizeof(AGENT_CONFIG_FILE));

        if (agent_bootstrap_file != NULL) {
            strcpy(agent_bootstrap_file, temp_buf);
            strcat(agent_bootstrap_file, AGENT_BOOTSTRAP_FILE);
        } else {
            log_error(LOG_FAILURE, "URL Access Agent: ", sn, rq,
                     "web_agent_init() unable to allocate memory for bootstrap "
                     "file name", DSAME_CONF_DIR);
            nsapi_status = REQ_ABORTED;
	}

        if (agent_config_file != NULL) {
            strcpy(agent_config_file, temp_buf);
            strcat(agent_config_file, AGENT_CONFIG_FILE);
        } else {
            log_error(LOG_FAILURE, "URL Access Agent: ", sn, rq,
                 "web_agent_init() unable to allocate memory for local config "
                 "file name", DSAME_CONF_DIR);
            nsapi_status = REQ_ABORTED;
        }

        status = am_properties_create(&agent_props.agent_bootstrap_props);
        if(status == AM_SUCCESS) {
            status = am_properties_load(agent_props.agent_bootstrap_props,
                                        agent_bootstrap_file);
            if(status == AM_SUCCESS) {
                //this is where the agent config info is passed from filter code
                //to amsdk. Not sure why agent_props is required.
                status = am_web_init(agent_bootstrap_file,
                                     agent_config_file);
                system_free(agent_bootstrap_file);
                system_free(agent_config_file);
                if (AM_SUCCESS != status) {
                    log_error(LOG_FAILURE, "URL Access Agent: ", sn, rq,
                             "Initialization of the agent failed: "
                             "status = %s (%d)", am_status_to_string(status),
                              status);
                    nsapi_status = REQ_ABORTED;
                 }
            } else {
                log_error(LOG_FAILURE, "web_agent_init():", sn, rq,
                         "Error while creating properties object= %s",
                          am_status_to_string(status));
                nsapi_status = REQ_ABORTED;
            }
        } else {
            log_error(LOG_FAILURE, "web_agent_init():", sn, rq,
                      "Error while creating properties object= %s",
                      am_status_to_string(status));
             nsapi_status = REQ_ABORTED;
        }
    } else {
        log_error(LOG_FAILURE, "URL Access Agent: ", sn, rq,
                 "web_agent_init() %s variable not defined in magnus.conf",
                  DSAME_CONF_DIR);
        nsapi_status = REQ_ABORTED;
    }

    if(nsapi_status == REQ_PROCEED) {
        daemon_atrestart(&agent_cleanup, NULL);
    }

    return nsapi_status;
}