git ssb

0+

cel / freecheck



Tree: 13d9698d9bd7a27d73234d96206ed5fe86166381

Files: 13d9698d9bd7a27d73234d96206ed5fe86166381 / freecheck.cgi

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

Built with git-ssb-web