Download | Plain Text | No Line Numbers


  1. #include <assert.h>
  2. #include "EXTERN.h"
  3. #include "perl.h"
  4. #include "XSUB.h"
  5. #include "ppport.h"
  6. #include "../cipher.h"
  7.  
  8. #define BLOCKSIZE 8192
  9.  
  10. #define SET_LEN(sv, len) \
  11.   do { SvPVX(sv)[len] = '\0'; SvCUR_set(sv, len); } while (0)
  12.  
  13. /* Internal defines */
  14. #ifdef PERL_FILTER_EXISTS
  15. # define CORE_FILTER_COUNT \
  16.   ((PL_parser && PL_parser->rsfp_filters) ? av_len(PL_parser->rsfp_filters) : 0)
  17. #else
  18. # define CORE_FILTER_COUNT \
  19.   ((PL_rsfp_filters) ? av_len(PL_rsfp_filters) : 0)
  20. #endif
  21.  
  22. #define FILTER_COUNT(s) IoPAGE(s)
  23. #define FILTER_LINE_NO(s) IoLINES(s)
  24. #define FIRST_TIME(s) IoLINES_LEFT(s)
  25.  
  26. #define CIPHER_GV(s) IoFMT_GV(s)
  27. #define CIPHER_SV(s) ((SV *) CIPHER_GV(s))
  28. #define CIPHER_BUFFER(s) ((ctx_t *)SvPVX(CIPHER_SV(s)))
  29. #define CLEAR_CIPHER_SV(s) SvCUR_set(CIPHER_SV(s), 0)
  30.  
  31. #define ENCRYPT_GV(s) IoTOP_GV(s)
  32. #define ENCRYPT_SV(s) ((SV *) ENCRYPT_GV(s))
  33. #define ENCRYPT_BUFFER(s) SvPVX(ENCRYPT_SV(s))
  34. #define CLEAR_ENCRYPT_SV(s) SvCUR_set(ENCRYPT_SV(s), 0)
  35.  
  36. #define DECRYPT_SV(s) s
  37. #define DECRYPT_BUFFER(s) SvPVX(DECRYPT_SV(s))
  38. #define CLEAR_DECRYPT_SV(s) SvCUR_set(DECRYPT_SV(s), 0)
  39. #define DECRYPT_BUFFER_LEN(s) SvCUR(DECRYPT_SV(s))
  40. #define DECRYPT_OFFSET(s) IoPAGE_LEN(DECRYPT_SV(s))
  41. #define SET_DECRYPT_BUFFER_LEN(s, n) SvCUR_set(DECRYPT_SV(s), n)
  42.  
  43. static unsigned
  44. decrypt(SV *in_cipher, SV *in_sv, SV *out_sv)
  45. {
  46. /* here is where the actual decryption takes place */
  47. ctx_t *cipher = (ctx_t *)SvPVX(in_cipher);
  48. char *in_buffer = (char *)SvPVX(in_sv);
  49. char *out_buffer;
  50. size_t in_len = SvCUR(in_sv);
  51. size_t out_len;
  52.  
  53. /* make certain that the output buffer is big enough
  54.   * as the output from the decryption can never be larger than
  55.   * the input buffer, make it that size
  56.   */
  57. SvGROW(out_sv, in_len);
  58. out_buffer = (char *)SvPVX(out_sv);
  59.  
  60. /* decrypt */
  61. out_len = CipherUpdate(cipher, in_buffer, in_len);
  62.  
  63. /* input has been consumed, so set length to 0 */
  64. SET_LEN(in_sv, 0);
  65.  
  66. /* set decrypt buffer length */
  67. assert(out_len <= BLOCKSIZE);
  68. SET_LEN(out_sv, out_len);
  69.  
  70. /* return the size of the decrypt buffer */
  71. return out_len;
  72. }
  73.  
  74. static int
  75. readblock(int idx, SV *sv, unsigned size)
  76. {
  77. /* read *exactly* size bytes from the next filter */
  78. int i = size;
  79. while (1)
  80. {
  81. int n = FILTER_READ(idx, sv, i);
  82. /* eof/error when nothing read so far */
  83. if (n <= 0 && i == size)
  84. return n;
  85. /* eof/error when something already read */
  86. if (n <= 0)
  87. return size - i;
  88. if (n == i)
  89. return size;
  90. i -= n;
  91. }
  92. }
  93.  
  94. static void
  95. pre_decrypt(int idx)
  96. {}
  97.  
  98. static void
  99. post_decrypt(int idx)
  100. {}
  101.  
  102. static I32
  103. filter_decrypt(pTHX_ int idx, SV *buf_sv, int maxlen)
  104. {
  105. char *out_ptr;
  106. char *p;
  107. char *nl = "\n";
  108. int n;
  109. SV *my_sv = FILTER_DATA(idx);
  110.  
  111. /* check if this is the first time through */
  112. if (FIRST_TIME(my_sv))
  113. {
  114. /* mild paranoia mode - make sure that no extra filters have
  115.   * been applied on the same line as the use Filter::decrypt
  116.   */
  117. if (CORE_FILTER_COUNT > FILTER_COUNT(my_sv))
  118. croak("too many filters");
  119.  
  120. /* as this is the first time through, so deal with any
  121.   * initialisation required
  122.   */
  123. pre_decrypt(idx);
  124.  
  125. FIRST_TIME(my_sv) = FALSE;
  126. SET_LEN(DECRYPT_SV(my_sv), 0);
  127. SET_LEN(ENCRYPT_SV(my_sv), 0);
  128. DECRYPT_OFFSET(my_sv) = 0;
  129. }
  130.  
  131. #ifdef DEBUG
  132. warn("**** In filter_decrypt - maxlen = %d, len buf = %d idx = %d\n",
  133. maxlen, SvCUR(buf_sv), idx);
  134. #endif
  135.  
  136. while (1)
  137. {
  138. /* anything left from last time */
  139. if ((n = SvCUR(DECRYPT_SV(my_sv))))
  140. {
  141. out_ptr = SvPVX(DECRYPT_SV(my_sv)) + DECRYPT_OFFSET(my_sv);
  142. if (maxlen)
  143. {
  144. /* want a block */
  145. #ifdef DEBUG
  146. warn("BLOCK(%d): size = %d, maxlen = %d\n", idx, n, maxlen);
  147. #endif
  148.  
  149. sv_catpvn(buf_sv, out_ptr, (maxlen > n) ? n : maxlen);
  150. if (n <= maxlen)
  151. {
  152. DECRYPT_OFFSET(my_sv) = 0;
  153. SET_LEN(DECRYPT_SV(my_sv), 0);
  154. }
  155. else
  156. {
  157. DECRYPT_OFFSET(my_sv) += maxlen;
  158. SvCUR_set(DECRYPT_SV(my_sv), n - maxlen);
  159. }
  160. return SvCUR(buf_sv);
  161. }
  162. else
  163. {
  164. /* want lines */
  165. if ((p = ninstr(out_ptr, out_ptr + n, nl, nl + 1)))
  166. {
  167. sv_catpvn(buf_sv, out_ptr, p - out_ptr + 1);
  168. n = n - (p - out_ptr + 1);
  169. DECRYPT_OFFSET(my_sv) += (p - out_ptr + 1);
  170. SvCUR_set(DECRYPT_SV(my_sv), n);
  171. #ifdef DEBUG
  172. warn("recycle(%d): leaving %d, returning %d [%.999s]\n",
  173. idx, n, SvCUR(buf_sv), SvPVX(buf_sv));
  174. #endif
  175. return SvCUR(buf_sv);
  176. }
  177. else
  178. {
  179. /* no EOL, so append the complete buffer */
  180. sv_catpvn(buf_sv, out_ptr, n);
  181. }
  182. }
  183. }
  184.  
  185. SET_LEN(DECRYPT_SV(my_sv), 0);
  186. DECRYPT_OFFSET(my_sv) = 0;
  187.  
  188. /* read at most BLOCKSIZE - 1 bytes from the file into the encrypt buffer:
  189.   * - 1 char ("#"-char) will be prepended during first call of CipherUpdate()
  190.   * - 1 char is needed for the string termination BUT perl already
  191.   * allocates +1 byte with newSV()
  192.   */
  193. if ((n = readblock(idx + 1, ENCRYPT_SV(my_sv), BLOCKSIZE - 1)) <= 0)
  194. {
  195. /* either EOF or an error */
  196. #ifdef DEBUG
  197. warn("filter_read(%d): returned %d, returning %d\n", idx, n,
  198. (SvCUR(buf_sv) > 0) ? SvCUR(buf_sv) : n);
  199. #endif
  200.  
  201. /* if the decrypt code needs to tidy up on EOF/error,
  202.   * now is the time - here is a hook
  203.   */
  204. post_decrypt(idx);
  205. filter_del(filter_decrypt);
  206.  
  207. /* if error, return the code */
  208. if (n < 0)
  209. return n;
  210.  
  211. /* return what we have so far else signal eof */
  212. return (SvCUR(buf_sv) > 0) ? SvCUR(buf_sv) : n;
  213. }
  214. #ifdef DEBUG
  215. else
  216. warn("filter_read(%d): read %d bytes\n", idx, n);
  217. #endif
  218.  
  219. #ifdef DEBUG
  220. warn("filter_decrypt(%d): sub-filter returned %d: '%.999s'\n",
  221. idx, n, SvPV(my_sv, PL_na));
  222. #endif
  223.  
  224. /* now decrypt a block */
  225. n = decrypt(CIPHER_SV(my_sv), ENCRYPT_SV(my_sv), DECRYPT_SV(my_sv));
  226.  
  227. #ifdef DEBUG
  228. warn("decrypt(%d): returned %d [%.999s]\n", idx, n, SvPVX(DECRYPT_SV(my_sv)));
  229. #endif
  230. }
  231. }
  232.  
  233.  
  234. MODULE = Confixx::Filter PACKAGE = Confixx::Filter
  235.  
  236. PROTOTYPES: DISABLE
  237.  
  238. BOOT:
  239. {
  240. #ifndef BYPASS
  241. /* don't run if this module is dynamically linked */
  242. if (!isALPHA(SvPV(GvSV(CvFILEGV(cv)), PL_na)[0]))
  243. croak("module is dynamically linked. Recompile as a static module");
  244. #ifdef DEBUGGING
  245. /* don't run if compiled with DEBUGGING */
  246. croak("recompile without -DDEBUGGING");
  247. #endif
  248.  
  249. /* double check that DEBUGGING hasn't been enabled */
  250. if (PL_debug)
  251. croak("debugging flags detected");
  252. #endif
  253. }
  254.  
  255. void
  256. import(module)
  257. SV *module
  258. PPCODE:
  259. {
  260. int ret;
  261. SV *sv;
  262.  
  263. /* main/decrypted SV */
  264. DECRYPT_SV(sv) = newSV(BLOCKSIZE);
  265. (void) SvPOK_only(DECRYPT_SV(sv));
  266. SET_LEN(DECRYPT_SV(sv), 0);
  267.  
  268. /* add filter */
  269. filter_add(filter_decrypt, DECRYPT_SV(sv));
  270.  
  271. /* cipher SV */
  272. CIPHER_GV(sv) = (GV *)newSV(sizeof(ctx_t));
  273. (void) SvPOK_only(CIPHER_GV(sv));
  274. (void) memset(CIPHER_BUFFER(sv), 0, sizeof(ctx_t));
  275. ret = CipherInit(CIPHER_BUFFER(sv));
  276. if (ret != 256)
  277. croak("unexpected return value of CipherInit(): %d\n", ret);
  278.  
  279. /* copy pointer to output buffer inside ciphers first bytes */
  280. CIPHER_BUFFER(sv)->out = DECRYPT_BUFFER(sv);
  281.  
  282. /* encrypted SV */
  283. ENCRYPT_GV(sv) = (GV *)newSV(BLOCKSIZE);
  284. (void) SvPOK_only(ENCRYPT_SV(sv));
  285. SET_LEN(ENCRYPT_SV(sv), 0);
  286.  
  287. /* enable first time flag */
  288. FIRST_TIME(sv) = TRUE;
  289. /* remember how many filters are enabled */
  290. FILTER_COUNT(sv) = CORE_FILTER_COUNT;
  291. /* and the line number */
  292. FILTER_LINE_NO(sv) = PL_curcop->cop_line;
  293. }
  294.  
  295. void
  296. unimport(...)
  297. PPCODE:
  298. //filter_del(filter_decrypt);
  299.