diff options
-rw-r--r-- | src/setup/gnunet-setup-gns-edit.h | 17 | ||||
-rw-r--r-- | src/setup/gnunet-setup-gns.c | 191 |
2 files changed, 183 insertions, 25 deletions
diff --git a/src/setup/gnunet-setup-gns-edit.h b/src/setup/gnunet-setup-gns-edit.h index 9a305560..c6fc1fad 100644 --- a/src/setup/gnunet-setup-gns-edit.h +++ b/src/setup/gnunet-setup-gns-edit.h | |||
@@ -95,6 +95,18 @@ struct EditDialogContext | |||
95 | GtkDialog *dialog; | 95 | GtkDialog *dialog; |
96 | 96 | ||
97 | /** | 97 | /** |
98 | * Context for loading/generating the zone key for the target zone | ||
99 | * (used if the edit operation causes the record to be moved). | ||
100 | */ | ||
101 | struct GNUNET_CRYPTO_RsaKeyGenerationContext *rkgc; | ||
102 | |||
103 | /** | ||
104 | * Associated namestore operation. | ||
105 | * (used if the edit operation causes the record to be moved). | ||
106 | */ | ||
107 | struct GNUNET_NAMESTORE_QueueEntry *qe; | ||
108 | |||
109 | /** | ||
98 | * Old name of the record (for deletion). | 110 | * Old name of the record (for deletion). |
99 | */ | 111 | */ |
100 | gchar *n_name; | 112 | gchar *n_name; |
@@ -120,6 +132,11 @@ struct EditDialogContext | |||
120 | int old_record_in_namestore; | 132 | int old_record_in_namestore; |
121 | 133 | ||
122 | /** | 134 | /** |
135 | * Type of the record. | ||
136 | */ | ||
137 | uint32_t record_type; | ||
138 | |||
139 | /** | ||
123 | * Is this record 'public'? | 140 | * Is this record 'public'? |
124 | */ | 141 | */ |
125 | gboolean n_public; | 142 | gboolean n_public; |
diff --git a/src/setup/gnunet-setup-gns.c b/src/setup/gnunet-setup-gns.c index 8f14edf4..95ca617b 100644 --- a/src/setup/gnunet-setup-gns.c +++ b/src/setup/gnunet-setup-gns.c | |||
@@ -845,6 +845,7 @@ check_name_validity_and_commit (GtkTreeIter *it, | |||
845 | gchar *n_name; | 845 | gchar *n_name; |
846 | gint n_type; | 846 | gint n_type; |
847 | gboolean n_public; | 847 | gboolean n_public; |
848 | gboolean n_is_shadow; | ||
848 | guint64 n_exp_time; | 849 | guint64 n_exp_time; |
849 | gboolean n_is_relative; | 850 | gboolean n_is_relative; |
850 | gchar *n_value; | 851 | gchar *n_value; |
@@ -857,6 +858,7 @@ check_name_validity_and_commit (GtkTreeIter *it, | |||
857 | GNS_TREESTORE_COL_IS_PUBLIC, &n_public, | 858 | GNS_TREESTORE_COL_IS_PUBLIC, &n_public, |
858 | GNS_TREESTORE_COL_EXP_TIME, &n_exp_time, | 859 | GNS_TREESTORE_COL_EXP_TIME, &n_exp_time, |
859 | GNS_TREESTORE_COL_EXP_TIME_IS_REL, &n_is_relative, | 860 | GNS_TREESTORE_COL_EXP_TIME_IS_REL, &n_is_relative, |
861 | GNS_TREESTORE_COL_IS_SHADOW, &n_is_shadow, | ||
860 | GNS_TREESTORE_COL_VAL_AS_STR, &n_value, | 862 | GNS_TREESTORE_COL_VAL_AS_STR, &n_value, |
861 | -1); | 863 | -1); |
862 | if ( (NULL == n_name) || | 864 | if ( (NULL == n_name) || |
@@ -880,6 +882,8 @@ check_name_validity_and_commit (GtkTreeIter *it, | |||
880 | rd[c].flags = GNUNET_NAMESTORE_RF_AUTHORITY; | 882 | rd[c].flags = GNUNET_NAMESTORE_RF_AUTHORITY; |
881 | else | 883 | else |
882 | rd[c].flags = GNUNET_NAMESTORE_RF_AUTHORITY | GNUNET_NAMESTORE_RF_PRIVATE; | 884 | rd[c].flags = GNUNET_NAMESTORE_RF_AUTHORITY | GNUNET_NAMESTORE_RF_PRIVATE; |
885 | if (n_is_shadow) | ||
886 | rd[c].flags |= GNUNET_NAMESTORE_RF_SHADOW_RECORD; | ||
883 | rd[c].record_type = n_type; | 887 | rd[c].record_type = n_type; |
884 | rd[c].expiration_time = n_exp_time; | 888 | rd[c].expiration_time = n_exp_time; |
885 | if (n_is_relative) | 889 | if (n_is_relative) |
@@ -1038,6 +1042,7 @@ remove_records_by_path (const gchar *path) | |||
1038 | gboolean n_public; | 1042 | gboolean n_public; |
1039 | guint64 n_exp_time; | 1043 | guint64 n_exp_time; |
1040 | gboolean n_is_relative; | 1044 | gboolean n_is_relative; |
1045 | gboolean n_is_shadow; | ||
1041 | char *n_value; | 1046 | char *n_value; |
1042 | 1047 | ||
1043 | gtk_tree_model_get_iter_from_string (tm, &it, path); | 1048 | gtk_tree_model_get_iter_from_string (tm, &it, path); |
@@ -1055,6 +1060,7 @@ remove_records_by_path (const gchar *path) | |||
1055 | GNS_TREESTORE_COL_IS_PUBLIC, &n_public, | 1060 | GNS_TREESTORE_COL_IS_PUBLIC, &n_public, |
1056 | GNS_TREESTORE_COL_EXP_TIME, &n_exp_time, | 1061 | GNS_TREESTORE_COL_EXP_TIME, &n_exp_time, |
1057 | GNS_TREESTORE_COL_EXP_TIME_IS_REL, &n_is_relative, | 1062 | GNS_TREESTORE_COL_EXP_TIME_IS_REL, &n_is_relative, |
1063 | GNS_TREESTORE_COL_IS_SHADOW, &n_is_shadow, | ||
1058 | GNS_TREESTORE_COL_VAL_AS_STR, &n_value, | 1064 | GNS_TREESTORE_COL_VAL_AS_STR, &n_value, |
1059 | -1); | 1065 | -1); |
1060 | 1066 | ||
@@ -1065,6 +1071,8 @@ remove_records_by_path (const gchar *path) | |||
1065 | rd.flags = GNUNET_NAMESTORE_RF_AUTHORITY | GNUNET_NAMESTORE_RF_PRIVATE; | 1071 | rd.flags = GNUNET_NAMESTORE_RF_AUTHORITY | GNUNET_NAMESTORE_RF_PRIVATE; |
1066 | if (n_is_relative) | 1072 | if (n_is_relative) |
1067 | rd.flags |= GNUNET_NAMESTORE_RF_RELATIVE_EXPIRATION; | 1073 | rd.flags |= GNUNET_NAMESTORE_RF_RELATIVE_EXPIRATION; |
1074 | if (n_is_shadow) | ||
1075 | rd.flags |= GNUNET_NAMESTORE_RF_SHADOW_RECORD; | ||
1068 | rd.record_type = n_type; | 1076 | rd.record_type = n_type; |
1069 | rd.expiration_time = n_exp_time; | 1077 | rd.expiration_time = n_exp_time; |
1070 | GNUNET_NAMESTORE_string_to_value (n_type, n_value, | 1078 | GNUNET_NAMESTORE_string_to_value (n_type, n_value, |
@@ -1121,6 +1129,100 @@ exp_time_to_string (gboolean is_relative, | |||
1121 | 1129 | ||
1122 | 1130 | ||
1123 | /** | 1131 | /** |
1132 | * Release resources of an edit dialog context. | ||
1133 | * | ||
1134 | * @param edc resources to free | ||
1135 | */ | ||
1136 | static void | ||
1137 | free_edit_dialog_context (struct EditDialogContext *edc) | ||
1138 | { | ||
1139 | g_free (edc->n_name); | ||
1140 | g_free (edc->n_new_name); | ||
1141 | g_free (edc->n_value); | ||
1142 | g_free (edc->new_zone_option); | ||
1143 | GNUNET_free (edc); | ||
1144 | } | ||
1145 | |||
1146 | |||
1147 | /** | ||
1148 | * Function called upon completion of a 'move' operation. | ||
1149 | * | ||
1150 | * @param cls the 'struct EditDialogContext' of the operation that completed | ||
1151 | * @param success GNUNET_OK if the operation succeeded | ||
1152 | * @param emsg error message if the operation failed | ||
1153 | */ | ||
1154 | static void | ||
1155 | record_move_finish (void *cls, | ||
1156 | int32_t success, | ||
1157 | const char *emsg) | ||
1158 | { | ||
1159 | struct EditDialogContext *edc = cls; | ||
1160 | |||
1161 | edc->qe = NULL; | ||
1162 | if (NULL != emsg) | ||
1163 | show_error_message (_("Failed to move record to target zone"), | ||
1164 | emsg); | ||
1165 | free_edit_dialog_context (edc); | ||
1166 | } | ||
1167 | |||
1168 | |||
1169 | /** | ||
1170 | * Function called upon completion of 'GNUNET_CRYPTO_rsa_key_create_async'. | ||
1171 | * Displays an error message upon failure, otherwise stores the moved record | ||
1172 | * in the target zone. | ||
1173 | * | ||
1174 | * @param cls closure with the struct EditDialogContext; | ||
1175 | * @param pk NULL on error, otherwise the private key (which must be free'd by the callee) | ||
1176 | * @param emsg NULL on success, otherwise an error message | ||
1177 | */ | ||
1178 | static void | ||
1179 | record_move_continuation (void *cls, | ||
1180 | struct GNUNET_CRYPTO_RsaPrivateKey *pk, | ||
1181 | const char *emsg) | ||
1182 | { | ||
1183 | struct EditDialogContext *edc = cls; | ||
1184 | struct GNUNET_NAMESTORE_RecordData rd; | ||
1185 | void *data; | ||
1186 | size_t data_size; | ||
1187 | |||
1188 | edc->rkgc = NULL; | ||
1189 | if (NULL != emsg) | ||
1190 | { | ||
1191 | show_error_message (_("Failed to access key for target zone"), | ||
1192 | emsg); | ||
1193 | free_edit_dialog_context (edc); | ||
1194 | return; | ||
1195 | } | ||
1196 | if (GNUNET_OK != | ||
1197 | GNUNET_NAMESTORE_string_to_value (edc->record_type, | ||
1198 | edc->n_value, | ||
1199 | &data, | ||
1200 | &data_size)) | ||
1201 | { | ||
1202 | /* edit dialog produced invalid value string!? */ | ||
1203 | GNUNET_break (0); | ||
1204 | return; | ||
1205 | } | ||
1206 | rd.record_type = edc->record_type; | ||
1207 | rd.expiration_time = UINT64_MAX; | ||
1208 | if (edc->n_public) | ||
1209 | rd.flags = GNUNET_NAMESTORE_RF_AUTHORITY; | ||
1210 | else | ||
1211 | rd.flags = GNUNET_NAMESTORE_RF_AUTHORITY | GNUNET_NAMESTORE_RF_PRIVATE; | ||
1212 | if (edc->n_is_relative) | ||
1213 | rd.flags |= GNUNET_NAMESTORE_RF_RELATIVE_EXPIRATION; | ||
1214 | if (edc->n_is_shadow) | ||
1215 | rd.flags |= GNUNET_NAMESTORE_RF_SHADOW_RECORD; | ||
1216 | rd.data_size = data_size; | ||
1217 | rd.data = data; | ||
1218 | edc->qe = GNUNET_NAMESTORE_record_create (namestore, pk, | ||
1219 | edc->n_new_name, | ||
1220 | &rd, | ||
1221 | &record_move_finish, edc); | ||
1222 | } | ||
1223 | |||
1224 | |||
1225 | /** | ||
1124 | * The edit dialog completed; update the namestore and the | 1226 | * The edit dialog completed; update the namestore and the |
1125 | * view based on the new values in 'edc'. | 1227 | * view based on the new values in 'edc'. |
1126 | * | 1228 | * |
@@ -1134,8 +1236,6 @@ edit_dialog_continuation (struct EditDialogContext *edc, | |||
1134 | char *path; | 1236 | char *path; |
1135 | char *estr; | 1237 | char *estr; |
1136 | 1238 | ||
1137 | /* FIXME: logic to move records between zones is missing here! | ||
1138 | (#2473) */ | ||
1139 | switch (ret) | 1239 | switch (ret) |
1140 | { | 1240 | { |
1141 | case GTK_RESPONSE_REJECT: /* code for 'delete' */ | 1241 | case GTK_RESPONSE_REJECT: /* code for 'delete' */ |
@@ -1170,39 +1270,79 @@ edit_dialog_continuation (struct EditDialogContext *edc, | |||
1170 | break; | 1270 | break; |
1171 | case GTK_RESPONSE_OK: | 1271 | case GTK_RESPONSE_OK: |
1172 | /* update model */ | 1272 | /* update model */ |
1173 | estr = exp_time_to_string (edc->n_is_relative, | 1273 | if (0 == strcmp (edc->new_zone_option, |
1174 | edc->n_exp_time); | 1274 | current_zone_option)) |
1175 | gtk_tree_store_set (ts, &edc->it, | ||
1176 | GNS_TREESTORE_COL_NAME, edc->n_name, | ||
1177 | GNS_TREESTORE_COL_IS_PUBLIC, edc->n_public, | ||
1178 | GNS_TREESTORE_COL_EXP_TIME, edc->n_exp_time, | ||
1179 | GNS_TREESTORE_COL_EXP_TIME_IS_REL, edc->n_is_relative, | ||
1180 | GNS_TREESTORE_COL_EXP_TIME_AS_STR, estr, | ||
1181 | GNS_TREESTORE_COL_IS_SHADOW, edc->n_is_shadow, | ||
1182 | GNS_TREESTORE_COL_VAL_AS_STR, edc->n_value, | ||
1183 | GNS_TREESTORE_COL_VAL_COLOR, NULL, | ||
1184 | -1); | ||
1185 | GNUNET_free (estr); | ||
1186 | if (GNUNET_YES == edc->old_record_in_namestore) | ||
1187 | { | 1275 | { |
1188 | /* replace record in database with that from model */ | 1276 | /* zone stayed the same, update record in current model/zone */ |
1189 | check_name_validity_and_commit (&edc->it, edc->n_name); | 1277 | estr = exp_time_to_string (edc->n_is_relative, |
1278 | edc->n_exp_time); | ||
1279 | gtk_tree_store_set (ts, &edc->it, | ||
1280 | GNS_TREESTORE_COL_NAME, edc->n_name, | ||
1281 | GNS_TREESTORE_COL_IS_PUBLIC, edc->n_public, | ||
1282 | GNS_TREESTORE_COL_EXP_TIME, edc->n_exp_time, | ||
1283 | GNS_TREESTORE_COL_EXP_TIME_IS_REL, edc->n_is_relative, | ||
1284 | GNS_TREESTORE_COL_EXP_TIME_AS_STR, estr, | ||
1285 | GNS_TREESTORE_COL_IS_SHADOW, edc->n_is_shadow, | ||
1286 | GNS_TREESTORE_COL_VAL_AS_STR, edc->n_value, | ||
1287 | GNS_TREESTORE_COL_VAL_COLOR, NULL, | ||
1288 | -1); | ||
1289 | GNUNET_free (estr); | ||
1290 | if (GNUNET_YES == edc->old_record_in_namestore) | ||
1291 | { | ||
1292 | /* replace record in database with that from model */ | ||
1293 | check_name_validity_and_commit (&edc->it, edc->n_name); | ||
1294 | } | ||
1295 | else | ||
1296 | { | ||
1297 | /* add record in database based on model */ | ||
1298 | check_name_validity_and_commit (&edc->it, NULL); | ||
1299 | } | ||
1190 | } | 1300 | } |
1191 | else | 1301 | else |
1192 | { | 1302 | { |
1193 | /* add record in database based on model */ | 1303 | char *keyfile; |
1194 | check_name_validity_and_commit (&edc->it, NULL); | 1304 | |
1305 | /* zone changed, remove record from old zone, add to new zone! */ | ||
1306 | if (GNUNET_YES == edc->old_record_in_namestore) | ||
1307 | { | ||
1308 | /* remove item from tree view and namestore */ | ||
1309 | path = gtk_tree_model_get_string_from_iter (tm, &edc->it); | ||
1310 | remove_records_by_path (path); | ||
1311 | g_free (path); | ||
1312 | } | ||
1313 | else | ||
1314 | { | ||
1315 | /* remove item just from tree view, as it was not in the model */ | ||
1316 | gtk_tree_store_remove (ts, &edc->it); | ||
1317 | } | ||
1318 | |||
1319 | /* now add item to target zone */ | ||
1320 | if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_filename (cfg, | ||
1321 | "gns", | ||
1322 | edc->new_zone_option, | ||
1323 | &keyfile)) | ||
1324 | { | ||
1325 | char *emsg; | ||
1326 | |||
1327 | GNUNET_asprintf (&emsg, | ||
1328 | _("Option `%s' missing in section `%s'\n"), | ||
1329 | edc->new_zone_option, "gns"); | ||
1330 | show_error_message (_("Failed to access key for target zone"), | ||
1331 | emsg); | ||
1332 | GNUNET_free (emsg); | ||
1333 | } | ||
1334 | edc->rkgc = GNUNET_CRYPTO_rsa_key_create_start (keyfile, | ||
1335 | &record_move_continuation, | ||
1336 | edc); | ||
1337 | GNUNET_free (keyfile); | ||
1338 | return; | ||
1195 | } | 1339 | } |
1196 | break; | 1340 | break; |
1197 | default: | 1341 | default: |
1198 | GNUNET_break (0); | 1342 | GNUNET_break (0); |
1199 | break; | 1343 | break; |
1200 | } | 1344 | } |
1201 | g_free (edc->n_name); | 1345 | free_edit_dialog_context (edc); |
1202 | g_free (edc->n_new_name); | ||
1203 | g_free (edc->n_value); | ||
1204 | g_free (edc->new_zone_option); | ||
1205 | GNUNET_free (edc); | ||
1206 | } | 1346 | } |
1207 | 1347 | ||
1208 | 1348 | ||
@@ -1244,6 +1384,7 @@ edit_selected_row (int old_record_in_namestore) | |||
1244 | edc->new_zone_option = g_strdup (current_zone_option); | 1384 | edc->new_zone_option = g_strdup (current_zone_option); |
1245 | edc->n_new_name = g_strdup (edc->n_name); | 1385 | edc->n_new_name = g_strdup (edc->n_name); |
1246 | edc->cont = &edit_dialog_continuation; | 1386 | edc->cont = &edit_dialog_continuation; |
1387 | edc->record_type = n_type; | ||
1247 | switch (n_type) | 1388 | switch (n_type) |
1248 | { | 1389 | { |
1249 | case GNUNET_DNSPARSER_TYPE_A: | 1390 | case GNUNET_DNSPARSER_TYPE_A: |