static void test_link_alloc2(void) { const char *o_tmpdir; /* try enough different sized base directory lengths so the code hits the different reallocations and tests for off-by-one errors */ string_t *basedir = t_str_new(256); str_append(basedir, cwd); str_append(basedir, "/"TEMP_DIRNAME); str_append_c(basedir, '/'); size_t base_len = str_len(basedir); o_tmpdir = tmpdir; /* path_normalize() initially allocates 128 bytes, so we'll test paths up to that length+1. */ unsigned char buf[128+1]; memset(buf, 'x', sizeof(buf)); for (size_t i = 1; i <= sizeof(buf); i++) { str_truncate(basedir, base_len); str_append_data(basedir, buf, i); tmpdir = str_c(basedir); (void)mkdir(str_c(basedir), 0700); create_links(tmpdir); test_link1(); test_link_loop(); } tmpdir = o_tmpdir; }
int http_parse_quoted_string(struct http_parser *parser, const char **str_r) { string_t *str; /* quoted-string = DQUOTE *( qdtext / quoted-pair ) DQUOTE qdtext = HTAB / SP / "!" / %x23-5B ; '#'-'[' / %x5D-7E ; ']'-'~' / obs-text quoted-pair = "\" ( HTAB / SP / VCHAR / obs-text ) obs-text = %x80-FF */ /* DQUOTE */ if (parser->cur >= parser->end || parser->cur[0] != '"') return 0; parser->cur++; /* *( qdtext / quoted-pair ) */ str = t_str_new(256); for (;;) { const unsigned char *first; /* *qdtext */ first = parser->cur; while (parser->cur < parser->end && http_char_is_qdtext(*parser->cur)) parser->cur++; if (parser->cur >= parser->end) return -1; str_append_data(str, first, parser->cur - first); /* DQUOTE */ if (*parser->cur == '"') { parser->cur++; break; /* "\" */ } else if (*parser->cur == '\\') { parser->cur++; if (parser->cur >= parser->end || !http_char_is_text(*parser->cur)) return -1; str_append_c(str, *parser->cur); parser->cur++; /* ERROR */ } else { return -1; } } *str_r = str_c(str); return 1; }
static int ocserv_conv(int msg_size, const struct pam_message **msg, struct pam_response **resp, void *uptr) { struct pam_ctx_st * pctx = uptr; unsigned i; if (msg_size == 0) return PAM_SUCCESS; pctx->replies = calloc(1, msg_size*sizeof(*pctx->replies)); if (pctx->replies == NULL) return PAM_BUF_ERR; for (i=0;i<msg_size;i++) { switch (msg[i]->msg_style) { case PAM_ERROR_MSG: case PAM_TEXT_INFO: syslog(LOG_DEBUG, "PAM-auth conv info: %s", msg[i]->msg); str_append_str(&pctx->msg, msg[i]->msg); str_append_data(&pctx->msg, " ", 1); pctx->sent_msg = 1; break; case PAM_PROMPT_ECHO_OFF: case PAM_PROMPT_ECHO_ON: if (pctx->sent_msg == 0) { /* no message, just asking for password */ str_reset(&pctx->msg); pctx->sent_msg = 1; } if (msg[i]->msg) { str_append_str(&pctx->msg, msg[i]->msg); } syslog(LOG_DEBUG, "PAM-auth conv: echo-%s, msg: '%s'", (msg[i]->msg_style==PAM_PROMPT_ECHO_ON)?"on":"off", msg[i]->msg!=NULL?msg[i]->msg:""); pctx->state = PAM_S_WAIT_FOR_PASS; pctx->cr_ret = PAM_SUCCESS; co_resume(); pctx->state = PAM_S_INIT; pctx->replies[i].resp = strdup(pctx->password); pctx->sent_msg = 0; break; } } *resp = pctx->replies; pctx->replies = NULL; return PAM_SUCCESS; }
static int pam_auth_msg(void* ctx, void *pool, passwd_msg_st *pst) { struct pam_ctx_st * pctx = ctx; size_t prompt_hash = 0; if (pctx->state != PAM_S_INIT && pctx->state != PAM_S_WAIT_FOR_PASS) { return 0; } if (pctx->state == PAM_S_INIT) { /* get the prompt */ pctx->cr_ret = PAM_CONV_ERR; co_call(pctx->cr); if (pctx->cr_ret != PAM_SUCCESS) { syslog(LOG_AUTH, "PAM-auth pam_auth_msg: %s", pam_strerror(pctx->ph, pctx->cr_ret)); return ERR_AUTH_FAIL; } } if (pctx->msg.length == 0) { if (pctx->changing) pst->msg_str = talloc_strdup(pool, "Please enter the new password."); /* else use the default prompt */ } else { if (str_append_data(&pctx->msg, "\0", 1) < 0) return -1; prompt_hash = hash_any(pctx->msg.data, pctx->msg.length, 0); pst->msg_str = talloc_strdup(pool, (char*)pctx->msg.data); } pst->counter = pctx->passwd_counter; /* differentiate password prompts, if the hash of the prompt * is different. */ if (pctx->prev_prompt_hash != prompt_hash) pctx->passwd_counter++; pctx->prev_prompt_hash = prompt_hash; return 0; }
int mbox_sync_parse_next_mail(struct istream *input, struct mbox_sync_mail_context *ctx) { struct mbox_sync_context *sync_ctx = ctx->sync_ctx; struct message_header_parser_ctx *hdr_ctx; struct message_header_line *hdr; struct mbox_sync_header_func *func; struct mbox_md5_context *mbox_md5_ctx; size_t line_start_pos; int i, ret; ctx->hdr_offset = ctx->mail.offset; ctx->mail.flags = MAIL_RECENT; /* default to having recent flag */ ctx->header_first_change = (size_t)-1; ctx->header_last_change = 0; for (i = 0; i < MBOX_HDR_COUNT; i++) ctx->hdr_pos[i] = (size_t)-1; ctx->content_length = (uoff_t)-1; str_truncate(ctx->header, 0); mbox_md5_ctx = ctx->sync_ctx->mbox->md5_v.init(); line_start_pos = 0; hdr_ctx = message_parse_header_init(input, NULL, 0); while ((ret = message_parse_header_next(hdr_ctx, &hdr)) > 0) { if (hdr->eoh) { ctx->have_eoh = TRUE; break; } if (!hdr->continued) { line_start_pos = str_len(ctx->header); str_append(ctx->header, hdr->name); str_append_data(ctx->header, hdr->middle, hdr->middle_len); } func = bsearch(hdr->name, header_funcs, N_ELEMENTS(header_funcs), sizeof(*header_funcs), mbox_sync_bsearch_header_func_cmp); if (func != NULL) { if (hdr->continues) { hdr->use_full_value = TRUE; continue; } if (!func->func(ctx, hdr)) { /* this header is broken, remove it */ ctx->need_rewrite = TRUE; str_truncate(ctx->header, line_start_pos); if (ctx->header_first_change == (size_t)-1) { ctx->header_first_change = line_start_pos; } continue; } buffer_append(ctx->header, hdr->full_value, hdr->full_value_len); } else { ctx->sync_ctx->mbox->md5_v.more(mbox_md5_ctx, hdr); buffer_append(ctx->header, hdr->value, hdr->value_len); } if (!hdr->no_newline) { if (hdr->crlf_newline) str_append_c(ctx->header, '\r'); str_append_c(ctx->header, '\n'); } } i_assert(ret != 0); message_parse_header_deinit(&hdr_ctx); ctx->sync_ctx->mbox->md5_v.finish(mbox_md5_ctx, ctx->hdr_md5_sum); if ((ctx->seq == 1 && !ctx->seen_imapbase) || (ctx->seq > 1 && sync_ctx->dest_first_mail)) { /* missing X-IMAPbase */ ctx->need_rewrite = TRUE; if (sync_ctx->base_uid_validity == 0) { /* figure out a new UIDVALIDITY for us. */ sync_ctx->base_uid_validity = sync_ctx->hdr->uid_validity != 0 && !sync_ctx->renumber_uids ? sync_ctx->hdr->uid_validity : I_MAX((uint32_t)ioloop_time, 1); } } ctx->body_offset = input->v_offset; if (input->stream_errno != 0) { mbox_sync_set_critical(ctx->sync_ctx, "read(%s) failed: %s", i_stream_get_name(input), i_stream_get_error(input)); return -1; } return 0; }
static bool parse_x_keywords_real(struct mbox_sync_mail_context *ctx, struct message_header_line *hdr) { struct mailbox *box = &ctx->sync_ctx->mbox->box; ARRAY_TYPE(keyword_indexes) keyword_list; const unsigned int *list; string_t *keyword; size_t keyword_start; unsigned int i, idx, count; size_t pos; if (array_is_created(&ctx->mail.keywords)) return FALSE; /* duplicate header, delete */ /* read keyword indexes to temporary array first */ keyword = t_str_new(128); t_array_init(&keyword_list, 16); for (pos = 0; pos < hdr->full_value_len; ) { if (IS_LWSP_LF(hdr->full_value[pos])) { pos++; continue; } /* read the keyword string */ keyword_start = pos; for (; pos < hdr->full_value_len; pos++) { if (IS_LWSP_LF(hdr->full_value[pos])) break; } str_truncate(keyword, 0); str_append_data(keyword, hdr->full_value + keyword_start, pos - keyword_start); if (!mail_index_keyword_lookup(box->index, str_c(keyword), &idx)) { /* keyword wasn't found. that means the sent mail originally contained X-Keywords header. Delete it. */ return FALSE; } /* check that the keyword isn't already added there. we don't want duplicates. */ list = array_get(&keyword_list, &count); for (i = 0; i < count; i++) { if (list[i] == idx) break; } if (i == count) array_append(&keyword_list, &idx, 1); } /* once we know how many keywords there are, we can allocate the array from mail_keyword_pool without wasting memory. */ if (array_count(&keyword_list) > 0) { p_array_init(&ctx->mail.keywords, ctx->sync_ctx->mail_keyword_pool, array_count(&keyword_list)); array_append_array(&ctx->mail.keywords, &keyword_list); } ctx->hdr_pos[MBOX_HDR_X_KEYWORDS] = str_len(ctx->header); parse_trailing_whitespace(ctx, hdr); return TRUE; }