You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

cookie.lua 3.0KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125
  1. --[[
  2. Copyright (c) 2022, Vsevolod Stakhov <vsevolod@rspamd.com>
  3. Licensed under the Apache License, Version 2.0 (the "License");
  4. you may not use this file except in compliance with the License.
  5. You may obtain a copy of the License at
  6. http://www.apache.org/licenses/LICENSE-2.0
  7. Unless required by applicable law or agreed to in writing, software
  8. distributed under the License is distributed on an "AS IS" BASIS,
  9. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  10. See the License for the specific language governing permissions and
  11. limitations under the License.
  12. ]]--
  13. local argparse = require "argparse"
  14. -- Define command line options
  15. local parser = argparse()
  16. :name "rspamadm cookie"
  17. :description "Produces cookies or message ids"
  18. :help_description_margin(30)
  19. parser:mutex(
  20. parser:option "-k --key"
  21. :description('Key to load')
  22. :argname "<32hex>",
  23. parser:flag "-K --new-key"
  24. :description('Generates a new key')
  25. )
  26. parser:option "-d --domain"
  27. :description('Use specified domain and generate full message id')
  28. :argname "<domain>"
  29. parser:flag "-D --decrypt"
  30. :description('Decrypt cookie instead of encrypting one')
  31. parser:flag "-t --timestamp"
  32. :description('Show cookie timestamp (valid for decrypting only)')
  33. parser:argument "cookie":args "?"
  34. :description('Use specified cookie')
  35. local function gen_cookie(args, key)
  36. local cr = require "rspamd_cryptobox"
  37. if not args.cookie then
  38. return
  39. end
  40. local function encrypt()
  41. if #args.cookie > 31 then
  42. print('cookie too long (>31 characters), cannot encrypt')
  43. os.exit(1)
  44. end
  45. local enc_cookie = cr.encrypt_cookie(key, args.cookie)
  46. if args.domain then
  47. print(string.format('<%s@%s>', enc_cookie, args.domain))
  48. else
  49. print(enc_cookie)
  50. end
  51. end
  52. local function decrypt()
  53. local extracted_cookie = args.cookie:match('^%<?([^@]+)@.*$')
  54. if not extracted_cookie then
  55. -- Assume full message id as a cookie
  56. extracted_cookie = args.cookie
  57. end
  58. local dec_cookie, ts = cr.decrypt_cookie(key, extracted_cookie)
  59. if dec_cookie then
  60. if args.timestamp then
  61. print(string.format('%s %s', dec_cookie, ts))
  62. else
  63. print(dec_cookie)
  64. end
  65. else
  66. print('cannot decrypt cookie')
  67. os.exit(1)
  68. end
  69. end
  70. if args.decrypt then
  71. decrypt()
  72. else
  73. encrypt()
  74. end
  75. end
  76. local function handler(args)
  77. local res = parser:parse(args)
  78. if not (res.key or res['new_key']) then
  79. parser:error('--key or --new-key must be specified')
  80. end
  81. if res.key then
  82. local pattern = { '^' }
  83. for i = 1, 32 do
  84. pattern[i + 1] = '[a-zA-Z0-9]'
  85. end
  86. pattern[34] = '$'
  87. if not res.key:match(table.concat(pattern, '')) then
  88. parser:error('invalid key: ' .. res.key)
  89. end
  90. gen_cookie(res, res.key)
  91. else
  92. local util = require "rspamd_util"
  93. local key = util.random_hex(32)
  94. print(key)
  95. gen_cookie(res, res.key)
  96. end
  97. end
  98. return {
  99. handler = handler,
  100. description = parser._description,
  101. name = 'cookie'
  102. }