static int make_key(struct buf *key, const duplicate_key_t *dkey) { if (!dkey || !dkey->id || !dkey->to || !dkey->date) return IMAP_INTERNAL; buf_reset(key); buf_appendmap(key, dkey->id, strlen(dkey->id)+1); buf_appendmap(key, dkey->to, strlen(dkey->to)+1); buf_appendmap(key, dkey->date, strlen(dkey->date)+1); /* We have three concatenated values now, all parts ending with '\0' */ return 0; }
static int denydb_foreach_cb(void *rock, const char *key, size_t keylen, const char *data, size_t datalen) { struct denydb_rock *dr = (struct denydb_rock *)rock; struct buf user = BUF_INITIALIZER; struct buf buf = BUF_INITIALIZER; char *wild = NULL; const char *msg = NULL; int r; /* ensure we have a nul-terminated user string */ buf_appendmap(&user, key, keylen); buf_cstring(&user); /* get fields from the record */ buf_init_ro(&buf, data, datalen); r = parse_record(&buf, &wild, &msg); if (r) { syslog(LOG_WARNING, "DENYDB_ERROR: invalid entry for '%s'", user.s); r = 0; /* whatever, keep going */ goto out; } r = dr->proc(user.s, wild, msg, dr->rock); out: buf_free(&user); buf_free(&buf); return r; }
EXPORTED char *jmapauth_tokenid(const struct jmapauth_token *tok) { struct buf buf = BUF_INITIALIZER; unsigned mdlen, hexlen; char macbuf[EVP_MAX_MD_SIZE]; char hexbuf[(JMAPAUTH_KEY_LEN + EVP_MAX_MD_SIZE)*2]; int r; /* Build the key */ r = make_key(&buf, tok); if (r) return NULL; /* Sign the extended key */ if (!(HMAC(EVP_sha1(), tok->secret, JMAPAUTH_SECRET_LEN, (unsigned char*) buf.s, buf.len, (unsigned char*) macbuf, &mdlen))) { buf_free(&buf); return NULL; } buf_appendmap(&buf, macbuf, mdlen); /* And return it hex-encoded */ hexlen = bin_to_hex(buf.s, buf.len, hexbuf, 0); if (hexlen != (mdlen + JMAPAUTH_KEY_LEN)*2) { buf_free(&buf); return NULL; } buf_free(&buf); return xstrndup(hexbuf, hexlen); }
static int make_key(struct buf *buf, const struct jmapauth_token *tok) { /* Concatenate version, kind and the session id */ buf_putc(buf, tok->version); buf_putc(buf, tok->kind); buf_appendmap(buf, tok->sessionid, JMAPAUTH_SESSIONID_LEN); return 0; }
static int _parseitem(struct dlistsax_state *s, struct buf *buf) { const char *sp; if (*s->p == '"') return _parseqstring(s, buf); else if (*s->p == '{') return _parseliteral(s, buf); sp = memchr(s->p, ' ', s->end - s->p); if (!sp) sp = s->end; while (sp[-1] == ')' && sp > s->p) sp--; /* this is much faster because it doesn't do a reset and check the MMAP flag */ buf->len = 0; buf_appendmap(buf, s->p, sp - s->p); s->p = sp; return 0; /* this could be the last thing, so end is OK */ }
static int build_notify_message(sieve_interp_t *i, const char *msg, void *message_context, struct buf *out) { const char *c; size_t n; if (msg == NULL) return SIEVE_OK; /* construct the message */ c = msg; while (*c) { /* expand variables */ if (!strncasecmp(c, "$from$", 6)) { add_header(i, 0 ,"From", message_context, out); c += 6; } else if (!strncasecmp(c, "$env-from$", 10)) { add_header(i, 1, "From", message_context, out); c += 10; } else if (!strncasecmp(c, "$subject$", 9)) { add_header(i, 0, "Subject", message_context, out); c += 9; } else if (i->getbody && !strncasecmp(c, "$text", 5) && (c[5] == '[' || c[5] == '$')) { const char *content_types[] = { "text", NULL }; sieve_bodypart_t **parts = NULL; c += 5; n = 0; if (*c++ == '[') { while (*c != ']') n = n * 10 + (*c++ - '0'); c += 2; /* skip ]$ */ } i->getbody(message_context, content_types, &parts); /* we only use the first text part */ if (parts && parts[0] && parts[0]->decoded_body) { size_t size = strlen(parts[0]->decoded_body); if (n && size > n) size = n; buf_appendmap(out, parts[0]->decoded_body, size); } /* free the results */ if (parts) { sieve_bodypart_t **p; for (p = parts; *p; p++) free(*p); free(parts); } } else { /* find length of plaintext up to next potential variable */ n = strcspn(c+1, "$") + 1; /* skip opening '$' */ buf_appendmap(out, c, n); c += n; } } buf_cstring(out); return SIEVE_OK; }
static void on_msg_recv_cb(wslay_event_context_ptr ev, const struct wslay_event_on_msg_recv_arg *arg, void *user_data) { struct transaction_t *txn = (struct transaction_t *) user_data; struct ws_context *ctx = (struct ws_context *) txn->ws_ctx; struct buf inbuf = BUF_INITIALIZER, outbuf = BUF_INITIALIZER; struct wslay_event_msg msgarg = { arg->opcode, NULL, 0 }; uint8_t rsv = WSLAY_RSV_NONE; double cmdtime, nettime; const char *err_msg; int r, err_code = 0; /* Place client request into a buf */ buf_init_ro(&inbuf, (const char *) arg->msg, arg->msg_length); /* Decompress request, if necessary */ if (wslay_get_rsv1(arg->rsv)) { /* Add trailing 4 bytes */ buf_appendmap(&inbuf, "\x00\x00\xff\xff", 4); r = zlib_decompress(txn, buf_base(&inbuf), buf_len(&inbuf)); if (r) { syslog(LOG_ERR, "on_msg_recv_cb(): zlib_decompress() failed"); err_code = WSLAY_CODE_PROTOCOL_ERROR; err_msg = DECOMP_FAILED_ERR; goto err; } buf_move(&inbuf, &txn->zbuf); } /* Log the uncompressed client request */ buf_truncate(&ctx->log, ctx->log_tail); buf_appendcstr(&ctx->log, " ("); if (txn->strm_ctx) { buf_printf(&ctx->log, "stream-id=%d; ", http2_get_streamid(txn->strm_ctx)); } buf_printf(&ctx->log, "opcode=%s; rsv=0x%x; length=%ld", wslay_str_opcode(arg->opcode), arg->rsv, arg->msg_length); switch (arg->opcode) { case WSLAY_CONNECTION_CLOSE: buf_printf(&ctx->log, "; status=%d; msg='%s'", arg->status_code, buf_len(&inbuf) ? buf_cstring(&inbuf)+2 : ""); txn->flags.conn = CONN_CLOSE; break; case WSLAY_TEXT_FRAME: case WSLAY_BINARY_FRAME: if (txn->conn->logfd != -1) { /* Telemetry logging */ struct iovec iov[2]; int niov = 0; assert(!buf_len(&txn->buf)); buf_printf(&txn->buf, "<%ld<", time(NULL)); /* timestamp */ WRITEV_ADD_TO_IOVEC(iov, niov, buf_base(&txn->buf), buf_len(&txn->buf)); WRITEV_ADD_TO_IOVEC(iov, niov, buf_base(&inbuf), buf_len(&inbuf)); writev(txn->conn->logfd, iov, niov); buf_reset(&txn->buf); } /* Process the request */ r = ctx->data_cb(&inbuf, &outbuf, &ctx->log, &ctx->cb_rock); if (r) { err_code = (r == HTTP_SERVER_ERROR ? WSLAY_CODE_INTERNAL_SERVER_ERROR : WSLAY_CODE_INVALID_FRAME_PAYLOAD_DATA); err_msg = error_message(r); goto err; } if (txn->conn->logfd != -1) { /* Telemetry logging */ struct iovec iov[2]; int niov = 0; assert(!buf_len(&txn->buf)); buf_printf(&txn->buf, ">%ld>", time(NULL)); /* timestamp */ WRITEV_ADD_TO_IOVEC(iov, niov, buf_base(&txn->buf), buf_len(&txn->buf)); WRITEV_ADD_TO_IOVEC(iov, niov, buf_base(&outbuf), buf_len(&outbuf)); writev(txn->conn->logfd, iov, niov); buf_reset(&txn->buf); } /* Compress the server response, if supported by the client */ if (ctx->ext & EXT_PMCE_DEFLATE) { r = zlib_compress(txn, ctx->pmce.deflate.no_context ? COMPRESS_START : 0, buf_base(&outbuf), buf_len(&outbuf)); if (r) { syslog(LOG_ERR, "on_msg_recv_cb(): zlib_compress() failed"); err_code = WSLAY_CODE_INTERNAL_SERVER_ERROR; err_msg = COMP_FAILED_ERR; goto err; } /* Trim the trailing 4 bytes */ buf_truncate(&txn->zbuf, buf_len(&txn->zbuf) - 4); buf_move(&outbuf, &txn->zbuf); rsv |= WSLAY_RSV1_BIT; } /* Queue the server response */ msgarg.msg = (const uint8_t *) buf_base(&outbuf); msgarg.msg_length = buf_len(&outbuf); wslay_event_queue_msg_ex(ev, &msgarg, rsv); /* Log the server response */ buf_printf(&ctx->log, ") => \"Success\" (opcode=%s; rsv=0x%x; length=%ld", wslay_str_opcode(msgarg.opcode), rsv, msgarg.msg_length); break; } err: if (err_code) { size_t err_msg_len = strlen(err_msg); syslog(LOG_DEBUG, "wslay_event_queue_close()"); wslay_event_queue_close(ev, err_code, (uint8_t *) err_msg, err_msg_len); /* Log the server response */ buf_printf(&ctx->log, ") => \"Fail\" (opcode=%s; rsv=0x%x; length=%ld" "; status=%d; msg='%s'", wslay_str_opcode(WSLAY_CONNECTION_CLOSE), rsv, err_msg_len, err_code, err_msg); } /* Add timing stats */ cmdtime_endtimer(&cmdtime, &nettime); buf_printf(&ctx->log, ") [timing: cmd=%f net=%f total=%f]", cmdtime, nettime, cmdtime + nettime); syslog(LOG_INFO, "%s", buf_cstring(&ctx->log)); buf_free(&inbuf); buf_free(&outbuf); }