git ssb

0+

cel / freecheck



Tree: 59041da2fc238b23ec7429880e66e960c1177c83

Files: 59041da2fc238b23ec7429880e66e960c1177c83 / freecheck.cgi

13166 bytesRaw
1#!/usr/bin/perl
2
3#---------------
4#
5# FreeCheck - a free check printing application released
6# under the GNU General Public Licene.
7#
8# Copyright (C) 2000 Eric Sandeen (sandeen-freecheck@sandeen.net)
9#
10# This program is free software; you can redistribute it and/or modify
11# it under the terms of the GNU General Public License as published by
12# the Free Software Foundation; either version 2 of the License, or
13# (at your option) any later version.
14#
15# This program is distributed in the hope that it will be useful,
16# but WITHOUT ANY WARRANTY; without even the implied warranty of
17# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18# GNU General Public License for more details.
19#
20# You should have received a copy of the GNU General Public License
21# along with this program; if not, write to the Free Software
22# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
23#
24#---------------
25
26###########################################
27# WARNING WARNING WARNING WARNING WARNING #
28###########################################
29# THIS CODE EXECUTES AT LEAST ONE EXTERNAL PROGRAM, BASED ON
30# STRINGS PASSED IN FROM THE FORM. A FEEBLE EFFORT HAS BEEN
31# MADE TO SANITIZE THOSE STRINGS, BUT THERE COULD STILL BE
32# A SECURITY RISK HERE. YOU HAVE BEEN WARNED
33##########################################
34
35# This script will generate a form that allows users to fill out information to
36# be printed on checks, and they get back either a PostScript or a PDF document.
37# Currently, the freecheck script and config files need to be in the same dir as
38# the CGI. If you want to generate PDFs, you need GhostScript. You also really
39# need the 6.x series, or the PDFs will look horrible, and checks printed almost
40# certainly will not be machine readable.
41
42# The freecheck executable script, and the freecheck config file
43# (freecheck.cfg) should be in the same dir as this script.
44
45use CGI qw(:standard);
46
47# The path to the GhostScript executable, with escaped "/"s
48$GS = "\/usr\/bin\/gs";
49
50# Parameters to GhostScript to generate PDFs (trailing "-" means STDIN
51$PDFOptions = "-q -dNOPAUSE -dBATCH -sDEVICE=pdfwrite -sOutputFile=- -";
52
53
54# Get the cookie to set the defaults, if it's there...
55%pairs_hash = cookie('FreeCheck');
56
57# If it's not there, set minimum defaults so the main script won't bonk
58if (!%pairs_hash) {
59 %pairs_hash = ( "NumPages", "1",
60 "PrintCheckBody", "true",
61 "PrintMICRLine", "true",
62 "CheckNumber", "100");
63}
64
65# If we have no parameters passed, generate the initial page with default vals
66# Those defaults might be from a cookie (above) if one has been set.
67if (!param()) {
68 print header;
69 print start_html('FreeCheck Online'),
70 #"Cookie:",br,
71 #%pairs_hash,
72 h1('FreeCheck'),
73 "A free check printing utility",
74 br,
75 "Version 0.30",
76 br,
77 "Copyright (C) 2000 Eric Sandeen (sandeen-freecheck @ sandeen.net)",
78 hr,
79 "WARNING - unless you're brave, treat this application as a
80 proof-of-concept, rather than a useful utility. I have not
81 had a chance to test this stuff with a bank yet, and I'm also
82 a bit concerned about the accuracy during conversion to
83 PDF. Just don't go paying your rent with this yet, ok? :)",
84 hr,
85 start_form,
86 submit( -name=>"Submit",
87 -label=>" Get my checks! "),
88 h2('Check Information'),
89 h3('Account Holder Information'),
90
91 textfield( -name=>'Name1',
92 -default=>$pairs_hash{"Name1"},
93 -maxlength=>50),
94 " Name 1", br,
95
96 textfield( -name=>'Name2',
97 -default=>$pairs_hash{"Name2"},
98 -maxlength=>50),
99 " Name 2", br,
100
101 textfield( -name=>'Address1',
102 -default=>$pairs_hash{"Address1"},
103 -maxlength=>50),
104 " Address Line 1", br,
105
106 textfield( -name=>'Address2',
107 -default=>$pairs_hash{"Address2"},
108 -maxlength=>50),
109 " Address Line 2", br,
110
111 textfield( -name=>'CityStateZip',
112 -default=>$pairs_hash{"CityStateZip"},
113 -maxlength=>50),
114 " City, State, Zip", br,
115
116 textfield( -name=>'PhoneNumber',
117 -default=>$pairs_hash{"PhoneNumber"},
118 -maxlength=>50),
119 " Phone Number", br,
120
121 h3('MICR Line Information'),
122 "Pay close attention here - this is where you enter the MICR
123 line at the bottom of your check. For the following symbols,
124 use these characters:", p,
125
126 hr,
127 img {-src=>'/images/transit.gif'}, " = \"R\"", br,
128 img {-src=>'/images/onus.gif'}, " = \"P\"", br,
129 img {-src=>'/images/dash.gif'}, " = \"-\" (dash, or minus)", p,
130 "For spaces, enter \"S\"", p,
131 "For check numbers, enter a \"C\" for each check digit", p,
132 hr,
133
134 "Auxiliary On-Us field - Everything to the left of the leftmost ",
135 img {-src=>'/images/transit.gif'}, " symbol", br,
136 em("Don't forget to include trailing spaces (\"S\")!"), br,
137 "This field may not be present on personal checks", br,
138
139 textfield( -name=>'AuxOnUs',
140 -default=>$pairs_hash{"AuxOnUs"},
141 -maxlength=>50),
142
143 " Auxiliary On-Us field", p,
144
145 "Transit / Routing Field - 9 numbers between, and including, the ",
146 img {-src=>'/images/transit.gif'}, " symbols", br,
147
148 textfield( -name=>'Routing',
149 -default=>$pairs_hash{"Routing"},
150 -size=>11, -maxlength=>11),
151
152 " Routing Field", p,
153
154 "On-Us field - everything to the right of the rightmost ",
155 img {-src=>'/images/transit.gif'}, " symbol", br,
156 em("Don't forget to include leading spaces (\"S\")!"), br,
157
158 textfield( -name=>'OnUs',
159 -default=>$pairs_hash{"OnUs"},
160 -maxlength=>50),
161
162 " On-Us field", p,
163
164 textfield( -name=>'Fraction',
165 -default=>$pairs_hash{"Fraction"},
166 -maxlength=>50),
167
168 " Fraction (printed at top right of check)", br,
169
170 h3('Bank Information'),
171 textfield( -name=>'BankName',
172 -default=>$pairs_hash{"BankName"},
173 -maxlength=>50),
174 " Bank Name", br,
175
176 textfield( -name=>'BankAddr1',
177 -default=>$pairs_hash{"BankAddr1"},
178 -maxlength=>50),
179 " Bank Address1", br,
180
181 textfield( -name=>'BankAddr2',
182 -default=>$pairs_hash{"BankAddr2"},
183 -maxlength=>50),
184 " Bank Address 2", br,
185
186 textfield( -name=>'BankCityStateZip',
187 -default=>$pairs_hash{"BankCityStateZip"},
188 -maxlength=>50),
189 " Bank City, State, Zip", br,
190
191 h2('Printing Options'),
192 textfield( -name=>'CheckNumber',
193 -default=>$pairs_hash{"CheckNumber"},
194 -size=>10,
195 -maxlength=>10),
196 " Starting Check Number",
197 br,
198
199 "Select check style: ",
200 popup_menu( -name=>'CheckStyle',
201 -values=>['Normal','Quicken_Personal'],
202 -default=>$pairs_hash{"CheckStyle"}),
203 br,
204
205 "Select check blank: ",
206 popup_menu( -name=>'CheckType',
207 -values=>['MVG3001','MVG1000','MVD1001'],
208 -default=>$pairs_hash{"CheckType"},
209 -labels=>{ 'MVG3001'=>'VersaCheck MVG3001',
210 'MVG1000'=>'VersaCheck MVG1000',
211 'MVD1001'=>'VersaCheck MVD1001'}),
212 p,
213
214
215 checkbox( -name=>'PrintCheckBody',
216 -checked=>$pairs_hash{"PrintCheckBody"},
217 -value=>'true',
218 -label=>' Print Check Body'),
219 br,
220
221 checkbox( -name=>'PrintMICRLine',
222 -checked=>$pairs_hash{"PrintMICRLine"},
223 -value=>'true',
224 -label=>' Print MICR Line'),
225 br,
226
227 checkbox( -name=>'Test',
228 -checked=>$pairs_hash{"Test"},
229 -value=>'true',
230 -label=>' Print voided test checks'),
231 p,
232
233 "Select Output Format:",
234 br,
235 em("Be sure to de-select \"Fit to Page\" when printing PDFs"),
236 br,
237 em("To view PostScript correctly, you must have the
238 GnuMICR font installed locally"),
239 br,
240 radio_group( -name=>'OutputType',
241 -values=>['PDF', 'PostScript'],
242 -labels=>{'PDF'=>' PDF',
243 'PostScript'=>' PostScript'},
244 -default=>$pairs_hash{"OutputType"},
245 -linebreak=>'true'),
246 br,
247
248 "Number of Pages to Print: ",
249 textfield( -name=>'NumPages',
250 -default=>$pairs_hash{"NumPages"},
251 -size=>2,
252 -maxlength=>1),
253 p,
254
255 "Save information in a cookie?",
256 br,
257 em("Note: if you're security-paranoid, and you've entered real data,
258 this might not be a such a good idea at this point..."),
259 br,
260 radio_group( -name=>'Cookie',
261 -values=>['ClearCookie', 'SetCookie'],
262 -default=>$pairs_hash{"Cookie"},
263 -labels=>{'ClearCookie'=>' Don\'t set, or clear',
264 'SetCookie'=>' Set a cookie'},
265 -linebreak=>'true'),
266 br,
267 submit( -name=>"Submit",
268 -label=>" Get my checks! "),
269 end_form,
270 em("If Netscape wants to save \"freecheck.cgi\" just rename it to
271 \"mychecks.[pdf,ps]\" - I don't know why this happens"),
272 hr;
273 print end_html;
274}
275
276# If Submit button has been pressed , then process the values
277if (param("Submit")) {
278
279 # Get a hash of all the fields and their values
280 my @names = param();
281 $pairs_string = "";
282 foreach (@names) {
283 $name = $_;
284 $value = param($_);
285 #$pairs_string = $pairs_string . $_ . " $value\n";
286 $pairs_hash{$name} = $value;
287 }
288 # "Submit" is the only thing we don't want to store
289 delete $pairs_hash{"Submit"};
290
291 # Deal with the form elements that didn't go in the hash:
292 $CheckStyle = param("CheckStyle");
293 $CheckType = param("CheckType");
294
295 # For checkboxes, delete them from the hash/cookie if not checked
296 if ( param("PrintMICRLine") ne "true" ) {
297 $MICR = "--nomicr";
298 delete $pairs_hash{"PrintMICRLine"};
299 }
300
301 if ( param("PrintCheckBody") ne "true" ) {
302 $BODY = "--nobody";
303 delete $pairs_hash{"PrintCheckBody"};
304 }
305
306 if ( param("Test") eq "true") {
307 $TEST = "--test";
308 } else {
309 delete $pairs_hash{"Test"};
310 }
311
312 # Turn the hash into a string (this is a bit goofy, I guess...)
313 # We do it as a hash initially to make it easier to fill in the
314 # forms, above.
315 # This is what is passed to the check generation script
316
317 $pairs_string = "";
318 $NotDefs="Submit Cookie Test OutputType CheckStyle CheckType";
319 while ( ($name,$value) = each(%pairs_hash) ) {
320 unless ($NotDefs =~ /${name}/ ) {
321 $pairs_string = $pairs_string . "$name $value\n";
322 }
323 }
324
325 # Create the argument string
326 $arguments = "--checkstyle $CheckStyle --checktype $CheckType $MICR $BODY $TEST";
327
328 # This is where we should set the next check number to be printed,
329 # if we knew how many checks per page we had... any good way
330 # to do this....? For now, we'll just set things up semi-manually
331
332 %ChecksPerPage =
333 ("MVG3001", "3", "MVG1000", "1", "MVD1001", "1");
334
335 $NextCheckNumber = param("CheckNumber") +
336 param("NumPages") *
337 $ChecksPerPage{param("CheckType")};
338
339 $pairs_hash{"CheckNumber"} = $NextCheckNumber;
340
341 # Sanitize $pairs_string and $arguments
342 # Let's not go spawning any new shells (this is minimal security...)
343 # Also checks for SSI strings
344
345 # Look for SSI
346 if ($pairs_string =~ /\<\!--\#(.*)\s+(.*)\s?=\s?(.*)--\>/s) {
347 kill_input();
348 }
349
350 if ($arguments =~ /\<\!--\#(.*)\s+(.*)\s?=\s?(.*)--\>/s) {
351 kill_input();
352 }
353
354 # Look for shell metachars
355 if ($pairs_string =~ /[;><\*`\|]/s) {
356 kill_input();
357 }
358
359 if ($arguments =~ /[;><\*`\|]/s) {
360 kill_input();
361 }
362
363 if ( param("Cookie") eq "SetCookie" ) {
364 $cookie = cookie( -name=>'FreeCheck',
365 -value=>\%pairs_hash,
366 -expires=>'+6M',
367 -path=>script_name(),
368 -domain=>server_name());
369 } elsif ( param("Cookie") eq "ClearCookie" ) {
370 $cookie = cookie( -name=>'FreeCheck',
371 -value=>'',
372 -expires=>'+1m',
373 -path=>script_name(),
374 -domain=>server_name());
375 }
376
377 # Generate the actual output.
378 # The PDF thing might become an option in the main script
379 # soon...
380 ###########################################
381 # WARNING WARNING WARNING WARNING WARNING #
382 ###########################################
383 # THIS CODE EXECUTES AT LEAST ONE EXTERNAL PROGRAM, BASED ON
384 # STRINGS PASSED IN FROM THE FORM. A FEEBLE EFFORT HAS BEEN
385 # MADE TO SANITIZE THOSE STRINGS, BUT THERE COULD STILL BE
386 # A SECURITY RISK HERE. YOU HAVE BEEN WARNED
387
388 if (param("OutputType") eq "PDF") {
389 $PDFConvert = "\| $GS $PDFOptions";
390 }
391
392 #print (`.\/freecheck --cgi \"$pairs_string\" $arguments \| $GS $PDFConvert`);
393 # This is just the postscript result, or the error:
394 $Result = `.\/freecheck --cgi \"$pairs_string\" $arguments`;
395
396 if (length($Result) < 500 ) { # Anything this short is an error...
397 print header;
398 print start_html("We encountered an error...");
399 print h1("There are some errors on your form:");
400 # HTML-ify the result ( \n to <br> )
401 $Result =~ s/\n/<br>/gsm;
402 print $Result;
403 print br;
404 print "Press the Back button on your browser to fix them...";
405 print p;
406 print em("If you select \"Print voided test checks\" then
407 MICR consistency checking will not be performed");
408 print end_html;
409 exit;
410 }
411
412 # Otherwise, generate the apropriate header...
413 # And send the data
414 if (param("OutputType") eq "PDF") {
415 print header( -type=>'application/pdf',
416 -attachment=>'mychecks.pdf',
417 -cookie=>$cookie);
418
419 # This is bad... running the script a 2nd time... must be a better
420 # way. Like open(PDF, "|$GS $PDFConvert
421 #open (PDF, "| $PDFConvert");
422 #print PDF $Result;
423 #close(PDF);
424
425 print (`.\/freecheck --cgi \"$pairs_string\" $arguments \| $GS $PDFOptions`);
426 } else {
427 print header( -type=>'application/postscript',
428 -attachment=>'mychecks.ps',
429 -cookie=>$cookie);
430
431 print $Result;
432 }
433
434 exit;
435}
436
437sub kill_input {
438 print header;
439 print start_html("Problem with those strings...");
440 print "You seem to have some shell metacharacters in your ";
441 print "entered strings. Sorry, you can't do that...";
442 print p;
443 print "Please get those funky things out of your form, and try again";
444 print p;
445 print "You can hit the back button to go back to your form.";
446 print end_html;
447 exit;
448}
449

Built with git-ssb-web