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

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121
  1. --[[
  2. Copyright (c) 2018, Vsevolod Stakhov <vsevolod@highsecure.ru>
  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 return end
  38. local function encrypt()
  39. if #args.cookie > 31 then
  40. print('cookie too long (>31 characters), cannot encrypt')
  41. os.exit(1)
  42. end
  43. local enc_cookie = cr.encrypt_cookie(key, args.cookie)
  44. if args.domain then
  45. print(string.format('<%s@%s>', enc_cookie, args.domain))
  46. else
  47. print(enc_cookie)
  48. end
  49. end
  50. local function decrypt()
  51. local extracted_cookie = args.cookie:match('^%<?([^@]+)@.*$')
  52. if not extracted_cookie then
  53. -- Assume full message id as a cookie
  54. extracted_cookie = args.cookie
  55. end
  56. local dec_cookie,ts = cr.decrypt_cookie(key, extracted_cookie)
  57. if dec_cookie then
  58. if args.timestamp then
  59. print(string.format('%s %s', dec_cookie, ts))
  60. else
  61. print(dec_cookie)
  62. end
  63. else
  64. print('cannot decrypt cookie')
  65. os.exit(1)
  66. end
  67. end
  68. if args.decrypt then
  69. decrypt()
  70. else
  71. encrypt()
  72. end
  73. end
  74. local function handler(args)
  75. local res = parser:parse(args)
  76. if not (res.key or res['new_key']) then
  77. parser:error('--key or --new-key must be specified')
  78. end
  79. if res.key then
  80. local pattern = {'^'}
  81. for i=1,32 do pattern[i + 1] = '[a-zA-Z0-9]' end
  82. pattern[34] = '$'
  83. if not res.key:match(table.concat(pattern, '')) then
  84. parser:error('invalid key: ' .. res.key)
  85. end
  86. gen_cookie(res, res.key)
  87. else
  88. local util = require "rspamd_util"
  89. local key = util.random_hex(32)
  90. print(key)
  91. gen_cookie(res, res.key)
  92. end
  93. end
  94. return {
  95. handler = handler,
  96. description = parser._description,
  97. name = 'cookie'
  98. }