recommend_pkg.c 2.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990
  1. /* Copyright (c) 2001-2004, Roger Dingledine.
  2. * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
  3. * Copyright (c) 2007-2019, The Tor Project, Inc. */
  4. /* See LICENSE for licensing information */
  5. /**
  6. * \file recommend_pkg.c
  7. * \brief Code related to the recommended-packages subsystem.
  8. *
  9. * Currently unused.
  10. **/
  11. #include "core/or/or.h"
  12. #include "feature/dirauth/recommend_pkg.h"
  13. /** Return true iff <b>line</b> is a valid RecommendedPackages line.
  14. */
  15. /*
  16. The grammar is:
  17. "package" SP PACKAGENAME SP VERSION SP URL SP DIGESTS NL
  18. PACKAGENAME = NONSPACE
  19. VERSION = NONSPACE
  20. URL = NONSPACE
  21. DIGESTS = DIGEST | DIGESTS SP DIGEST
  22. DIGEST = DIGESTTYPE "=" DIGESTVAL
  23. NONSPACE = one or more non-space printing characters
  24. DIGESTVAL = DIGESTTYPE = one or more non-=, non-" " characters.
  25. SP = " "
  26. NL = a newline
  27. */
  28. int
  29. validate_recommended_package_line(const char *line)
  30. {
  31. const char *cp = line;
  32. #define WORD() \
  33. do { \
  34. if (*cp == ' ') \
  35. return 0; \
  36. cp = strchr(cp, ' '); \
  37. if (!cp) \
  38. return 0; \
  39. } while (0)
  40. WORD(); /* skip packagename */
  41. ++cp;
  42. WORD(); /* skip version */
  43. ++cp;
  44. WORD(); /* Skip URL */
  45. ++cp;
  46. /* Skip digesttype=digestval + */
  47. int n_entries = 0;
  48. while (1) {
  49. const char *start_of_word = cp;
  50. const char *end_of_word = strchr(cp, ' ');
  51. if (! end_of_word)
  52. end_of_word = cp + strlen(cp);
  53. if (start_of_word == end_of_word)
  54. return 0;
  55. const char *eq = memchr(start_of_word, '=', end_of_word - start_of_word);
  56. if (!eq)
  57. return 0;
  58. if (eq == start_of_word)
  59. return 0;
  60. if (eq == end_of_word - 1)
  61. return 0;
  62. if (memchr(eq+1, '=', end_of_word - (eq+1)))
  63. return 0;
  64. ++n_entries;
  65. if (0 == *end_of_word)
  66. break;
  67. cp = end_of_word + 1;
  68. }
  69. /* If we reach this point, we have at least 1 entry. */
  70. tor_assert(n_entries > 0);
  71. return 1;
  72. }