base.ts 2.9 KB

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