Beispiel #1
0
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;
}
Beispiel #2
0
/* token -> AES encrypt with session key -> rawdata_to_hex -> output  */
static char *
encrypt_token (CcnetProcessor *processor, const char *token)
{
    CcnetPeer *peer = NULL;
    char *enc_out = NULL;
    SeafileCrypt *crypt = NULL;
    unsigned char key[16], iv[16];
    int len;
    char *output = NULL;

    if (!token)
        goto out;

    peer = ccnet_get_peer(seaf->ccnetrpc_client, processor->peer_id);
    if (!peer || !peer->session_key) {
        seaf_warning ("[check tx v2] peer or peer session key not exist\n");
        goto out;
    }

    seafile_generate_enc_key (peer->session_key,
                              strlen(peer->session_key),
                              CURRENT_ENC_VERSION, key, iv);

    crypt = seafile_crypt_new (CURRENT_ENC_VERSION, key, iv);

    /* encrypt the token with session key, including the trailing null byte */
    if (seafile_encrypt (&enc_out, &len, token, strlen(token) + 1, crypt) < 0) {
        seaf_warning ("[check tx v2] failed to encrypt token\n");
        goto out;
    }

    output = g_malloc (len * 2 + 1);
    rawdata_to_hex ((unsigned char *)enc_out, output, len);
    output[len * 2] = '\0';


out:
    g_free (crypt);
    g_free (enc_out);
    if (peer)
        g_object_unref(peer);

    return output;
}
static int
decrypt_token (CcnetProcessor *processor)
{
    USE_PRIV;
    int hex_len, encrypted_len, token_len; 
    char *encrypted_token = NULL;
    SeafileCrypt *crypt = NULL;
    unsigned char key[16], iv[16];
    char *token = NULL;
    int ret = 0;

    /* raw data is half the length of hexidecimal */
    hex_len = strlen(priv->token);
    if (hex_len % 2 != 0) {
        seaf_warning ("[check tx slave v2] invalid length of encrypted token\n"); 
        ret = -1;
        goto out;
    }

    token = seaf_repo_manager_get_decrypted_token (seaf->repo_mgr,
                                                   priv->token,
                                                   priv->session_key);
    if (token)
        goto found;
    
    encrypted_len = hex_len / 2;
    encrypted_token = g_malloc (encrypted_len);
    hex_to_rawdata (priv->token,
                    (unsigned char *)encrypted_token,
                    encrypted_len);

    seafile_generate_enc_key (priv->session_key,
                              strlen(priv->session_key),
                              CURRENT_ENC_VERSION, key, iv);
    crypt = seafile_crypt_new (CURRENT_ENC_VERSION, key, iv);
    
    if (seafile_decrypt (&token, &token_len, encrypted_token,
                         encrypted_len, crypt) < 0) {
        seaf_warning ("[check tx slave v2] failed to decrypt token\n");
        ret = -1;
        goto out;
    }

    /* Add to cache. */
    seaf_repo_manager_add_decrypted_token (seaf->repo_mgr,
                                           priv->token,
                                           priv->session_key,
                                           token);

found:
    g_free (priv->token);
    /* we can use the decrypted data directly, since the trailing null byte is
     * also included when encrypting in the client */
    priv->token = token;

out:
    g_free (crypt);
    g_free (encrypted_token);
    
    return ret;
}