void auth_request_handler_reply(struct auth_request *request, enum auth_client_result result, const void *auth_reply, size_t reply_size) { struct auth_request_handler *handler = request->handler; string_t *str; int ret; if (handler->destroyed) { /* the client connection was already closed. we can't do anything but abort this request */ request->internal_failure = TRUE; result = AUTH_CLIENT_RESULT_FAILURE; /* make sure this request is set to finished state (it's not with result=continue) */ auth_request_set_state(request, AUTH_REQUEST_STATE_FINISHED); } switch (result) { case AUTH_CLIENT_RESULT_CONTINUE: str = t_str_new(16 + MAX_BASE64_ENCODED_SIZE(reply_size)); str_printfa(str, "CONT\t%u\t", request->id); base64_encode(auth_reply, reply_size, str); request->accept_cont_input = TRUE; handler->callback(str_c(str), handler->context); break; case AUTH_CLIENT_RESULT_SUCCESS: if (reply_size > 0) { str = t_str_new(MAX_BASE64_ENCODED_SIZE(reply_size)); base64_encode(auth_reply, reply_size, str); auth_fields_add(request->extra_fields, "resp", str_c(str), 0); } ret = auth_request_proxy_finish(request, auth_request_handler_proxy_callback); if (ret < 0) auth_request_handler_reply_failure_finish(request); else if (ret > 0) auth_request_handler_reply_success_finish(request); else return; break; case AUTH_CLIENT_RESULT_FAILURE: auth_request_proxy_finish_failure(request); auth_request_handler_reply_failure_finish(request); break; } /* NOTE: request may be destroyed now */ auth_request_handler_unref(&handler); }
int cmd_login(struct imap_client *imap_client, const struct imap_arg *args) { struct client *client = &imap_client->common; const char *user, *pass; string_t *plain_login, *base64; /* two arguments: username and password */ if (!imap_arg_get_astring(&args[0], &user) || !imap_arg_get_astring(&args[1], &pass) || !IMAP_ARG_IS_EOL(&args[2])) return -1; if (!client_check_plaintext_auth(client, TRUE)) return 1; /* authorization ID \0 authentication ID \0 pass */ plain_login = buffer_create_dynamic(pool_datastack_create(), 64); buffer_append_c(plain_login, '\0'); buffer_append(plain_login, user, strlen(user)); buffer_append_c(plain_login, '\0'); buffer_append(plain_login, pass, strlen(pass)); base64 = buffer_create_dynamic(pool_datastack_create(), MAX_BASE64_ENCODED_SIZE(plain_login->used)); base64_encode(plain_login->data, plain_login->used, base64); return imap_client_auth_begin(imap_client, "PLAIN", str_c(base64)); }
bool cmd_x_state(struct client_command_context *cmd) { /* FIXME: state importing can cause unnecessarily large memory usage by specifying an old modseq, because the EXPUNGE/FETCH replies aren't currently sent asynchronously. so this command is disabled for now. */ #if 0 const struct imap_arg *args; const char *str, *error; buffer_t *state, *state_encoded; int ret; if (!client_read_args(cmd, 0, 0, &args)) return FALSE; state = buffer_create_dynamic(cmd->pool, 256); if (imap_arg_get_astring(&args[0], &str)) { if (cmd->client->mailbox != NULL) { client_send_tagline(cmd, "BAD Can't be used in SELECTED state"); return TRUE; } if (base64_decode(str, strlen(str), NULL, state) < 0) ret = 0; else { ret = imap_state_import_external(cmd->client, state->data, state->used, &error); } if (ret < 0) { client_send_tagline(cmd, t_strdup_printf( "NO Failed to restore state: %s", error)); } else if (ret == 0) { client_send_tagline(cmd, t_strdup_printf( "BAD Broken state: %s", error)); } else { client_send_tagline(cmd, "OK State imported."); } return TRUE; } else if (args[0].type == IMAP_ARG_EOL) { if (!imap_state_export_external(cmd->client, state, &error)) { client_send_tagline(cmd, t_strdup_printf( "NO Can't save state: %s", error)); return TRUE; } state_encoded = buffer_create_dynamic(cmd->pool, MAX_BASE64_ENCODED_SIZE(state->used)+10); str_append(state_encoded, "* STATE "); base64_encode(state->data, state->used, state_encoded); client_send_line(cmd->client, str_c(state_encoded)); client_send_tagline(cmd, "OK State exported."); return TRUE; } else { client_send_command_error(cmd, "Invalid arguments."); return TRUE; } #else client_send_command_error(cmd, "Command is disabled for now."); return TRUE; #endif }
bool password_generate_encoded(const char *plaintext, const struct password_generate_params *params, const char *scheme, const char **password_r) { const struct password_scheme *s; const unsigned char *raw_password; enum password_encoding encoding; string_t *str; size_t size; s = password_scheme_lookup(scheme, &encoding); if (s == NULL) return FALSE; s->password_generate(plaintext, params, &raw_password, &size); switch (encoding) { case PW_ENCODING_NONE: *password_r = t_strndup(raw_password, size); break; case PW_ENCODING_BASE64: str = t_str_new(MAX_BASE64_ENCODED_SIZE(size) + 1); base64_encode(raw_password, size, str); *password_r = str_c(str); break; case PW_ENCODING_HEX: *password_r = binary_to_hex(raw_password, size); break; } return TRUE; }
static string_t *get_digest_challenge(struct digest_auth_request *request) { const struct auth_settings *set = request->auth_request.set; buffer_t buf; string_t *str; const char *const *tmp; unsigned char nonce[16]; unsigned char nonce_base64[MAX_BASE64_ENCODED_SIZE(sizeof(nonce))+1]; int i; bool first_qop; /* realm="hostname" (multiple allowed) nonce="randomized data, at least 64bit" qop="auth,auth-int,auth-conf" maxbuf=number (with auth-int, auth-conf, defaults to 64k) charset="utf-8" (iso-8859-1 if it doesn't exist) algorithm="md5-sess" cipher="3des,des,rc4-40,rc4,rc4-56" (with auth-conf) */ /* get 128bit of random data as nonce */ random_fill(nonce, sizeof(nonce)); buffer_create_from_data(&buf, nonce_base64, sizeof(nonce_base64)); base64_encode(nonce, sizeof(nonce), &buf); buffer_append_c(&buf, '\0'); request->nonce = p_strdup(request->pool, buf.data); str = t_str_new(256); if (*set->realms_arr == NULL) { /* If no realms are given, at least Cyrus SASL client defaults to destination host name */ str_append(str, "realm=\"\","); } else { for (tmp = set->realms_arr; *tmp != NULL; tmp++) str_printfa(str, "realm=\"%s\",", *tmp); } str_printfa(str, "nonce=\"%s\",", request->nonce); str_append(str, "qop=\""); first_qop = TRUE; for (i = 0; i < QOP_COUNT; i++) { if (request->qop & (1 << i)) { if (first_qop) first_qop = FALSE; else str_append_c(str, ','); str_append(str, qop_names[i]); } } str_append(str, "\","); str_append(str, "charset=\"utf-8\"," "algorithm=\"md5-sess\""); return str; }
static const char * mail_storage_service_generate_session_id(pool_t pool, const char *prefix) { guid_128_t guid; unsigned int prefix_len = prefix == NULL ? 0 : strlen(prefix); string_t *str = str_new(pool, MAX_BASE64_ENCODED_SIZE(prefix_len + 1 + sizeof(guid))); if (prefix != NULL) str_printfa(str, "%s-", prefix); guid_128_generate(guid); base64_encode(guid, sizeof(guid), str); /* remove the trailing "==" */ i_assert(str_data(str)[str_len(str)-2] == '='); str_truncate(str, str_len(str)-2); return str_c(str); }