const char * vmod_decrypt(struct sess *sp, const char *text, const char *key) { char *p; unsigned u, v; unsigned char decrypt[TAILLE]; memset (decrypt, 0, TAILLE ); u = WS_Reserve(sp->wrk->ws, 0); /* Reserve some work space */ p = sp->wrk->ws->f; /* Front of workspace area */ decryption ((char*)key, (unsigned char*) decrypt, (unsigned char*) text); v = snprintf(p, u, "%s", decrypt); v++; if (v > u) { /* No space, reset and leave */ WS_Release(sp->wrk->ws, 0); return (NULL); } /* Update work space with what we've used */ WS_Release(sp->wrk->ws, v); return (p); }
VCL_STRING vmod_uuid(const struct vrt_ctx *ctx, struct vmod_priv *pv){ char *p; unsigned u, v; char *uuid_str = uuid_v1(); u = WS_Reserve(ctx->ws, 0); // Reserve some work space if (sizeof(uuid_str) > u) { // No space, reset and leave WS_Release(ctx->ws, 0); return(NULL); } p = ctx->ws->f; // Front of workspace area strncpy(p, uuid_str, 37); // free up the uuid string once it's copied in place if(uuid_str){ free(uuid_str); } // keep track of how much we actually used v+=37; // Update work space with what we've used WS_Release(ctx->ws, v); // debug("uuid: %s", p); return(p); }
vmod_exec(const struct vrt_ctx *ctx, struct vmod_priv *priv, VCL_STRING sql) { struct vmod_sqlite3_result r; struct vmod_sqlite3 *v; char *e, *p; CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC); AN(priv); if (!priv->priv) { e = (char *)sqlite3_errstr(SQLITE_ERROR); p = WS_Copy(ctx->ws, e, -1); return (p); } CAST_OBJ_NOTNULL(v, priv->priv, VMOD_SQLITE3_MAGIC); r.u = WS_Reserve(ctx->ws, 0); r.p = ctx->ws->f; r.d = v->d; r.l = 0; r.r = 0; *(r.p) = '\0'; if (sqlite3_exec(v->db, sql, vmod_exec_cb, &r, &e) != SQLITE_OK) { WS_Release(ctx->ws, 0); p = WS_Copy(ctx->ws, e, -1); sqlite3_free(e); return (p); } WS_Release(ctx->ws, r.l + 1); return (r.p); }
static const char * vmod_updown(const struct vrt_ctx *ctx, int up, const char *s, va_list ap) { unsigned u; char *b, *e; const char *p; CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC); u = WS_Reserve(ctx->ws, 0); e = b = ctx->ws->f; e += u; p = s; while (p != vrt_magic_string_end && b < e) { if (p != NULL) { for (; b < e && *p != '\0'; p++) if (up) *b++ = (char)toupper(*p); else *b++ = (char)tolower(*p); } p = va_arg(ap, const char *); } if (b < e) *b = '\0'; b++; if (b > e) { WS_Release(ctx->ws, 0); return (NULL); } else { e = b; b = ctx->ws->f; WS_Release(ctx->ws, e - b); return (b); } }
const char * vmod_encrypt(struct sess *sp, const char *text, const char *key ) { char *p; unsigned u, v; unsigned char crypt64[TAILLE]; unsigned char ciphertext_buffer[TAILLE]; unsigned char *ciphertext_string = &ciphertext_buffer[0]; int ciphertext_len = 0; memset (crypt64, 0, TAILLE ); memset (ciphertext_buffer, 0, TAILLE ); u = WS_Reserve(sp->wrk->ws, 0); /* Reserve some work space */ p = sp->wrk->ws->f; /* Front of workspace area */ encryption ((char*)key,(unsigned char*) text, (unsigned char*) ciphertext_string, (unsigned char*) crypt64, &ciphertext_len); v = snprintf(p, u, "%s", crypt64); v++; if (v > u) { /* No space, reset and leave */ WS_Release(sp->wrk->ws, 0); return (NULL); } /* Update work space with what we've used */ WS_Release(sp->wrk->ws, v); return (p); }
static const char * absolutize_link(struct ws* ws, const char* path, const char* link) { unsigned available, written; char *front, *path_copy; if (link[0] == '/') { return link; } path_copy = (char*) WS_Copy(ws, path, -1); if (path_copy == NULL) { return NULL; } available = WS_Reserve(ws, 0); front = ws->f; written = snprintf(front, available, "%s/%s", dirname(path_copy), link); written++; // null-terminating char if (written > available) { WS_Release(ws, 0); return NULL; } WS_Release(ws, written); return front; }
char * VRT_String(struct ws *ws, const char *h, const char *p, va_list ap) { char *b, *e; unsigned u, x; u = WS_Reserve(ws, 0); e = b = ws->f; e += u; if (h != NULL) { x = strlen(h); if (b + x < e) memcpy(b, h, x); b += x; if (b < e) *b = ' '; b++; } b = VRT_StringList(b, e > b ? e - b : 0, p, ap); if (b == NULL || b == e) { WS_Release(ws, 0); return (NULL); } e = b; b = ws->f; WS_Release(ws, e - b); return (b); }
static const char* apply_filter(struct filter_context *context) { const char *params = context->params.filter.params; unsigned available = WS_Reserve(context->ws, 0); char *begin = context->ws->f; char *end = &begin[available]; const char *cursor = context->query_string; append_string(&begin, end, context->uri, cursor - context->uri + 1); while (*cursor != '\0' && begin < end) { const char *param_position = ++cursor; const char *equal_position = NULL; while (*cursor != '\0' && *cursor != '&') { if (equal_position == NULL && *cursor == '=') { equal_position = cursor; } cursor++; } int param_name_length = (equal_position ? equal_position : cursor) - param_position; if ( ! context->is_filtered(param_position, param_name_length, context) ) { append_string(&begin, end, param_position, cursor - param_position); if (*cursor == '&') { *begin = '&'; begin++; } } } if (begin < end) { begin -= (begin[-1] == '&'); begin -= (begin[-1] == '?'); *begin = '\0'; } begin++; if (begin > end) { WS_Release(context->ws, 0); return context->uri; } end = begin; begin = context->ws->f; WS_Release(context->ws, end - begin); return begin; }
unsigned url_encode_setHdr(struct sess *sp, char* url,char *head,int *encoded_size){ char *copy; char buf[3075]; int size = 3 * strlen(url) + 3; if(size > 3075){ /////////////////////////////////////////////// //use ws int u = WS_Reserve(sp->wrk->ws, 0); if(u < size){ #ifdef DEBUG_SYSLOG syslog(6,"parse:url_encode_setHdr more ws size"); #endif return 0; } copy = (char*)sp->wrk->ws->f; /////////////////////////////////////////////// }else{ copy = buf; } __url_encode(url,encoded_size,copy); *encoded_size += strlen(copy) + head[0] +1; if(size > 3075){ WS_Release(sp->wrk->ws,strlen(copy)+1); } //sethdr VRT_SetHdr(sp, HDR_REQ, head, copy, vrt_magic_string_end); return(1); }
vbf_printRequestBody(struct req *req, void *priv, void *ptr, size_t l) { unsigned u; //reserve work-space u = WS_Reserve(req->ws, 0); if(u <= VMOD_DUMP_KEY_LEN) { //no space. WS_Release(req->ws, 0); return (0); } work_body(req,req->ws->f, u, ptr, l, req->http0); //free work-space WS_Release(req->ws, 0); return(0); }
SES_Proto_Sess(struct worker *wrk, void *arg) { struct req *req; struct sess *sp; CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC); CAST_OBJ_NOTNULL(sp, arg, SESS_MAGIC); WS_Release(sp->ws, 0); /* * Assume we're going to receive something that will likely * involve a request... */ (void)VTCP_blocking(sp->fd); req = Req_New(wrk, sp); CHECK_OBJ_NOTNULL(req, REQ_MAGIC); req->htc->fd = sp->fd; SES_RxInit(req->htc, req->ws, cache_param->http_req_size, cache_param->http_req_hdr_len); if (sp->sess_step < S_STP_H1_LAST) { wrk->task.func = SES_Proto_Req; wrk->task.priv = req; } else if (sp->sess_step < S_STP_PROXY_LAST) { wrk->task.func = VPX_Proto_Sess; wrk->task.priv = req; } else { WRONG("Wrong session step"); } }
void http_CollectHdr(struct http *hp, const char *hdr) { unsigned u, v, ml, f = 0, x; char *b = NULL, *e = NULL; for (u = HTTP_HDR_FIRST; u < hp->nhd; u++) { while (u < hp->nhd && http_IsHdr(&hp->hd[u], hdr)) { Tcheck(hp->hd[u]); if (f == 0) { /* Found first header, just record the fact */ f = u; break; } if (b == NULL) { /* Found second header, start our collection */ ml = WS_Reserve(hp->ws, 0); b = hp->ws->f; e = b + ml; x = Tlen(hp->hd[f]); if (b + x < e) { memcpy(b, hp->hd[f].b, x); b += x; } else b = e; } AN(b); AN(e); /* Append the Nth header we found */ if (b < e) *b++ = ','; x = Tlen(hp->hd[u]) - *hdr; if (b + x < e) { memcpy(b, hp->hd[u].b + *hdr, x); b += x; } else b = e; /* Shift remaining headers up one slot */ for (v = u; v < hp->nhd - 1; v++) hp->hd[v] = hp->hd[v + 1]; hp->nhd--; } } if (b == NULL) return; AN(e); if (b >= e) { WS_Release(hp->ws, 0); return; } *b = '\0'; hp->hd[f].b = hp->ws->f; hp->hd[f].e = b; WS_ReleaseP(hp->ws, b + 1); }
vmod_normalize(VRT_CTX, VCL_STRING s) { char *p; utf8proc_ssize_t len; unsigned u; int options; CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC); if (!s || !*s) { VSLb(ctx->vsl, SLT_Error, "vsf.normalize: No input"); return (NULL); } len = strlen(s); assert(len > 0); u = WS_Reserve(ctx->ws, 0); if (u < len * sizeof(utf8proc_int32_t) + 1) { VSLb(ctx->vsl, SLT_Error, "vsf.normalize: Out of workspace"); WS_Release(ctx->ws, 0); return (NULL); } p = ctx->ws->f; options = UTF8PROC_STABLE | UTF8PROC_COMPAT | UTF8PROC_COMPOSE | UTF8PROC_IGNORE | UTF8PROC_NLF2LF | UTF8PROC_LUMP | UTF8PROC_STRIPMARK; len = utf8proc_decompose((utf8proc_uint8_t *)s, len, (utf8proc_int32_t *)p, len, options); if (len < 0) { VSLb(ctx->vsl, SLT_Error, "vsf.normalize: utf8proc_decompose: %s", utf8proc_errmsg(len)); WS_Release(ctx->ws, 0); return (NULL); } assert(len * sizeof(utf8proc_int32_t) + 1 < u); len = utf8proc_reencode((utf8proc_int32_t *)p, len, options); assert(len > 0); WS_Release(ctx->ws, len + 1); return (p); }
static const char * vmod_hmac_sha256(const struct vrt_ctx *ctx, const char *key,size_t lkey, const char *msg,size_t lmsg,bool raw) { hashid hash = MHASH_SHA256; size_t blocksize = mhash_get_block_size(hash); char *p; char *ptmp; p = WS_Alloc(ctx->ws, blocksize * 2 + 1); ptmp = p; unsigned char *mac; unsigned u; u = WS_Reserve(ctx->ws, 0); assert(u > blocksize); mac = (unsigned char*)ctx->ws->f; int i; MHASH td; assert(msg); assert(key); assert(mhash_get_hash_pblock(hash) > 0); td = mhash_hmac_init(hash, (void *) key, lkey, mhash_get_hash_pblock(hash)); mhash(td, msg, lmsg); mhash_hmac_deinit(td,mac); if(raw){ WS_Release(ctx->ws, blocksize); return (char *)mac; } WS_Release(ctx->ws, 0); for (i = 0; i<blocksize;i++) { sprintf(ptmp,"%.2x",mac[i]); ptmp+=2; } return p; }
char * VRT_IP_string(VRT_CTX, VCL_IP ip) { char *p; unsigned len; CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC); if (ip == NULL) return (NULL); len = WS_Reserve(ctx->ws, 0); if (len == 0) { WS_Release(ctx->ws, 0); return (NULL); } p = ctx->ws->f; VTCP_name(ip, p, len, NULL, 0); WS_Release(ctx->ws, strlen(p) + 1); return (p); }
static void WRW_Release(struct worker *wrk) { struct wrw *wrw; CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC); wrw = wrk->wrw; wrk->wrw = NULL; CHECK_OBJ_NOTNULL(wrw, WRW_MAGIC); WS_Release(wrk->aws, 0); WS_Reset(wrk->aws, NULL); }
vmod_transform(VRT_CTX, VCL_STRING s, VCL_INT options) { char *p; utf8proc_ssize_t len; unsigned u; CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC); if (!s) { VSLb(ctx->vsl, SLT_Error, "utf8.transform: No input"); return (NULL); } /* Use composed if not specified. */ if ((options & UTF8PROC_STRIPMARK) && (options & (UTF8PROC_COMPOSE | UTF8PROC_DECOMPOSE)) == 0) options |= UTF8PROC_COMPOSE; /* Input is NULL terminated. */ options |= UTF8PROC_NULLTERM; u = WS_Reserve(ctx->ws, 0); p = ctx->ws->f; len = utf8proc_decompose((utf8proc_uint8_t *)s, 0 /* IGNORED */, (utf8proc_int32_t *)p, u, options); if (len < 0) { VSLb(ctx->vsl, SLT_Error, "utf8.transform: utf8proc_decompose: %s", utf8proc_errmsg(len)); WS_Release(ctx->ws, 0); return (NULL); } len = utf8proc_reencode((utf8proc_int32_t *)p, len, options); assert(len > 0); assert(len < u); WS_Release(ctx->ws, len + 1); return (p); }
VCL_VOID vmod_req(VRT_CTX, VCL_STRING val) { //thread check if(ctx->req == NULL || ctx->req->magic != REQ_MAGIC){ VSLb(ctx->vsl, SLT_Error,"vmod-dump: dump.req work only at client-thread."); return; } //remote client local server //VRT_r_remote_ip //VRT_r_client_ip //VRT_r_local_ip //VRT_r_server_ip //VRT_IP_string(IP) ip->str //VSA_Port(IP) ip->port VSLb(ctx->vsl, SLT_Debug,"%s-I: %s %d %s %d", VMOD_DUMP_PRE, VRT_IP_string(ctx, VRT_r_client_ip(ctx)), VSA_Port(VRT_r_client_ip(ctx)), VRT_IP_string(ctx, VRT_r_server_ip(ctx)), VSA_Port(VRT_r_server_ip(ctx)) ); VSLb(ctx->vsl, SLT_Debug,"%s-S: REQ", VMOD_DUMP_PRE); VSLb(ctx->vsl, SLT_Debug,"%s-V: %s", VMOD_DUMP_PRE, val); unsigned u; //reserve work-space u = WS_Reserve(ctx->req->ws, 0); if(u <= VMOD_DUMP_KEY_LEN) { //no space. WS_Release(ctx->req->ws, 0); return; } work_head(ctx->req,ctx->req->ws->f, u, ctx->req->http0,HTTP1_Req); //free work-space WS_Release(ctx->req->ws, 0); VRB_Iterate(ctx->req, vbf_printRequestBody, NULL); VSLb(ctx->vsl, SLT_Debug,"%s-S: END", VMOD_DUMP_PRE); }
char * VRT_IP_string(const struct vrt_ctx *ctx, VCL_IP ip) { char *p; unsigned len; CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC); len = WS_Reserve(ctx->ws, 0); p = ctx->ws->f; VTCP_name(ip, p, len, NULL, 0); WS_Release(ctx->ws, strlen(p) + 1); return (p); }
vmod_urldecode(VRT_CTX, VCL_STRING s) { unsigned u, v; char *p; CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC); if (!s || !*s) { VSLb(ctx->vsl, SLT_Error, "vsf.urldecode: No input"); return (NULL); } u = WS_Reserve(ctx->ws, 0); p = ctx->ws->f; v = vsf_urldecode(p, s, u); if (v >= u) { VSLb(ctx->vsl, SLT_Error, "vsf.urldecode: Out of workspace"); WS_Release(ctx->ws, 0); return (NULL); } else { WS_Release(ctx->ws, v + 1); return (p); } }
void * WS_Printf(struct ws *ws, const char *fmt, ...) { unsigned u, v; va_list ap; char *p; WS_Assert(ws); assert(ws->r == NULL); u = WS_Reserve(ws, 0); p = ws->f; va_start(ap, fmt); v = vsnprintf(p, u, fmt, ap); va_end(ap); if (v >= u) { WS_Release(ws, 0); p = NULL; } else { WS_Release(ws, v + 1); } return (p); }
static void wrw_release(struct worker *wrk, uint64_t *pacc) { struct wrw *wrw; CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC); wrw = wrk->wrw; wrk->wrw = NULL; CHECK_OBJ_NOTNULL(wrw, WRW_MAGIC); if (pacc != NULL) *pacc += wrw->cnt; WS_Release(wrk->aws, 0); WS_Reset(wrk->aws, NULL); }
const char * vmod_id(struct sess *sp, const char *key, const int shards) { char *p; unsigned u, v; uint32_t hash[4]; uint32_t seed = 69; CHECK_OBJ_NOTNULL(sp, SESS_MAGIC); u = WS_Reserve(sp->wrk->ws, 0); /* Reserve some work space */ p = sp->wrk->ws->f; /* Front of workspace area */ MurmurHash3_x64_128(key, strlen(key), seed, hash); v = snprintf(p, u, "%d", hash[0] % shards); v++; if (v > u) { /* No space, reset and leave */ WS_Release(sp->wrk->ws, 0); return (NULL); } WS_Release(sp->wrk->ws, v); return (p); }
void http_PrintfHeader(struct http *to, const char *fmt, ...) { va_list ap; unsigned l, n; CHECK_OBJ_NOTNULL(to, HTTP_MAGIC); l = WS_Reserve(to->ws, 0); va_start(ap, fmt); n = vsnprintf(to->ws->f, l, fmt, ap); va_end(ap); if (n + 1 >= l || to->nhd >= to->shd) { VSC_C_main->losthdr++; VSLb(to->vsl, SLT_LostHeader, "%s", to->ws->f); WS_Release(to->ws, 0); } else { to->hd[to->nhd].b = to->ws->f; to->hd[to->nhd].e = to->ws->f + n; to->hdf[to->nhd] = 0; WS_Release(to->ws, n + 1); to->nhd++; } }
unsigned V1L_FlushRelease(struct worker *wrk) { struct v1l *v1l; unsigned u; CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC); u = V1L_Flush(wrk); v1l = wrk->v1l; wrk->v1l = NULL; CHECK_OBJ_NOTNULL(v1l, V1L_MAGIC); WS_Release(v1l->ws, 0); WS_Reset(v1l->ws, v1l->res); return (u); }
http1_unwait(struct worker *wrk, void *arg) { struct sess *sp; struct req *req; CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC); CAST_OBJ_NOTNULL(sp, arg, SESS_MAGIC); WS_Release(sp->ws, 0); req = Req_New(wrk, sp); CHECK_OBJ_NOTNULL(req, REQ_MAGIC); req->htc->rfd = &sp->fd; HTC_RxInit(req->htc, req->ws); http1_setstate(sp, H1NEWREQ); wrk->task.func = http1_req; wrk->task.priv = req; }
vmod_syslog(const struct vrt_ctx *ctx, VCL_INT fac, const char *fmt, ...) { char *p; unsigned u; va_list ap; CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC); u = WS_Reserve(ctx->ws, 0); p = ctx->ws->f; va_start(ap, fmt); p = VRT_StringList(p, u, fmt, ap); va_end(ap); if (p != NULL) syslog((int)fac, "%s", p); WS_Release(ctx->ws, 0); }
static void ses_reserve_attr(struct sess *sp, enum sess_attr a, void **dst, int sz) { ssize_t o; CHECK_OBJ_NOTNULL(sp, SESS_MAGIC); assert(a < SA_LAST); assert(sz >= 0); AN(dst); o = WS_Reserve(sp->ws, sz); assert(o >= sz); *dst = sp->ws->f; o = sp->ws->f - sp->ws->s; WS_Release(sp->ws, sz); assert(o >= 0 && o <= 0xffff); sp->sattr[a] = (uint16_t)o; }
static VCL_STRING tlv_string(VRT_CTX, int tlv) { char *dst, *d; int len; CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC); if (VPX_tlv(ctx->req, tlv, (void **)&dst, &len)) return (NULL); if (!WS_Reserve(ctx->ws, len+1)) return (NULL); d = ctx->ws->f; memcpy(d, dst, len); d[len] = '\0'; WS_Release(ctx->ws, len+1); return (d); }
void VRY_Finish(struct req *req, enum vry_finish_flag flg) { uint8_t *p = NULL; (void)VRY_Validate(req->vary_b); if (flg == KEEP && req->vary_l != NULL) { p = malloc(req->vary_l - req->vary_b); if (p != NULL) { memcpy(p, req->vary_b, req->vary_l - req->vary_b); (void)VRY_Validate(p); } } WS_Release(req->ws, 0); req->vary_l = NULL; req->vary_e = NULL; req->vary_b = p; }