static void hash_format_digest(string_t *dest, const struct hash_format_list *list, const unsigned char *digest) { unsigned int i, orig_len, size = list->bits / 8; i_assert(list->bits % 8 == 0); switch (list->encoding) { case HASH_ENCODING_HEX: binary_to_hex_append(dest, digest, size); break; case HASH_ENCODING_HEX_SHORT: orig_len = str_len(dest); binary_to_hex_append(dest, digest, size); /* drop leading zeros, except if it's the only one */ for (i = orig_len; i < str_len(dest); i++) { if (str_data(dest)[i] != '0') break; } if (i == str_len(dest)) i--; str_delete(dest, orig_len, i-orig_len); break; case HASH_ENCODING_BASE64: orig_len = str_len(dest); base64_encode(digest, size, dest); /* drop trailing '=' chars */ while (str_len(dest) > orig_len && str_data(dest)[str_len(dest)-1] == '=') str_truncate(dest, str_len(dest)-1); break; } }
static bool auth_worker_verify_db_hash(const char *line) { string_t *str; unsigned char passdb_md5[MD5_RESULTLEN]; unsigned char userdb_md5[MD5_RESULTLEN]; passdbs_generate_md5(passdb_md5); userdbs_generate_md5(userdb_md5); str = t_str_new(128); str_append(str, "DBHASH\t"); binary_to_hex_append(str, passdb_md5, sizeof(passdb_md5)); str_append_c(str, '\t'); binary_to_hex_append(str, userdb_md5, sizeof(userdb_md5)); return strcmp(line, str_c(str)) == 0; }
void auth_client_connection_create(struct auth *auth, int fd, bool login_requests, bool token_auth) { static unsigned int connect_uid_counter = 0; struct auth_client_connection *conn; const char *mechanisms; string_t *str; conn = i_new(struct auth_client_connection, 1); conn->auth = auth; conn->refcount = 1; conn->connect_uid = ++connect_uid_counter; conn->login_requests = login_requests; conn->token_auth = token_auth; random_fill(conn->cookie, sizeof(conn->cookie)); conn->fd = fd; conn->input = i_stream_create_fd(fd, AUTH_CLIENT_MAX_LINE_LENGTH); conn->output = o_stream_create_fd(fd, (size_t)-1); o_stream_set_no_error_handling(conn->output, TRUE); o_stream_set_flush_callback(conn->output, auth_client_output, conn); conn->io = io_add(fd, IO_READ, auth_client_input, conn); DLLIST_PREPEND(&auth_client_connections, conn); if (token_auth) { mechanisms = t_strconcat("MECH\t", mech_dovecot_token.mech_name, "\n", NULL); } else { mechanisms = str_c(auth->reg->handshake); } str = t_str_new(128); str_printfa(str, "VERSION\t%u\t%u\n%sSPID\t%s\nCUID\t%u\nCOOKIE\t", AUTH_CLIENT_PROTOCOL_MAJOR_VERSION, AUTH_CLIENT_PROTOCOL_MINOR_VERSION, mechanisms, my_pid, conn->connect_uid); binary_to_hex_append(str, conn->cookie, sizeof(conn->cookie)); str_append(str, "\nDONE\n"); if (o_stream_send(conn->output, str_data(str), str_len(str)) < 0) auth_client_disconnected(&conn); }
static void test_binary_to_hex(void) { static unsigned char input[] = { 0xff, 0x00, 0x01, 0xb3 }; static char *output_lcase = "ff0001b3"; static char *output_ucase = "FF0001B3"; string_t *str; test_begin("binary to hex"); test_assert(strcmp(binary_to_hex(input, sizeof(input)), output_lcase) == 0); test_end(); test_begin("binary to hex ucase"); test_assert(strcmp(binary_to_hex_ucase(input, sizeof(input)), output_ucase) == 0); test_end(); test_begin("binary to hex ucase"); str = t_str_new(32); str_append_c(str, '<'); binary_to_hex_append(str, input, sizeof(input)); str_append_c(str, '>'); test_assert(strcmp(str_c(str), t_strconcat("<", output_lcase, ">", NULL)) == 0); test_end(); }
static void master_login_auth_send_request(struct master_login_auth *auth, struct master_login_auth_request *req) { string_t *str; if (!auth_request_check_spid(auth, req)) { master_login_auth_request_remove(auth, req); req->callback(NULL, MASTER_AUTH_ERRMSG_INTERNAL_FAILURE, req->context); i_free(req); return; } str = t_str_new(128); str_printfa(str, "REQUEST\t%u\t%u\t%u\t", req->id, req->client_pid, req->auth_id); binary_to_hex_append(str, req->cookie, sizeof(req->cookie)); str_printfa(str, "\tsession_pid=%s", my_pid); if (auth->request_auth_token) str_append(str, "\trequest_auth_token"); str_append_c(str, '\n'); o_stream_nsend(auth->output, str_data(str), str_len(str)); }