/** * Sends a brigade with an error bucket down the filter chain. */ apr_status_t send_error_bucket(modsec_rec *msr, ap_filter_t *f, int status) { apr_bucket_brigade *brigade = NULL; apr_bucket *bucket = NULL; /* Set the status line explicitly for the error document */ f->r->status_line = ap_get_status_line(status); brigade = apr_brigade_create(f->r->pool, f->r->connection->bucket_alloc); if (brigade == NULL) return APR_EGENERAL; bucket = ap_bucket_error_create(status, NULL, f->r->pool, f->r->connection->bucket_alloc); if (bucket == NULL) return APR_EGENERAL; APR_BRIGADE_INSERT_TAIL(brigade, bucket); bucket = apr_bucket_eos_create(f->r->connection->bucket_alloc); if (bucket == NULL) return APR_EGENERAL; APR_BRIGADE_INSERT_TAIL(brigade, bucket); ap_pass_brigade(f->next, brigade); /* NOTE: * It may not matter what we do from the filter as it may be too * late to even generate an error (already sent to client). Nick Kew * recommends to return APR_EGENERAL in hopes that the handler in control * will notice and do The Right Thing. So, that is what we do now. */ return APR_EGENERAL; }
static void flush_headers(slash_context_t* ctx) { sl_response_key_value_t* headers; size_t header_count, i; if(!ctx->headers_sent) { ctx->r->status = sl_response_get_status(ctx->vm); ctx->r->status_line = ap_get_status_line(ctx->r->status); headers = sl_response_get_headers(ctx->vm, &header_count); for(i = 0; i < header_count; i++) { apr_table_add(ctx->r->headers_out, headers[i].name, headers[i].value); } ctx->headers_sent = 1; } }
DAV_DECLARE(dav_get_props_result) dav_get_props(dav_propdb *propdb, apr_xml_elem *prop_elem) { const dav_hooks_db *db_hooks = propdb->db_hooks; apr_xml_elem *elem = prop_elem; apr_text_header hdr_good = { 0 }; apr_text_header hdr_bad = { 0 }; apr_text_header hdr_403 = { 0 }; apr_text_header hdr_ns = { 0 }; int have_good = 0; dav_get_props_result result = { 0 }; char *marks_liveprop; dav_xmlns_info *xi; int xi_filled = 0; /* ### NOTE: we should pass in TWO buffers -- one for keys, one for the marks */ /* we will ALWAYS provide a "good" result, even if it is EMPTY */ apr_text_append(propdb->p, &hdr_good, "<D:propstat>" DEBUG_CR "<D:prop>" DEBUG_CR); /* ### the marks should be in a buffer! */ /* allocate zeroed-memory for the marks. These marks indicate which liveprop namespaces we've generated into the output xmlns buffer */ /* same for the liveprops */ marks_liveprop = apr_pcalloc(propdb->p, dav_get_liveprop_ns_count() + 1); xi = dav_xmlns_create(propdb->p); for (elem = elem->first_child; elem; elem = elem->next) { dav_elem_private *priv; dav_error *err; dav_prop_insert inserted; dav_prop_name name; if (elem->ns == APR_XML_NS_NONE) name.ns = ""; else name.ns = APR_XML_GET_URI_ITEM(propdb->ns_xlate, elem->ns); name.name = elem->name; /* ** First try live property providers; if they don't handle ** the property, then try looking it up in the propdb. */ if (elem->priv == NULL) { elem->priv = apr_pcalloc(propdb->p, sizeof(*priv)); } priv = elem->priv; /* cache the propid; dav_get_props() could be called many times */ if (priv->propid == 0) dav_find_liveprop(propdb, elem); if (priv->propid != DAV_PROPID_CORE_UNKNOWN) { /* insert the property. returns 1 if an insertion was done. */ if ((err = dav_insert_liveprop(propdb, elem, DAV_PROP_INSERT_VALUE, &hdr_good, &inserted)) != NULL) { /* ### need to propagate the error to the caller... */ /* ### skip it for now, as if nothing was inserted */ } if (inserted == DAV_PROP_INSERT_VALUE) { have_good = 1; /* ** Add the liveprop's namespace URIs. Note that provider==NULL ** for core properties. */ if (priv->provider != NULL) { const char * const * scan_ns_uri; for (scan_ns_uri = priv->provider->namespace_uris; *scan_ns_uri != NULL; ++scan_ns_uri) { long ns; ns = dav_get_liveprop_ns_index(*scan_ns_uri); if (marks_liveprop[ns]) continue; marks_liveprop[ns] = 1; dav_insert_xmlns(propdb->p, "lp", ns, *scan_ns_uri, &hdr_ns); } } /* property added. move on to the next property. */ continue; } else if (inserted == DAV_PROP_INSERT_NOTDEF) { /* nothing to do. fall thru to allow property to be handled as a dead property */ } else if (inserted == DAV_PROP_INSERT_FORBIDDEN) { if (hdr_403.first == NULL) apr_text_append(propdb->p, &hdr_403, "<D:propstat>" DEBUG_CR "<D:prop>" DEBUG_CR); /* output this property's name (into the forbidden propstats) */ dav_output_prop_name(propdb->p, &name, xi, &hdr_403); continue; } #if DAV_DEBUG else { #if 0 /* ### need to change signature to return an error */ return dav_new_error(propdb->p, HTTP_INTERNAL_SERVER_ERROR, 0, "INTERNAL DESIGN ERROR: insert_liveprop " "did not insert what was asked for."); #endif } #endif } /* The property wasn't a live property, so look in the dead property database. */ /* make sure propdb is really open */ if (propdb->deferred) { /* ### what to do with db open error? */ (void) dav_really_open_db(propdb, 1 /*ro*/); } /* only bother to look if a database exists */ if (propdb->db != NULL) { int found; if ((err = (*db_hooks->output_value)(propdb->db, &name, xi, &hdr_good, &found)) != NULL) { /* ### what to do? continue doesn't seem right... */ continue; } if (found) { have_good = 1; /* if we haven't added the db's namespaces, then do so... */ if (!xi_filled) { (void) (*db_hooks->define_namespaces)(propdb->db, xi); xi_filled = 1; } continue; } } /* not found as a live OR dead property. add a record to the "bad" propstats */ /* make sure we've started our "bad" propstat */ if (hdr_bad.first == NULL) { apr_text_append(propdb->p, &hdr_bad, "<D:propstat>" DEBUG_CR "<D:prop>" DEBUG_CR); } /* output this property's name (into the bad propstats) */ dav_output_prop_name(propdb->p, &name, xi, &hdr_bad); } apr_text_append(propdb->p, &hdr_good, "</D:prop>" DEBUG_CR "<D:status>HTTP/1.1 200 OK</D:status>" DEBUG_CR "</D:propstat>" DEBUG_CR); /* default to start with the good */ result.propstats = hdr_good.first; /* we may not have any "bad" results */ if (hdr_bad.first != NULL) { /* "close" the bad propstat */ apr_text_append(propdb->p, &hdr_bad, "</D:prop>" DEBUG_CR "<D:status>HTTP/1.1 404 Not Found</D:status>" DEBUG_CR "</D:propstat>" DEBUG_CR); /* if there are no good props, then just return the bad */ if (!have_good) { result.propstats = hdr_bad.first; } else { /* hook the bad propstat to the end of the good one */ hdr_good.last->next = hdr_bad.first; } } if (hdr_403.first != NULL) { /* "close" the bad propstat */ char *perm_denied_txt = apr_psprintf(propdb->p, "</D:prop>" DEBUG_CR "<D:status>HTTP/1.1 %s </D:status>" "</D:propstat>" DEBUG_CR, ap_get_status_line(dav_get_permission_denied_status(propdb->r))); apr_text_append(propdb->p, &hdr_403, perm_denied_txt); if (hdr_bad.first != NULL) hdr_bad.last->next = hdr_403.first; else if (have_good) hdr_good.last->next = hdr_403.first; else result.propstats = hdr_403.first; } /* add in all the various namespaces, and return them */ dav_xmlns_generate(xi, &hdr_ns); result.xmlns = hdr_ns.first; return result; }
apr_status_t ma_advertise_server(server_rec *server, int type) { char buf[MA_BSIZE]; char dat[APR_RFC822_DATE_LEN]; char add[40]; unsigned char msig[APR_MD5_DIGESTSIZE]; unsigned char ssig[APR_MD5_DIGESTSIZE * 2 + 1]; const char *asl; char *p = buf; int i, c = 0; apr_size_t l = MA_BSIZE - 8; apr_size_t n = 0; apr_md5_ctx_t md; mod_advertise_config *mconf = ap_get_module_config(server->module_config, &advertise_module); ma_sequence++; if (ma_sequence < 1) ma_sequence = 1; sprintf(buf, "%" APR_INT64_T_FMT, ma_sequence); ap_recent_rfc822_date(dat, apr_time_now()); asl = ap_get_status_line(ma_advertise_stat); /* Create MD5 digest * salt + date + sequence + srvid */ apr_md5_init(&md); apr_md5_update(&md, magd->ssalt, APR_MD5_DIGESTSIZE); apr_md5_update(&md, dat, strlen(dat)); apr_md5_update(&md, buf, strlen(buf)); apr_md5_update(&md, magd->srvid + 1, strlen(magd->srvid) - 1); apr_md5_final(msig, &md); /* Convert MD5 digest to hex string */ for (i = 0; i < APR_MD5_DIGESTSIZE; i++) { ssig[c++] = hex[msig[i] >> 4]; ssig[c++] = hex[msig[i] & 0x0F]; } ssig[c] = '\0'; n = apr_snprintf(p, l, MA_ADVERTISE_SERVER_FMT, asl, dat, ma_sequence, ssig, magd->srvid + 1); if (type == MA_ADVERTISE_SERVER) { char *ma_advertise_srvs = mconf->ma_advertise_srvs; if (strchr(ma_advertise_srvs, ':') != NULL) { apr_snprintf(add, 40, "[%s]", mconf->ma_advertise_srvs); ma_advertise_srvs = add; } l -= n; n += apr_snprintf(p + n, l, "X-Manager-Address: %s:%u" CRLF "X-Manager-Url: %s" CRLF "X-Manager-Protocol: %s" CRLF "X-Manager-Host: %s" CRLF, ma_advertise_srvs, mconf->ma_advertise_srvp, mconf->ma_advertise_srvh, mconf->ma_advertise_srvm, server->server_hostname); } strcat(p, CRLF); n += 2; return apr_socket_sendto(ma_mgroup_socket, ma_mgroup_sa, 0, buf, &n); }