05_wildcard_matching 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118
  1. See https://bugzilla.redhat.com/bugzilla/show_bug.cgi?id=17847
  2. (Though the original code needs to be patched to be case-insensitive.)
  3. --- a/hosts_access.5
  4. +++ b/hosts_access.5
  5. @@ -89,6 +89,10 @@ An expression of the form `n.n.n.n/m.m.m
  6. bitwise AND of the address and the `mask\'. For example, the net/mask
  7. pattern `131.155.72.0/255.255.254.0\' matches every address in the
  8. range `131.155.72.0\' through `131.155.73.255\'.
  9. +.IP \(bu
  10. +Wildcards `*\' and `?\' can be used to match hostnames or IP addresses. This
  11. +method of matching cannot be used in conjunction with `net/mask\' matching,
  12. +hostname matching beginning with `.\' or IP address matching ending with `.\'.
  13. .SH WILDCARDS
  14. The access control language supports explicit wildcards:
  15. .IP ALL
  16. --- a/hosts_access.c
  17. +++ b/hosts_access.c
  18. @@ -82,6 +82,7 @@ static int client_match();
  19. static int host_match();
  20. static int string_match();
  21. static int masked_match();
  22. +static int match_pattern_ylo();
  23. /* Size of logical line buffer. */
  24. @@ -289,6 +290,11 @@ char *string;
  25. {
  26. int n;
  27. +#ifndef DISABLE_WILDCARD_MATCHING
  28. + if (strchr(tok, '*') || strchr(tok,'?')) { /* contains '*' or '?' */
  29. + return (match_pattern_ylo(string,tok));
  30. + } else
  31. +#endif
  32. if (tok[0] == '.') { /* suffix */
  33. n = strlen(string) - strlen(tok);
  34. return (n > 0 && STR_EQ(tok, string + n));
  35. @@ -329,3 +335,78 @@ char *string;
  36. }
  37. return ((addr & mask) == net);
  38. }
  39. +
  40. +#ifndef DISABLE_WILDCARD_MATCHING
  41. +/* Note: this feature has been adapted in a pretty straightforward way
  42. + from Tatu Ylonen's last SSH version under free license by
  43. + Pekka Savola <pekkas@netcore.fi>.
  44. +
  45. + Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
  46. +*/
  47. +
  48. +/* Returns true if the given string matches the pattern (which may contain
  49. + ? and * as wildcards), and zero if it does not match. */
  50. +
  51. +static int match_pattern_ylo(const char *s, const char *pattern)
  52. +{
  53. + char src;
  54. + char pat;
  55. + while (1)
  56. + {
  57. + /* If at end of pattern, accept if also at end of string. */
  58. + if (!*pattern)
  59. + return !*s;
  60. +
  61. + /* Process '*'. */
  62. + if (*pattern == '*')
  63. + {
  64. + /* Skip the asterisk. */
  65. + pattern++;
  66. +
  67. + /* If at end of pattern, accept immediately. */
  68. + if (!*pattern)
  69. + return 1;
  70. +
  71. + /* If next character in pattern is known, optimize. */
  72. + if (*pattern != '?' && *pattern != '*')
  73. + {
  74. + /* Look instances of the next character in pattern, and try
  75. + to match starting from those. */
  76. + pat = *pattern;
  77. + for (; *s; s++) {
  78. + src = *s;
  79. + if (toupper(src) == toupper(pat) &&
  80. + match_pattern_ylo(s + 1, pattern + 1))
  81. + return 1;
  82. + }
  83. + /* Failed. */
  84. + return 0;
  85. + }
  86. +
  87. + /* Move ahead one character at a time and try to match at each
  88. + position. */
  89. + for (; *s; s++)
  90. + if (match_pattern_ylo(s, pattern))
  91. + return 1;
  92. + /* Failed. */
  93. + return 0;
  94. + }
  95. +
  96. + /* There must be at least one more character in the string. If we are
  97. + at the end, fail. */
  98. + if (!*s)
  99. + return 0;
  100. +
  101. + /* Check if the next character of the string is acceptable. */
  102. + pat = *pattern;
  103. + src = *s;
  104. + if (*pattern != '?' && toupper(pat) != toupper(src))
  105. + return 0;
  106. +
  107. + /* Move to the next character, both in string and in pattern. */
  108. + s++;
  109. + pattern++;
  110. + }
  111. + /*NOTREACHED*/
  112. +}
  113. +#endif /* DISABLE_WILDCARD_MATCHING */