base.ts 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109
  1. import type { Span } from '../../trace';
  2. import { compareAndWriteFile } from '../create-file';
  3. import { compareAndWriteFileInWorker } from '../create-file.worker';
  4. /**
  5. * The class is not about holding rule data, instead it determines how the
  6. * date is written to a file.
  7. */
  8. export abstract class BaseWriteStrategy {
  9. public abstract readonly name: string;
  10. /**
  11. * Sometimes a ruleset will create extra files (e.g. reject-url-regex w/ mitm.sgmodule),
  12. * and doesn't share the same filename and id. This property is used to overwrite the filename.
  13. */
  14. public overwriteFilename: string | null = null;
  15. public withFilename(filename: string) {
  16. this.overwriteFilename = filename;
  17. return this;
  18. }
  19. public abstract readonly type: 'domainset' | 'non_ip' | 'ip' | (string & {});
  20. abstract readonly fileExtension: 'conf' | 'txt' | 'json' | 'sgmodule'; /* | (string & {}) */
  21. constructor(public readonly outputDir: string) {}
  22. protected abstract result: string[] | null;
  23. abstract writeDomain(domain: string): void;
  24. abstract writeDomainSuffix(domain: string): void;
  25. abstract writeDomainKeywords(keyword: Set<string>): void;
  26. abstract writeDomainWildcards(wildcard: Set<string>): void;
  27. abstract writeUserAgents(userAgent: Set<string>): void;
  28. abstract writeProcessNames(processName: Set<string>): void;
  29. abstract writeProcessPaths(processPath: Set<string>): void;
  30. abstract writeUrlRegexes(urlRegex: Set<string>): void;
  31. abstract writeIpCidrs(ipCidr: string[], noResolve: boolean): void;
  32. abstract writeIpCidr6s(ipCidr6: string[], noResolve: boolean): void;
  33. abstract writeGeoip(geoip: Set<string>, noResolve: boolean): void;
  34. abstract writeIpAsns(asns: Set<string>, noResolve: boolean): void;
  35. abstract writeSourceIpCidrs(sourceIpCidr: string[]): void;
  36. abstract writeSourcePorts(port: Set<string>): void;
  37. abstract writeDestinationPorts(port: Set<string>): void;
  38. abstract writeProtocols(protocol: Set<string>): void;
  39. abstract writeOtherRules(rule: string[]): void;
  40. protected abstract withPadding(title: string, description: string[] | readonly string[], date: Date, content: string[]): string[];
  41. static readonly domainWildCardToRegex = (domain: string) => {
  42. let result = '^';
  43. for (let i = 0, len = domain.length; i < len; i++) {
  44. switch (domain[i]) {
  45. case '.':
  46. result += String.raw`\.`;
  47. break;
  48. case '*':
  49. result += String.raw`[\w.-]*?`;
  50. break;
  51. case '?':
  52. result += String.raw`[\w.-]`;
  53. break;
  54. default:
  55. result += domain[i];
  56. }
  57. }
  58. result += '$';
  59. return result;
  60. };
  61. public output(
  62. span: Span,
  63. title: string,
  64. description: string[] | readonly string[],
  65. date: Date,
  66. filePath: string
  67. ): void | Promise<void> {
  68. if (!this.result) {
  69. return;
  70. }
  71. if (this.result.length > 1000) {
  72. return compareAndWriteFileInWorker(
  73. span,
  74. this.withPadding(
  75. title,
  76. description,
  77. date,
  78. this.result
  79. ),
  80. filePath
  81. );
  82. }
  83. return compareAndWriteFile(
  84. span,
  85. this.withPadding(
  86. title,
  87. description,
  88. date,
  89. this.result
  90. ),
  91. filePath
  92. );
  93. };
  94. public get content() {
  95. return this.result;
  96. }
  97. }