int seaf_passwd_manager_set_passwd (SeafPasswdManager *mgr, const char *repo_id, const char *user, const char *passwd, GError **error) { SeafRepo *repo = seaf_repo_manager_get_repo (seaf->repo_mgr, repo_id); DecryptKey *crypt_key; GString *hash_key; if (!repo) { g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_BAD_ARGS, "Invalid repo"); return -1; } if (!repo->encrypted) { seaf_repo_unref (repo); g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_BAD_ARGS, "Repo is not encrypted"); return -1; } if (seaf_repo_verify_passwd (repo, passwd) < 0) { seaf_repo_unref (repo); g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_GENERAL, "Incorrect password"); return -1; } crypt_key = g_new0 (DecryptKey, 1); if (!crypt_key) { g_warning ("Failed to alloc crypt key struct.\n"); seaf_repo_unref (repo); g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_INTERNAL, "Internal server error"); return -1; } seafile_generate_enc_key (passwd, strlen(passwd), repo->enc_version, crypt_key->key, crypt_key->iv); crypt_key->passwd = g_strdup(passwd); crypt_key->expire_time = (guint64)time(NULL) + REAP_THRESHOLD; hash_key = g_string_new (NULL); g_string_printf (hash_key, "%s.%s", repo_id, user); /* g_debug ("[passwd mgr] Set passwd for %s\n", hash_key->str); */ g_hash_table_insert (mgr->priv->decrypt_keys, g_string_free (hash_key, FALSE), crypt_key); seaf_repo_unref (repo); return 0; }
static void start_checkout (SeafRepo *repo, CloneTask *task) { if (repo->encrypted && task->passwd != NULL) { /* keep this password check to be compatible with old servers. */ if (repo->enc_version >= 1 && seaf_repo_verify_passwd (repo->id, task->passwd, repo->magic) < 0) { seaf_warning ("[Clone mgr] incorrect password.\n"); transition_to_error (task, CLONE_ERROR_PASSWD); return; } if (seaf_repo_manager_set_repo_passwd (seaf->repo_mgr, repo, task->passwd) < 0) { seaf_warning ("[Clone mgr] failed to set passwd for %s.\n", repo->id); transition_to_error (task, CLONE_ERROR_INTERNAL); return; } } else if (repo->encrypted) { seaf_warning ("[Clone mgr] Password is empty for encrypted repo %s.\n", repo->id); transition_to_error (task, CLONE_ERROR_PASSWD); return; } if (g_access (task->worktree, F_OK) != 0 && g_mkdir_with_parents (task->worktree, 0777) < 0) { seaf_warning ("[clone mgr] Failed to create worktree %s.\n", task->worktree); transition_to_error (task, CLONE_ERROR_CHECKOUT); return; } if (!is_non_empty_directory (task->worktree)) { transition_state (task, CLONE_STATE_CHECKOUT); seaf_repo_manager_add_checkout_task (seaf->repo_mgr, repo, task->worktree, on_checkout_done, task->manager); } else { MergeAux *aux = g_new0 (MergeAux, 1); aux->task = task; aux->repo = repo; transition_state (task, CLONE_STATE_MERGE); ccnet_job_manager_schedule_job (seaf->job_mgr, merge_job, merge_job_done, aux); } }
char * seaf_clone_manager_add_download_task (SeafCloneManager *mgr, const char *repo_id, const char *peer_id, const char *repo_name, const char *token, const char *passwd, const char *magic, const char *wt_parent, const char *peer_addr, const char *peer_port, const char *email, GError **error) { SeafRepo *repo; char *wt_tmp, *worktree; char *ret; if (!seaf->started) { seaf_message ("System not started, skip adding clone task.\n"); return NULL; } g_assert (strlen(repo_id) == 36); repo = seaf_repo_manager_get_repo (seaf->repo_mgr, repo_id); if (repo != NULL && repo->head != NULL) { g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_GENERAL, "Repo already exists"); return NULL; } if (is_duplicate_task (mgr, repo_id)) { g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_GENERAL, "Task is already in progress"); return NULL; } /* If magic is not given, check password before checkout. */ if (passwd && magic && seaf_repo_verify_passwd(repo_id, passwd, magic) < 0) { g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_GENERAL, "Incorrect password"); return NULL; } wt_tmp = g_build_filename (wt_parent, repo_name, NULL); worktree = make_worktree_for_download (mgr, wt_tmp, error); if (!worktree) { g_free (wt_tmp); return NULL; } ret = add_task_common (mgr, repo, repo_id, peer_id, repo_name, token, passwd, worktree, peer_addr, peer_port, email, error); g_free (worktree); g_free (wt_tmp); return ret; }