gdipmailchk.pm 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244
  1. ########################################################################
  2. # gdipmailchk.pm
  3. #
  4. # These routines are used by the GnuDIP web interface to prevent robots
  5. # from having GnuDIP send E-mail.
  6. #
  7. # See COPYING for licensing information.
  8. #
  9. ########################################################################
  10. # Perl modules
  11. use strict;
  12. # global variables
  13. use vars qw($conf $pref $reqparm $thiscgi);
  14. # GnuDIP common subroutines
  15. use gdiplib;
  16. use gdipcgi_cmn;
  17. use htmlgen;
  18. ########################################################################
  19. # generate HTML for inclusion in a page
  20. ########################################################################
  21. sub mchk_html {
  22. return if $$pref{'NO_ROBOTS'} and $$pref{'NO_ROBOTS'} eq 'NO';
  23. # generate random string and signature
  24. my $sign = nrb_write();
  25. return if ! $sign;
  26. # generate the HTML
  27. tpr(qq*
  28. <input type="hidden" name="image_signature" value="$sign">
  29. <p>
  30. <center>
  31. Text From Image Below: <input type="text" name="image_text">
  32. <p>
  33. <table border=1><tr><td>
  34. <img align=middle
  35. src="$thiscgi?mailcheck=$sign"
  36. alt="No Robots Image"
  37. border=0 height=30 width=190
  38. >
  39. </td></tr></table>
  40. </center>
  41. <p>
  42. *);
  43. }
  44. #######################################################################
  45. # generate and return image
  46. #######################################################################
  47. sub pg_mchk_img {
  48. default_empty('mailcheck');
  49. # command to generate image
  50. my $imgcmd = $$conf{'no_robots_imgcmd'};
  51. $imgcmd = '/usr/local/gnudip/sbin/textimage.sh'
  52. if ! $imgcmd;
  53. # prefix for any temporary files
  54. my $prefix = nrb_filename($$reqparm{'mailcheck'});
  55. # retrieve string
  56. my $string = nrb_read($$reqparm{'mailcheck'});
  57. if (! $string) {
  58. pg_msg(qq*
  59. Error: No E-mail Pending
  60. *,qq*
  61. There is no E-mail pending for this page.
  62. *)
  63. }
  64. # readable fork to generate image
  65. my $pid = open(CMD, "-|");
  66. if (! defined $pid) {
  67. writelog('pg_mchk_img: open failed');
  68. bad_config();
  69. }
  70. if ($pid eq 0) {
  71. # child
  72. # to placate "-T" - trust path and arguments
  73. my $path = $ENV{PATH};
  74. if ($path =~ /^(.*)$/) {
  75. $path = $1;
  76. }
  77. $ENV{PATH} = $path;
  78. if ($imgcmd =~ /^(.*)$/) {
  79. $imgcmd = $1;
  80. }
  81. if ($string =~ /^(.*)$/) {
  82. $string = $1;
  83. }
  84. if ($prefix =~ /^(.*)$/) {
  85. $prefix = $1;
  86. }
  87. # for FCGI.pm compatibility
  88. untie *STDOUT;
  89. # pass control to command
  90. my $ok = exec {$imgcmd} $imgcmd, $string, $prefix;
  91. if (! $ok) {
  92. # should not have come back!
  93. # exit, bypassing Perl
  94. POSIX::_exit 255;
  95. }
  96. }
  97. # parent
  98. # retrieve output
  99. my $imagedata = '';
  100. while (my $moredata = <CMD>) {
  101. $imagedata .= $moredata;
  102. }
  103. # close it
  104. my $close = close CMD;
  105. my $sysmsg = $!;
  106. my $exitval = $? >> 8;
  107. # no image data?
  108. if (! $imagedata) {
  109. writelog("pg_mchk_img: no image returned - $imgcmd $string $prefix");
  110. writelog("pg_mchk_img: close failed - $imgcmd $string $prefix - $sysmsg")
  111. if !$close and $sysmsg;
  112. writelog("pg_mchk_img: exit code $exitval - $imgcmd $string $prefix")
  113. if $exitval ne 0;
  114. bad_config();
  115. }
  116. # pump out the image
  117. print STDOUT $imagedata;
  118. exit;
  119. }
  120. ########################################################################
  121. # check response
  122. ########################################################################
  123. sub mchk_check {
  124. return if $$pref{'NO_ROBOTS'} and $$pref{'NO_ROBOTS'} eq 'NO';
  125. default_empty('image_signature');
  126. default_empty('image_text');
  127. # have a signature?
  128. pg_error('bad_request') if ! $$reqparm{'image_signature'};
  129. # retrieve string
  130. my $string = nrb_read($$reqparm{'image_signature'});
  131. if (! $string) {
  132. pg_msg(qq*
  133. Error: No E-mail Pending
  134. *,qq*
  135. There is no E-mail pending for this page.
  136. *)
  137. }
  138. # check response
  139. if ($string ne $$reqparm{'image_text'}) {
  140. pg_msg(qq*
  141. Error: Robot Test Failed
  142. *,qq*
  143. You did not correctly enter the character string contained in the image.
  144. *);
  145. }
  146. # remove file
  147. unlink nrb_filename($$reqparm{'image_signature'});
  148. }
  149. ########################################################################
  150. # state management local routines
  151. ########################################################################
  152. sub nrb_write {
  153. # generate random string and signature
  154. my @chars = ('a' .. 'z');
  155. my $string = '';
  156. for (my $charcount = 0; $charcount < 10; $charcount++) {
  157. $string .= $chars[ rand @chars ];
  158. }
  159. my $sign = md5_hex($string.$$pref{'SERVER_KEY'});
  160. # file name
  161. my $statefile = nrb_filename($sign);
  162. return '' if ! $statefile;
  163. # write over file
  164. local *STATE;
  165. if (! open (STATE, ">$statefile")) {
  166. writelog("mchk_html: cannot open $statefile: $!");
  167. return '';
  168. }
  169. print STATE $string;
  170. close STATE;
  171. # restrict permissions
  172. chmod 0600, ($statefile);
  173. return $sign;
  174. }
  175. sub nrb_read {
  176. my $sign = shift;
  177. return '' if ! $sign;
  178. # file name
  179. my $statefile = nrb_filename($sign);
  180. return '' if ! $statefile;
  181. # file exists?
  182. return '' if ! -f $statefile;
  183. # read it
  184. local *STATE;
  185. if (! open (STATE, "<$statefile")) {
  186. writelog("mchk_html: cannot open $statefile: $!");
  187. return '';
  188. }
  189. read(STATE, my $string, 100);
  190. close STATE;
  191. return $string;
  192. }
  193. sub nrb_filename {
  194. my $sign = shift;
  195. return '' if ! $sign;
  196. my $prefix = $$conf{'no_robots_prfx'};
  197. $prefix = '/tmp/gdipnrb_' if ! $prefix;
  198. return $prefix . $sign;
  199. }
  200. #####################################################
  201. # must return 1
  202. #####################################################
  203. 1;