diff options
Diffstat (limited to 'src/regex/plugin_block_regex.c')
-rw-r--r-- | src/regex/plugin_block_regex.c | 228 |
1 files changed, 223 insertions, 5 deletions
diff --git a/src/regex/plugin_block_regex.c b/src/regex/plugin_block_regex.c index ad897493f..0953830ab 100644 --- a/src/regex/plugin_block_regex.c +++ b/src/regex/plugin_block_regex.c | |||
@@ -329,6 +329,222 @@ block_plugin_regex_evaluate (void *cls, | |||
329 | 329 | ||
330 | 330 | ||
331 | /** | 331 | /** |
332 | * Function called to validate a query. | ||
333 | * | ||
334 | * @param cls closure | ||
335 | * @param ctx block context | ||
336 | * @param type block type | ||
337 | * @param query original query (hash) | ||
338 | * @param xquery extrended query data (can be NULL, depending on type) | ||
339 | * @param xquery_size number of bytes in @a xquery | ||
340 | * @return #GNUNET_OK if the query is fine, #GNUNET_NO if not | ||
341 | */ | ||
342 | static enum GNUNET_GenericReturnValue | ||
343 | block_plugin_regex_check_query (void *cls, | ||
344 | enum GNUNET_BLOCK_Type type, | ||
345 | const struct GNUNET_HashCode *query, | ||
346 | const void *xquery, | ||
347 | size_t xquery_size) | ||
348 | { | ||
349 | switch (type) | ||
350 | { | ||
351 | case GNUNET_BLOCK_TYPE_REGEX: | ||
352 | if (0 != xquery_size) | ||
353 | { | ||
354 | const char *s; | ||
355 | |||
356 | s = (const char *) xquery; | ||
357 | if ('\0' != s[xquery_size - 1]) /* must be valid 0-terminated string */ | ||
358 | { | ||
359 | GNUNET_break_op (0); | ||
360 | return GNUNET_NO; | ||
361 | } | ||
362 | } | ||
363 | return GNUNET_OK; | ||
364 | case GNUNET_BLOCK_TYPE_REGEX_ACCEPT: | ||
365 | if (0 != xquery_size) | ||
366 | { | ||
367 | GNUNET_break_op (0); | ||
368 | return GNUNET_NO; | ||
369 | } | ||
370 | return GNUNET_OK; | ||
371 | default: | ||
372 | GNUNET_break (0); | ||
373 | return GNUNET_SYSERR; | ||
374 | } | ||
375 | } | ||
376 | |||
377 | |||
378 | /** | ||
379 | * Function called to validate a block for storage. | ||
380 | * | ||
381 | * @param cls closure | ||
382 | * @param type block type | ||
383 | * @param query key for the block (hash), must match exactly | ||
384 | * @param block block data to validate | ||
385 | * @param block_size number of bytes in @a block | ||
386 | * @return #GNUNET_OK if the block is fine, #GNUNET_NO if not | ||
387 | */ | ||
388 | static enum GNUNET_GenericReturnValue | ||
389 | block_plugin_regex_check_block (void *cls, | ||
390 | enum GNUNET_BLOCK_Type type, | ||
391 | const struct GNUNET_HashCode *query, | ||
392 | const void *block, | ||
393 | size_t block_size) | ||
394 | { | ||
395 | switch (type) | ||
396 | { | ||
397 | case GNUNET_BLOCK_TYPE_REGEX: | ||
398 | if (GNUNET_SYSERR == | ||
399 | REGEX_BLOCK_check (block, | ||
400 | block_size, | ||
401 | query, | ||
402 | NULL)) | ||
403 | return GNUNET_NO; | ||
404 | return GNUNET_OK; | ||
405 | case GNUNET_BLOCK_TYPE_REGEX_ACCEPT: | ||
406 | { | ||
407 | const struct RegexAcceptBlock *rba; | ||
408 | |||
409 | if (sizeof(struct RegexAcceptBlock) != block_size) | ||
410 | { | ||
411 | GNUNET_break_op (0); | ||
412 | return GNUNET_NO; | ||
413 | } | ||
414 | rba = block; | ||
415 | if (ntohl (rba->purpose.size) != | ||
416 | sizeof(struct GNUNET_CRYPTO_EccSignaturePurpose) | ||
417 | + sizeof(struct GNUNET_TIME_AbsoluteNBO) | ||
418 | + sizeof(struct GNUNET_HashCode)) | ||
419 | { | ||
420 | GNUNET_break_op (0); | ||
421 | return GNUNET_NO; | ||
422 | } | ||
423 | if (GNUNET_TIME_absolute_is_past (GNUNET_TIME_absolute_ntoh ( | ||
424 | rba->expiration_time))) | ||
425 | { | ||
426 | return GNUNET_NO; | ||
427 | } | ||
428 | if (GNUNET_OK != | ||
429 | GNUNET_CRYPTO_eddsa_verify_ (GNUNET_SIGNATURE_PURPOSE_REGEX_ACCEPT, | ||
430 | &rba->purpose, | ||
431 | &rba->signature, | ||
432 | &rba->peer.public_key)) | ||
433 | { | ||
434 | GNUNET_break_op (0); | ||
435 | return GNUNET_NO; | ||
436 | } | ||
437 | return GNUNET_OK; | ||
438 | } | ||
439 | default: | ||
440 | GNUNET_break (0); | ||
441 | return GNUNET_SYSERR; | ||
442 | } | ||
443 | } | ||
444 | |||
445 | |||
446 | /** | ||
447 | * Function called to validate a reply to a request. Note that it is assumed | ||
448 | * that the reply has already been matched to the key (and signatures checked) | ||
449 | * as it would be done with the GetKeyFunction and the | ||
450 | * BlockEvaluationFunction. | ||
451 | * | ||
452 | * @param cls closure | ||
453 | * @param type block type | ||
454 | * @param group which block group to use for evaluation | ||
455 | * @param query original query (hash) | ||
456 | * @param xquery extrended query data (can be NULL, depending on type) | ||
457 | * @param xquery_size number of bytes in @a xquery | ||
458 | * @param reply_block response to validate | ||
459 | * @param reply_block_size number of bytes in @a reply_block | ||
460 | * @return characterization of result | ||
461 | */ | ||
462 | static enum GNUNET_BLOCK_ReplyEvaluationResult | ||
463 | block_plugin_regex_check_reply ( | ||
464 | void *cls, | ||
465 | enum GNUNET_BLOCK_Type type, | ||
466 | struct GNUNET_BLOCK_Group *group, | ||
467 | const struct GNUNET_HashCode *query, | ||
468 | const void *xquery, | ||
469 | size_t xquery_size, | ||
470 | const void *reply_block, | ||
471 | size_t reply_block_size) | ||
472 | { | ||
473 | struct GNUNET_HashCode chash; | ||
474 | |||
475 | switch (type) | ||
476 | { | ||
477 | case GNUNET_BLOCK_TYPE_REGEX: | ||
478 | if (0 != xquery_size) | ||
479 | { | ||
480 | const char *s; | ||
481 | |||
482 | s = (const char *) xquery; | ||
483 | if ('\0' != s[xquery_size - 1]) /* must be valid 0-terminated string */ | ||
484 | { | ||
485 | /* Technically, the query is invalid ... */ | ||
486 | GNUNET_break (0); | ||
487 | return GNUNET_BLOCK_REPLY_INVALID; | ||
488 | } | ||
489 | } | ||
490 | switch (REGEX_BLOCK_check (reply_block, | ||
491 | reply_block_size, | ||
492 | query, | ||
493 | xquery)) | ||
494 | { | ||
495 | case GNUNET_SYSERR: | ||
496 | GNUNET_break_op (0); | ||
497 | return GNUNET_BLOCK_REPLY_INVALID; | ||
498 | case GNUNET_NO: | ||
499 | /* xquery mismatch, can happen */ | ||
500 | return GNUNET_BLOCK_REPLY_IRRELEVANT; | ||
501 | default: | ||
502 | break; | ||
503 | } | ||
504 | GNUNET_CRYPTO_hash (reply_block, | ||
505 | reply_block_size, | ||
506 | &chash); | ||
507 | if (GNUNET_YES == | ||
508 | GNUNET_BLOCK_GROUP_bf_test_and_set (group, | ||
509 | &chash)) | ||
510 | return GNUNET_BLOCK_REPLY_OK_DUPLICATE; | ||
511 | return GNUNET_BLOCK_REPLY_OK_MORE; | ||
512 | case GNUNET_BLOCK_TYPE_REGEX_ACCEPT: | ||
513 | { | ||
514 | const struct RegexAcceptBlock *rba; | ||
515 | |||
516 | if (sizeof(struct RegexAcceptBlock) != reply_block_size) | ||
517 | { | ||
518 | GNUNET_break_op (0); | ||
519 | return GNUNET_BLOCK_REPLY_INVALID; | ||
520 | } | ||
521 | rba = reply_block; | ||
522 | if (ntohl (rba->purpose.size) != | ||
523 | sizeof(struct GNUNET_CRYPTO_EccSignaturePurpose) | ||
524 | + sizeof(struct GNUNET_TIME_AbsoluteNBO) | ||
525 | + sizeof(struct GNUNET_HashCode)) | ||
526 | { | ||
527 | GNUNET_break_op (0); | ||
528 | return GNUNET_BLOCK_REPLY_INVALID; | ||
529 | } | ||
530 | GNUNET_CRYPTO_hash (reply_block, | ||
531 | reply_block_size, | ||
532 | &chash); | ||
533 | if (GNUNET_YES == | ||
534 | GNUNET_BLOCK_GROUP_bf_test_and_set (group, | ||
535 | &chash)) | ||
536 | return GNUNET_BLOCK_REPLY_OK_DUPLICATE; | ||
537 | return GNUNET_BLOCK_REPLY_OK_MORE; | ||
538 | } | ||
539 | default: | ||
540 | GNUNET_break (0); | ||
541 | return GNUNET_BLOCK_REPLY_TYPE_NOT_SUPPORTED; | ||
542 | } | ||
543 | return GNUNET_BLOCK_REPLY_OK_MORE; | ||
544 | } | ||
545 | |||
546 | |||
547 | /** | ||
332 | * Function called to obtain the key for a block. | 548 | * Function called to obtain the key for a block. |
333 | * | 549 | * |
334 | * @param cls closure | 550 | * @param cls closure |
@@ -339,7 +555,7 @@ block_plugin_regex_evaluate (void *cls, | |||
339 | * @return #GNUNET_OK on success, #GNUNET_SYSERR if type not supported | 555 | * @return #GNUNET_OK on success, #GNUNET_SYSERR if type not supported |
340 | * (or if extracting a key from a block of this type does not work) | 556 | * (or if extracting a key from a block of this type does not work) |
341 | */ | 557 | */ |
342 | static int | 558 | static enum GNUNET_GenericReturnValue |
343 | block_plugin_regex_get_key (void *cls, | 559 | block_plugin_regex_get_key (void *cls, |
344 | enum GNUNET_BLOCK_Type type, | 560 | enum GNUNET_BLOCK_Type type, |
345 | const void *block, | 561 | const void *block, |
@@ -350,14 +566,14 @@ block_plugin_regex_get_key (void *cls, | |||
350 | { | 566 | { |
351 | case GNUNET_BLOCK_TYPE_REGEX: | 567 | case GNUNET_BLOCK_TYPE_REGEX: |
352 | if (GNUNET_OK != | 568 | if (GNUNET_OK != |
353 | REGEX_BLOCK_get_key (block, block_size, | 569 | REGEX_BLOCK_get_key (block, |
570 | block_size, | ||
354 | key)) | 571 | key)) |
355 | { | 572 | { |
356 | GNUNET_break_op (0); | 573 | GNUNET_break_op (0); |
357 | return GNUNET_NO; | 574 | return GNUNET_NO; |
358 | } | 575 | } |
359 | return GNUNET_OK; | 576 | return GNUNET_OK; |
360 | |||
361 | case GNUNET_BLOCK_TYPE_REGEX_ACCEPT: | 577 | case GNUNET_BLOCK_TYPE_REGEX_ACCEPT: |
362 | if (sizeof(struct RegexAcceptBlock) != block_size) | 578 | if (sizeof(struct RegexAcceptBlock) != block_size) |
363 | { | 579 | { |
@@ -366,7 +582,6 @@ block_plugin_regex_get_key (void *cls, | |||
366 | } | 582 | } |
367 | *key = ((struct RegexAcceptBlock *) block)->key; | 583 | *key = ((struct RegexAcceptBlock *) block)->key; |
368 | return GNUNET_OK; | 584 | return GNUNET_OK; |
369 | |||
370 | default: | 585 | default: |
371 | GNUNET_break (0); | 586 | GNUNET_break (0); |
372 | return GNUNET_SYSERR; | 587 | return GNUNET_SYSERR; |
@@ -380,7 +595,7 @@ block_plugin_regex_get_key (void *cls, | |||
380 | void * | 595 | void * |
381 | libgnunet_plugin_block_regex_init (void *cls) | 596 | libgnunet_plugin_block_regex_init (void *cls) |
382 | { | 597 | { |
383 | static enum GNUNET_BLOCK_Type types[] = { | 598 | static const enum GNUNET_BLOCK_Type types[] = { |
384 | GNUNET_BLOCK_TYPE_REGEX, | 599 | GNUNET_BLOCK_TYPE_REGEX, |
385 | GNUNET_BLOCK_TYPE_REGEX_ACCEPT, | 600 | GNUNET_BLOCK_TYPE_REGEX_ACCEPT, |
386 | GNUNET_BLOCK_TYPE_ANY /* end of list */ | 601 | GNUNET_BLOCK_TYPE_ANY /* end of list */ |
@@ -390,6 +605,9 @@ libgnunet_plugin_block_regex_init (void *cls) | |||
390 | api = GNUNET_new (struct GNUNET_BLOCK_PluginFunctions); | 605 | api = GNUNET_new (struct GNUNET_BLOCK_PluginFunctions); |
391 | api->evaluate = &block_plugin_regex_evaluate; | 606 | api->evaluate = &block_plugin_regex_evaluate; |
392 | api->get_key = &block_plugin_regex_get_key; | 607 | api->get_key = &block_plugin_regex_get_key; |
608 | api->check_query = &block_plugin_regex_check_query; | ||
609 | api->check_block = &block_plugin_regex_check_block; | ||
610 | api->check_reply = &block_plugin_regex_check_reply; | ||
393 | api->create_group = &block_plugin_regex_create_group; | 611 | api->create_group = &block_plugin_regex_create_group; |
394 | api->types = types; | 612 | api->types = types; |
395 | return api; | 613 | return api; |