static void start_connect_task_relay (CloneTask *task, GError **error) { CcnetPeer *peer = ccnet_get_peer (seaf->ccnetrpc_client, task->peer_id); if (!peer) { /* clone from a new relay */ GString *buf = NULL; seaf_message ("add relay before clone, %s:%s\n", task->peer_addr, task->peer_port); buf = g_string_new(NULL); g_string_append_printf (buf, "add-relay --id %s --addr %s:%s", task->peer_id, task->peer_addr, task->peer_port); ccnet_send_command (seaf->session, buf->str, NULL, NULL); transition_state (task, CLONE_STATE_CONNECT); g_string_free (buf, TRUE); } else { /* The peer is added to ccnet already and will be connected, * only need to transition the state */ transition_state (task, CLONE_STATE_CONNECT); } if (peer) g_object_unref (peer); }
gboolean ccnet_peer_is_ready (SearpcClient *client, const char *peer_id) { CcnetPeer *peer; gboolean ret; peer = ccnet_get_peer (client, peer_id); if (!peer) return FALSE; ret = peer->is_ready; g_object_unref (peer); return ret; }
int ccnet_get_peer_bind_status (SearpcClient *client, const char *peer_id) { CcnetPeer *peer; int ret; peer = ccnet_get_peer (client, peer_id); if (!peer) return BIND_UNKNOWN; ret = peer->bind_status; g_object_unref (peer); return ret; }
int ccnet_get_peer_net_state (SearpcClient *client, const char *peer_id) { CcnetPeer *peer; int ret; peer = ccnet_get_peer (client, peer_id); if (!peer) return PEER_DOWN; ret = peer->net_state; g_object_unref (peer); return ret; }
CcnetPeer * ccnet_get_default_relay (SearpcClient *client) { CcnetSessionBase *base = (CcnetSessionBase *) searpc_client_call__object( client, "get_session_info", CCNET_TYPE_SESSION_BASE, NULL, 0); if (!base) return NULL; CcnetPeer *relay = ccnet_get_peer (client, base->relay_id); g_object_unref (base); return relay; }
/* 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 v3] peer or peer session key not exist\n"); goto out; } EVP_BytesToKey (EVP_aes_128_cbc(), /* cipher mode */ EVP_sha1(), /* message digest */ NULL, /* slat */ (unsigned char*)peer->session_key, strlen(peer->session_key), 1, /* iteration times */ key, /* the derived key */ iv); /* IV, initial vector */ 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 v3] 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; }
/* In case ccnet relay info is lost(e.g. ~/ccnet is removed), we need to * re-add the relay by supplying addr:port */ static void add_relay_if_needed (SeafRepo *repo) { CcnetPeer *relay = NULL; char *relay_port = NULL, *relay_addr = NULL; GString *buf = NULL; seaf_repo_manager_get_repo_relay_info (seaf->repo_mgr, repo->id, &relay_addr, &relay_port); relay = ccnet_get_peer (seaf->ccnetrpc_client, repo->relay_id); if (relay) { /* no relay addr/port info in seafile db. This means we are * updating from an old version. */ if (!relay_addr || !relay_port) { if (relay->public_addr && relay->public_port) { char port[16]; snprintf (port, sizeof(port), "%d", relay->public_port); seaf_repo_manager_set_repo_relay_info (seaf->repo_mgr, repo->id, relay->public_addr, port); } } goto out; } /* relay info is lost in ccnet, but we have its addr:port in seafile.db */ if (relay_addr && relay_port) { buf = g_string_new(NULL); g_string_append_printf (buf, "add-relay --id %s --addr %s:%s", repo->relay_id, relay_addr, relay_port); } else { seaf_warning ("[sync mgr] relay addr/port info" " of repo %.10s is unknown\n", repo->id); } if (buf) { ccnet_send_command (seaf->session, buf->str, NULL, NULL); } out: g_free (relay_addr); g_free (relay_port); if (relay) g_object_unref (relay); if (buf) g_string_free (buf, TRUE); }
/* 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 start (CcnetProcessor *processor, int argc, char **argv) { char *repo_id, *branch_name, *token; USE_PRIV; if (argc != 5) { ccnet_processor_send_response (processor, SC_BAD_ARGS, SS_BAD_ARGS, NULL, 0); ccnet_processor_done (processor, FALSE); return -1; } if (strcmp (argv[0], "upload") == 0) { priv->type = CHECK_TX_TYPE_UPLOAD; } else if (strcmp (argv[0], "download") == 0) { priv->type = CHECK_TX_TYPE_DOWNLOAD; } else { ccnet_processor_send_response (processor, SC_BAD_ARGS, SS_BAD_ARGS, NULL, 0); ccnet_processor_done (processor, FALSE); return -1; } int client_version = atoi(argv[1]); if (client_version == 4) { seaf_debug ("Client protocol version is 4, not supported.\n"); ccnet_processor_send_response (processor, SC_PROTOCOL_MISMATCH, SS_PROTOCOL_MISMATCH, NULL, 0); ccnet_processor_done (processor, FALSE); return -1; } repo_id = argv[2]; branch_name = argv[3]; token = argv[4]; if (strlen(repo_id) != 36) { ccnet_processor_send_response (processor, SC_BAD_ARGS, SS_BAD_ARGS, NULL, 0); ccnet_processor_done (processor, FALSE); return -1; } if (priv->type == CHECK_TX_TYPE_UPLOAD && strcmp (branch_name, "master") != 0) { ccnet_processor_send_response (processor, SC_BAD_ARGS, SS_BAD_ARGS, NULL, 0); ccnet_processor_done (processor, FALSE); return -1; } memcpy (priv->repo_id, repo_id, 37); priv->branch_name = g_strdup(branch_name); priv->token = g_strdup(token); CcnetPeer *peer = ccnet_get_peer (seaf->ccnetrpc_client, processor->peer_id); if (!peer || !peer->session_key) { seaf_warning ("[check tx slave v3] session key of peer %.10s is null\n", processor->peer_id); ccnet_processor_send_response (processor, SC_BAD_PEER, SS_BAD_PEER, NULL, 0); ccnet_processor_done (processor, FALSE); if (peer) g_object_unref (peer); return -1; } priv->session_key = g_strdup(peer->session_key); priv->peer_addr = g_strdup(peer->addr_str); priv->peer_name = g_strdup(peer->name); if (!priv->peer_name) priv->peer_name = g_strdup("Unknown"); g_object_unref (peer); seaf_debug ("[check-tx] %s repo %.8s.\n", argv[0], repo_id); ccnet_processor_thread_create (processor, seaf->job_mgr, check_tx, thread_done, processor); return 0; }