/[dtapublic]/to_be_filed/nixprojs/cron/2007/05/cc_kt1_auth_php/cc_kt1_auth_php.c
ViewVC logotype

Annotation of /to_be_filed/nixprojs/cron/2007/05/cc_kt1_auth_php/cc_kt1_auth_php.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 17 - (hide annotations) (download)
Sat Oct 8 04:11:18 2016 UTC (7 years, 4 months ago) by dashley
File MIME type: text/plain
File size: 103562 byte(s)
Initial commit.
1 dashley 17 //$Header: /home/dashley/cvsrep/e3ft_gpl01/e3ft_gpl01/nixprojs/cron/2007/05/cc_kt1_auth_php/cc_kt1_auth_php.c,v 1.11 2009/11/04 16:27:11 dashley Exp $
2     //-------------------------------------------------------------------------------------------------
3     //This source code and any program in which it is compiled/used is provided under the GNU GENERAL
4     //PUBLIC LICENSE, Version 3, full license text below.
5     //-------------------------------------------------------------------------------------------------
6     // GNU GENERAL PUBLIC LICENSE
7     // Version 3, 29 June 2007
8     //
9     // Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
10     // Everyone is permitted to copy and distribute verbatim copies
11     // of this license document, but changing it is not allowed.
12     //
13     // Preamble
14     //
15     // The GNU General Public License is a free, copyleft license for
16     //software and other kinds of works.
17     //
18     // The licenses for most software and other practical works are designed
19     //to take away your freedom to share and change the works. By contrast,
20     //the GNU General Public License is intended to guarantee your freedom to
21     //share and change all versions of a program--to make sure it remains free
22     //software for all its users. We, the Free Software Foundation, use the
23     //GNU General Public License for most of our software; it applies also to
24     //any other work released this way by its authors. You can apply it to
25     //your programs, too.
26     //
27     // When we speak of free software, we are referring to freedom, not
28     //price. Our General Public Licenses are designed to make sure that you
29     //have the freedom to distribute copies of free software (and charge for
30     //them if you wish), that you receive source code or can get it if you
31     //want it, that you can change the software or use pieces of it in new
32     //free programs, and that you know you can do these things.
33     //
34     // To protect your rights, we need to prevent others from denying you
35     //these rights or asking you to surrender the rights. Therefore, you have
36     //certain responsibilities if you distribute copies of the software, or if
37     //you modify it: responsibilities to respect the freedom of others.
38     //
39     // For example, if you distribute copies of such a program, whether
40     //gratis or for a fee, you must pass on to the recipients the same
41     //freedoms that you received. You must make sure that they, too, receive
42     //or can get the source code. And you must show them these terms so they
43     //know their rights.
44     //
45     // Developers that use the GNU GPL protect your rights with two steps:
46     //(1) assert copyright on the software, and (2) offer you this License
47     //giving you legal permission to copy, distribute and/or modify it.
48     //
49     // For the developers' and authors' protection, the GPL clearly explains
50     //that there is no warranty for this free software. For both users' and
51     //authors' sake, the GPL requires that modified versions be marked as
52     //changed, so that their problems will not be attributed erroneously to
53     //authors of previous versions.
54     //
55     // Some devices are designed to deny users access to install or run
56     //modified versions of the software inside them, although the manufacturer
57     //can do so. This is fundamentally incompatible with the aim of
58     //protecting users' freedom to change the software. The systematic
59     //pattern of such abuse occurs in the area of products for individuals to
60     //use, which is precisely where it is most unacceptable. Therefore, we
61     //have designed this version of the GPL to prohibit the practice for those
62     //products. If such problems arise substantially in other domains, we
63     //stand ready to extend this provision to those domains in future versions
64     //of the GPL, as needed to protect the freedom of users.
65     //
66     // Finally, every program is threatened constantly by software patents.
67     //States should not allow patents to restrict development and use of
68     //software on general-purpose computers, but in those that do, we wish to
69     //avoid the special danger that patents applied to a free program could
70     //make it effectively proprietary. To prevent this, the GPL assures that
71     //patents cannot be used to render the program non-free.
72     //
73     // The precise terms and conditions for copying, distribution and
74     //modification follow.
75     //
76     // TERMS AND CONDITIONS
77     //
78     // 0. Definitions.
79     //
80     // "This License" refers to version 3 of the GNU General Public License.
81     //
82     // "Copyright" also means copyright-like laws that apply to other kinds of
83     //works, such as semiconductor masks.
84     //
85     // "The Program" refers to any copyrightable work licensed under this
86     //License. Each licensee is addressed as "you". "Licensees" and
87     //"recipients" may be individuals or organizations.
88     //
89     // To "modify" a work means to copy from or adapt all or part of the work
90     //in a fashion requiring copyright permission, other than the making of an
91     //exact copy. The resulting work is called a "modified version" of the
92     //earlier work or a work "based on" the earlier work.
93     //
94     // A "covered work" means either the unmodified Program or a work based
95     //on the Program.
96     //
97     // To "propagate" a work means to do anything with it that, without
98     //permission, would make you directly or secondarily liable for
99     //infringement under applicable copyright law, except executing it on a
100     //computer or modifying a private copy. Propagation includes copying,
101     //distribution (with or without modification), making available to the
102     //public, and in some countries other activities as well.
103     //
104     // To "convey" a work means any kind of propagation that enables other
105     //parties to make or receive copies. Mere interaction with a user through
106     //a computer network, with no transfer of a copy, is not conveying.
107     //
108     // An interactive user interface displays "Appropriate Legal Notices"
109     //to the extent that it includes a convenient and prominently visible
110     //feature that (1) displays an appropriate copyright notice, and (2)
111     //tells the user that there is no warranty for the work (except to the
112     //extent that warranties are provided), that licensees may convey the
113     //work under this License, and how to view a copy of this License. If
114     //the interface presents a list of user commands or options, such as a
115     //menu, a prominent item in the list meets this criterion.
116     //
117     // 1. Source Code.
118     //
119     // The "source code" for a work means the preferred form of the work
120     //for making modifications to it. "Object code" means any non-source
121     //form of a work.
122     //
123     // A "Standard Interface" means an interface that either is an official
124     //standard defined by a recognized standards body, or, in the case of
125     //interfaces specified for a particular programming language, one that
126     //is widely used among developers working in that language.
127     //
128     // The "System Libraries" of an executable work include anything, other
129     //than the work as a whole, that (a) is included in the normal form of
130     //packaging a Major Component, but which is not part of that Major
131     //Component, and (b) serves only to enable use of the work with that
132     //Major Component, or to implement a Standard Interface for which an
133     //implementation is available to the public in source code form. A
134     //"Major Component", in this context, means a major essential component
135     //(kernel, window system, and so on) of the specific operating system
136     //(if any) on which the executable work runs, or a compiler used to
137     //produce the work, or an object code interpreter used to run it.
138     //
139     // The "Corresponding Source" for a work in object code form means all
140     //the source code needed to generate, install, and (for an executable
141     //work) run the object code and to modify the work, including scripts to
142     //control those activities. However, it does not include the work's
143     //System Libraries, or general-purpose tools or generally available free
144     //programs which are used unmodified in performing those activities but
145     //which are not part of the work. For example, Corresponding Source
146     //includes interface definition files associated with source files for
147     //the work, and the source code for shared libraries and dynamically
148     //linked subprograms that the work is specifically designed to require,
149     //such as by intimate data communication or control flow between those
150     //subprograms and other parts of the work.
151     //
152     // The Corresponding Source need not include anything that users
153     //can regenerate automatically from other parts of the Corresponding
154     //Source.
155     //
156     // The Corresponding Source for a work in source code form is that
157     //same work.
158     //
159     // 2. Basic Permissions.
160     //
161     // All rights granted under this License are granted for the term of
162     //copyright on the Program, and are irrevocable provided the stated
163     //conditions are met. This License explicitly affirms your unlimited
164     //permission to run the unmodified Program. The output from running a
165     //covered work is covered by this License only if the output, given its
166     //content, constitutes a covered work. This License acknowledges your
167     //rights of fair use or other equivalent, as provided by copyright law.
168     //
169     // You may make, run and propagate covered works that you do not
170     //convey, without conditions so long as your license otherwise remains
171     //in force. You may convey covered works to others for the sole purpose
172     //of having them make modifications exclusively for you, or provide you
173     //with facilities for running those works, provided that you comply with
174     //the terms of this License in conveying all material for which you do
175     //not control copyright. Those thus making or running the covered works
176     //for you must do so exclusively on your behalf, under your direction
177     //and control, on terms that prohibit them from making any copies of
178     //your copyrighted material outside their relationship with you.
179     //
180     // Conveying under any other circumstances is permitted solely under
181     //the conditions stated below. Sublicensing is not allowed; section 10
182     //makes it unnecessary.
183     //
184     // 3. Protecting Users' Legal Rights From Anti-Circumvention Law.
185     //
186     // No covered work shall be deemed part of an effective technological
187     //measure under any applicable law fulfilling obligations under article
188     //11 of the WIPO copyright treaty adopted on 20 December 1996, or
189     //similar laws prohibiting or restricting circumvention of such
190     //measures.
191     //
192     // When you convey a covered work, you waive any legal power to forbid
193     //circumvention of technological measures to the extent such circumvention
194     //is effected by exercising rights under this License with respect to
195     //the covered work, and you disclaim any intention to limit operation or
196     //modification of the work as a means of enforcing, against the work's
197     //users, your or third parties' legal rights to forbid circumvention of
198     //technological measures.
199     //
200     // 4. Conveying Verbatim Copies.
201     //
202     // You may convey verbatim copies of the Program's source code as you
203     //receive it, in any medium, provided that you conspicuously and
204     //appropriately publish on each copy an appropriate copyright notice;
205     //keep intact all notices stating that this License and any
206     //non-permissive terms added in accord with section 7 apply to the code;
207     //keep intact all notices of the absence of any warranty; and give all
208     //recipients a copy of this License along with the Program.
209     //
210     // You may charge any price or no price for each copy that you convey,
211     //and you may offer support or warranty protection for a fee.
212     //
213     // 5. Conveying Modified Source Versions.
214     //
215     // You may convey a work based on the Program, or the modifications to
216     //produce it from the Program, in the form of source code under the
217     //terms of section 4, provided that you also meet all of these conditions:
218     //
219     // a) The work must carry prominent notices stating that you modified
220     // it, and giving a relevant date.
221     //
222     // b) The work must carry prominent notices stating that it is
223     // released under this License and any conditions added under section
224     // 7. This requirement modifies the requirement in section 4 to
225     // "keep intact all notices".
226     //
227     // c) You must license the entire work, as a whole, under this
228     // License to anyone who comes into possession of a copy. This
229     // License will therefore apply, along with any applicable section 7
230     // additional terms, to the whole of the work, and all its parts,
231     // regardless of how they are packaged. This License gives no
232     // permission to license the work in any other way, but it does not
233     // invalidate such permission if you have separately received it.
234     //
235     // d) If the work has interactive user interfaces, each must display
236     // Appropriate Legal Notices; however, if the Program has interactive
237     // interfaces that do not display Appropriate Legal Notices, your
238     // work need not make them do so.
239     //
240     // A compilation of a covered work with other separate and independent
241     //works, which are not by their nature extensions of the covered work,
242     //and which are not combined with it such as to form a larger program,
243     //in or on a volume of a storage or distribution medium, is called an
244     //"aggregate" if the compilation and its resulting copyright are not
245     //used to limit the access or legal rights of the compilation's users
246     //beyond what the individual works permit. Inclusion of a covered work
247     //in an aggregate does not cause this License to apply to the other
248     //parts of the aggregate.
249     //
250     // 6. Conveying Non-Source Forms.
251     //
252     // You may convey a covered work in object code form under the terms
253     //of sections 4 and 5, provided that you also convey the
254     //machine-readable Corresponding Source under the terms of this License,
255     //in one of these ways:
256     //
257     // a) Convey the object code in, or embodied in, a physical product
258     // (including a physical distribution medium), accompanied by the
259     // Corresponding Source fixed on a durable physical medium
260     // customarily used for software interchange.
261     //
262     // b) Convey the object code in, or embodied in, a physical product
263     // (including a physical distribution medium), accompanied by a
264     // written offer, valid for at least three years and valid for as
265     // long as you offer spare parts or customer support for that product
266     // model, to give anyone who possesses the object code either (1) a
267     // copy of the Corresponding Source for all the software in the
268     // product that is covered by this License, on a durable physical
269     // medium customarily used for software interchange, for a price no
270     // more than your reasonable cost of physically performing this
271     // conveying of source, or (2) access to copy the
272     // Corresponding Source from a network server at no charge.
273     //
274     // c) Convey individual copies of the object code with a copy of the
275     // written offer to provide the Corresponding Source. This
276     // alternative is allowed only occasionally and noncommercially, and
277     // only if you received the object code with such an offer, in accord
278     // with subsection 6b.
279     //
280     // d) Convey the object code by offering access from a designated
281     // place (gratis or for a charge), and offer equivalent access to the
282     // Corresponding Source in the same way through the same place at no
283     // further charge. You need not require recipients to copy the
284     // Corresponding Source along with the object code. If the place to
285     // copy the object code is a network server, the Corresponding Source
286     // may be on a different server (operated by you or a third party)
287     // that supports equivalent copying facilities, provided you maintain
288     // clear directions next to the object code saying where to find the
289     // Corresponding Source. Regardless of what server hosts the
290     // Corresponding Source, you remain obligated to ensure that it is
291     // available for as long as needed to satisfy these requirements.
292     //
293     // e) Convey the object code using peer-to-peer transmission, provided
294     // you inform other peers where the object code and Corresponding
295     // Source of the work are being offered to the general public at no
296     // charge under subsection 6d.
297     //
298     // A separable portion of the object code, whose source code is excluded
299     //from the Corresponding Source as a System Library, need not be
300     //included in conveying the object code work.
301     //
302     // A "User Product" is either (1) a "consumer product", which means any
303     //tangible personal property which is normally used for personal, family,
304     //or household purposes, or (2) anything designed or sold for incorporation
305     //into a dwelling. In determining whether a product is a consumer product,
306     //doubtful cases shall be resolved in favor of coverage. For a particular
307     //product received by a particular user, "normally used" refers to a
308     //typical or common use of that class of product, regardless of the status
309     //of the particular user or of the way in which the particular user
310     //actually uses, or expects or is expected to use, the product. A product
311     //is a consumer product regardless of whether the product has substantial
312     //commercial, industrial or non-consumer uses, unless such uses represent
313     //the only significant mode of use of the product.
314     //
315     // "Installation Information" for a User Product means any methods,
316     //procedures, authorization keys, or other information required to install
317     //and execute modified versions of a covered work in that User Product from
318     //a modified version of its Corresponding Source. The information must
319     //suffice to ensure that the continued functioning of the modified object
320     //code is in no case prevented or interfered with solely because
321     //modification has been made.
322     //
323     // If you convey an object code work under this section in, or with, or
324     //specifically for use in, a User Product, and the conveying occurs as
325     //part of a transaction in which the right of possession and use of the
326     //User Product is transferred to the recipient in perpetuity or for a
327     //fixed term (regardless of how the transaction is characterized), the
328     //Corresponding Source conveyed under this section must be accompanied
329     //by the Installation Information. But this requirement does not apply
330     //if neither you nor any third party retains the ability to install
331     //modified object code on the User Product (for example, the work has
332     //been installed in ROM).
333     //
334     // The requirement to provide Installation Information does not include a
335     //requirement to continue to provide support service, warranty, or updates
336     //for a work that has been modified or installed by the recipient, or for
337     //the User Product in which it has been modified or installed. Access to a
338     //network may be denied when the modification itself materially and
339     //adversely affects the operation of the network or violates the rules and
340     //protocols for communication across the network.
341     //
342     // Corresponding Source conveyed, and Installation Information provided,
343     //in accord with this section must be in a format that is publicly
344     //documented (and with an implementation available to the public in
345     //source code form), and must require no special password or key for
346     //unpacking, reading or copying.
347     //
348     // 7. Additional Terms.
349     //
350     // "Additional permissions" are terms that supplement the terms of this
351     //License by making exceptions from one or more of its conditions.
352     //Additional permissions that are applicable to the entire Program shall
353     //be treated as though they were included in this License, to the extent
354     //that they are valid under applicable law. If additional permissions
355     //apply only to part of the Program, that part may be used separately
356     //under those permissions, but the entire Program remains governed by
357     //this License without regard to the additional permissions.
358     //
359     // When you convey a copy of a covered work, you may at your option
360     //remove any additional permissions from that copy, or from any part of
361     //it. (Additional permissions may be written to require their own
362     //removal in certain cases when you modify the work.) You may place
363     //additional permissions on material, added by you to a covered work,
364     //for which you have or can give appropriate copyright permission.
365     //
366     // Notwithstanding any other provision of this License, for material you
367     //add to a covered work, you may (if authorized by the copyright holders of
368     //that material) supplement the terms of this License with terms:
369     //
370     // a) Disclaiming warranty or limiting liability differently from the
371     // terms of sections 15 and 16 of this License; or
372     //
373     // b) Requiring preservation of specified reasonable legal notices or
374     // author attributions in that material or in the Appropriate Legal
375     // Notices displayed by works containing it; or
376     //
377     // c) Prohibiting misrepresentation of the origin of that material, or
378     // requiring that modified versions of such material be marked in
379     // reasonable ways as different from the original version; or
380     //
381     // d) Limiting the use for publicity purposes of names of licensors or
382     // authors of the material; or
383     //
384     // e) Declining to grant rights under trademark law for use of some
385     // trade names, trademarks, or service marks; or
386     //
387     // f) Requiring indemnification of licensors and authors of that
388     // material by anyone who conveys the material (or modified versions of
389     // it) with contractual assumptions of liability to the recipient, for
390     // any liability that these contractual assumptions directly impose on
391     // those licensors and authors.
392     //
393     // All other non-permissive additional terms are considered "further
394     //restrictions" within the meaning of section 10. If the Program as you
395     //received it, or any part of it, contains a notice stating that it is
396     //governed by this License along with a term that is a further
397     //restriction, you may remove that term. If a license document contains
398     //a further restriction but permits relicensing or conveying under this
399     //License, you may add to a covered work material governed by the terms
400     //of that license document, provided that the further restriction does
401     //not survive such relicensing or conveying.
402     //
403     // If you add terms to a covered work in accord with this section, you
404     //must place, in the relevant source files, a statement of the
405     //additional terms that apply to those files, or a notice indicating
406     //where to find the applicable terms.
407     //
408     // Additional terms, permissive or non-permissive, may be stated in the
409     //form of a separately written license, or stated as exceptions;
410     //the above requirements apply either way.
411     //
412     // 8. Termination.
413     //
414     // You may not propagate or modify a covered work except as expressly
415     //provided under this License. Any attempt otherwise to propagate or
416     //modify it is void, and will automatically terminate your rights under
417     //this License (including any patent licenses granted under the third
418     //paragraph of section 11).
419     //
420     // However, if you cease all violation of this License, then your
421     //license from a particular copyright holder is reinstated (a)
422     //provisionally, unless and until the copyright holder explicitly and
423     //finally terminates your license, and (b) permanently, if the copyright
424     //holder fails to notify you of the violation by some reasonable means
425     //prior to 60 days after the cessation.
426     //
427     // Moreover, your license from a particular copyright holder is
428     //reinstated permanently if the copyright holder notifies you of the
429     //violation by some reasonable means, this is the first time you have
430     //received notice of violation of this License (for any work) from that
431     //copyright holder, and you cure the violation prior to 30 days after
432     //your receipt of the notice.
433     //
434     // Termination of your rights under this section does not terminate the
435     //licenses of parties who have received copies or rights from you under
436     //this License. If your rights have been terminated and not permanently
437     //reinstated, you do not qualify to receive new licenses for the same
438     //material under section 10.
439     //
440     // 9. Acceptance Not Required for Having Copies.
441     //
442     // You are not required to accept this License in order to receive or
443     //run a copy of the Program. Ancillary propagation of a covered work
444     //occurring solely as a consequence of using peer-to-peer transmission
445     //to receive a copy likewise does not require acceptance. However,
446     //nothing other than this License grants you permission to propagate or
447     //modify any covered work. These actions infringe copyright if you do
448     //not accept this License. Therefore, by modifying or propagating a
449     //covered work, you indicate your acceptance of this License to do so.
450     //
451     // 10. Automatic Licensing of Downstream Recipients.
452     //
453     // Each time you convey a covered work, the recipient automatically
454     //receives a license from the original licensors, to run, modify and
455     //propagate that work, subject to this License. You are not responsible
456     //for enforcing compliance by third parties with this License.
457     //
458     // An "entity transaction" is a transaction transferring control of an
459     //organization, or substantially all assets of one, or subdividing an
460     //organization, or merging organizations. If propagation of a covered
461     //work results from an entity transaction, each party to that
462     //transaction who receives a copy of the work also receives whatever
463     //licenses to the work the party's predecessor in interest had or could
464     //give under the previous paragraph, plus a right to possession of the
465     //Corresponding Source of the work from the predecessor in interest, if
466     //the predecessor has it or can get it with reasonable efforts.
467     //
468     // You may not impose any further restrictions on the exercise of the
469     //rights granted or affirmed under this License. For example, you may
470     //not impose a license fee, royalty, or other charge for exercise of
471     //rights granted under this License, and you may not initiate litigation
472     //(including a cross-claim or counterclaim in a lawsuit) alleging that
473     //any patent claim is infringed by making, using, selling, offering for
474     //sale, or importing the Program or any portion of it.
475     //
476     // 11. Patents.
477     //
478     // A "contributor" is a copyright holder who authorizes use under this
479     //License of the Program or a work on which the Program is based. The
480     //work thus licensed is called the contributor's "contributor version".
481     //
482     // A contributor's "essential patent claims" are all patent claims
483     //owned or controlled by the contributor, whether already acquired or
484     //hereafter acquired, that would be infringed by some manner, permitted
485     //by this License, of making, using, or selling its contributor version,
486     //but do not include claims that would be infringed only as a
487     //consequence of further modification of the contributor version. For
488     //purposes of this definition, "control" includes the right to grant
489     //patent sublicenses in a manner consistent with the requirements of
490     //this License.
491     //
492     // Each contributor grants you a non-exclusive, worldwide, royalty-free
493     //patent license under the contributor's essential patent claims, to
494     //make, use, sell, offer for sale, import and otherwise run, modify and
495     //propagate the contents of its contributor version.
496     //
497     // In the following three paragraphs, a "patent license" is any express
498     //agreement or commitment, however denominated, not to enforce a patent
499     //(such as an express permission to practice a patent or covenant not to
500     //sue for patent infringement). To "grant" such a patent license to a
501     //party means to make such an agreement or commitment not to enforce a
502     //patent against the party.
503     //
504     // If you convey a covered work, knowingly relying on a patent license,
505     //and the Corresponding Source of the work is not available for anyone
506     //to copy, free of charge and under the terms of this License, through a
507     //publicly available network server or other readily accessible means,
508     //then you must either (1) cause the Corresponding Source to be so
509     //available, or (2) arrange to deprive yourself of the benefit of the
510     //patent license for this particular work, or (3) arrange, in a manner
511     //consistent with the requirements of this License, to extend the patent
512     //license to downstream recipients. "Knowingly relying" means you have
513     //actual knowledge that, but for the patent license, your conveying the
514     //covered work in a country, or your recipient's use of the covered work
515     //in a country, would infringe one or more identifiable patents in that
516     //country that you have reason to believe are valid.
517     //
518     // If, pursuant to or in connection with a single transaction or
519     //arrangement, you convey, or propagate by procuring conveyance of, a
520     //covered work, and grant a patent license to some of the parties
521     //receiving the covered work authorizing them to use, propagate, modify
522     //or convey a specific copy of the covered work, then the patent license
523     //you grant is automatically extended to all recipients of the covered
524     //work and works based on it.
525     //
526     // A patent license is "discriminatory" if it does not include within
527     //the scope of its coverage, prohibits the exercise of, or is
528     //conditioned on the non-exercise of one or more of the rights that are
529     //specifically granted under this License. You may not convey a covered
530     //work if you are a party to an arrangement with a third party that is
531     //in the business of distributing software, under which you make payment
532     //to the third party based on the extent of your activity of conveying
533     //the work, and under which the third party grants, to any of the
534     //parties who would receive the covered work from you, a discriminatory
535     //patent license (a) in connection with copies of the covered work
536     //conveyed by you (or copies made from those copies), or (b) primarily
537     //for and in connection with specific products or compilations that
538     //contain the covered work, unless you entered into that arrangement,
539     //or that patent license was granted, prior to 28 March 2007.
540     //
541     // Nothing in this License shall be construed as excluding or limiting
542     //any implied license or other defenses to infringement that may
543     //otherwise be available to you under applicable patent law.
544     //
545     // 12. No Surrender of Others' Freedom.
546     //
547     // If conditions are imposed on you (whether by court order, agreement or
548     //otherwise) that contradict the conditions of this License, they do not
549     //excuse you from the conditions of this License. If you cannot convey a
550     //covered work so as to satisfy simultaneously your obligations under this
551     //License and any other pertinent obligations, then as a consequence you may
552     //not convey it at all. For example, if you agree to terms that obligate you
553     //to collect a royalty for further conveying from those to whom you convey
554     //the Program, the only way you could satisfy both those terms and this
555     //License would be to refrain entirely from conveying the Program.
556     //
557     // 13. Use with the GNU Affero General Public License.
558     //
559     // Notwithstanding any other provision of this License, you have
560     //permission to link or combine any covered work with a work licensed
561     //under version 3 of the GNU Affero General Public License into a single
562     //combined work, and to convey the resulting work. The terms of this
563     //License will continue to apply to the part which is the covered work,
564     //but the special requirements of the GNU Affero General Public License,
565     //section 13, concerning interaction through a network will apply to the
566     //combination as such.
567     //
568     // 14. Revised Versions of this License.
569     //
570     // The Free Software Foundation may publish revised and/or new versions of
571     //the GNU General Public License from time to time. Such new versions will
572     //be similar in spirit to the present version, but may differ in detail to
573     //address new problems or concerns.
574     //
575     // Each version is given a distinguishing version number. If the
576     //Program specifies that a certain numbered version of the GNU General
577     //Public License "or any later version" applies to it, you have the
578     //option of following the terms and conditions either of that numbered
579     //version or of any later version published by the Free Software
580     //Foundation. If the Program does not specify a version number of the
581     //GNU General Public License, you may choose any version ever published
582     //by the Free Software Foundation.
583     //
584     // If the Program specifies that a proxy can decide which future
585     //versions of the GNU General Public License can be used, that proxy's
586     //public statement of acceptance of a version permanently authorizes you
587     //to choose that version for the Program.
588     //
589     // Later license versions may give you additional or different
590     //permissions. However, no additional obligations are imposed on any
591     //author or copyright holder as a result of your choosing to follow a
592     //later version.
593     //
594     // 15. Disclaimer of Warranty.
595     //
596     // THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
597     //APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
598     //HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
599     //OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
600     //THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
601     //PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
602     //IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
603     //ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
604     //
605     // 16. Limitation of Liability.
606     //
607     // IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
608     //WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
609     //THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
610     //GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
611     //USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
612     //DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
613     //PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
614     //EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
615     //SUCH DAMAGES.
616     //
617     // 17. Interpretation of Sections 15 and 16.
618     //
619     // If the disclaimer of warranty and limitation of liability provided
620     //above cannot be given local legal effect according to their terms,
621     //reviewing courts shall apply local law that most closely approximates
622     //an absolute waiver of all civil liability in connection with the
623     //Program, unless a warranty or assumption of liability accompanies a
624     //copy of the Program in return for a fee.
625     //
626     // END OF TERMS AND CONDITIONS
627     //
628     // How to Apply These Terms to Your New Programs
629     //
630     // If you develop a new program, and you want it to be of the greatest
631     //possible use to the public, the best way to achieve this is to make it
632     //free software which everyone can redistribute and change under these terms.
633     //
634     // To do so, attach the following notices to the program. It is safest
635     //to attach them to the start of each source file to most effectively
636     //state the exclusion of warranty; and each file should have at least
637     //the "copyright" line and a pointer to where the full notice is found.
638     //
639     // <one line to give the program's name and a brief idea of what it does.>
640     // Copyright (C) <year> <name of author>
641     //
642     // This program is free software: you can redistribute it and/or modify
643     // it under the terms of the GNU General Public License as published by
644     // the Free Software Foundation, either version 3 of the License, or
645     // (at your option) any later version.
646     //
647     // This program is distributed in the hope that it will be useful,
648     // but WITHOUT ANY WARRANTY; without even the implied warranty of
649     // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
650     // GNU General Public License for more details.
651     //
652     // You should have received a copy of the GNU General Public License
653     // along with this program. If not, see <http://www.gnu.org/licenses/>.
654     //
655     //Also add information on how to contact you by electronic and paper mail.
656     //
657     // If the program does terminal interaction, make it output a short
658     //notice like this when it starts in an interactive mode:
659     //
660     // <program> Copyright (C) <year> <name of author>
661     // This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
662     // This is free software, and you are welcome to redistribute it
663     // under certain conditions; type `show c' for details.
664     //
665     //The hypothetical commands `show w' and `show c' should show the appropriate
666     //parts of the General Public License. Of course, your program's commands
667     //might be different; for a GUI interface, you would use an "about box".
668     //
669     // You should also get your employer (if you work as a programmer) or school,
670     //if any, to sign a "copyright disclaimer" for the program, if necessary.
671     //For more information on this, and how to apply and follow the GNU GPL, see
672     //<http://www.gnu.org/licenses/>.
673     //
674     // The GNU General Public License does not permit incorporating your program
675     //into proprietary programs. If your program is a subroutine library, you
676     //may consider it more useful to permit linking proprietary applications with
677     //the library. If this is what you want to do, use the GNU Lesser General
678     //Public License instead of this License. But first, please read
679     //<http://www.gnu.org/philosophy/why-not-lgpl.html>.
680     //-------------------------------------------------------------------------------------------------
681     //------------------------------------------------------------------------
682     //cc_kt1_auth_php.c : A program to authenticate the CryptoCard KT-1
683     // keychain token from the PHP scripting language.
684     //
685     //Copyright (C)2007-2009 David T. Ashley (dashley@gmail.com).
686     //
687     //This program is free software; you can redistribute it and/or modify
688     //it under the terms of the GNU General Public License as published by
689     //the Free Software Foundation; either version 2 of the License, or
690     //(at your option) any later version.
691     //
692     //This program is distributed in the hope that it will be useful,
693     //but WITHOUT ANY WARRANTY; without even the implied warranty of
694     //MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
695     //GNU General Public License for more details.
696     //
697     //You should have received a copy of the GNU General Public License along
698     //with this program; if not, write to the Free Software Foundation, Inc.,
699     //51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
700     //
701     //The GPL, Version 2, is included in its entirety at the end of this
702     //source file.
703     //------------------------------------------------------------------------
704     //GENERAL DESCRIPTION
705     //-------------------
706     //This program is designed to be called from a PHP script and will use
707     //the AuthEngine SDK library provided by CryptoCard to verify whether an
708     //OTP (one-time password) value supplied to the program was plausibly
709     //obtained from a CryptoCard KT-1 token using certain options. It is
710     //assumed that input to the program comes from stdin and that output
711     //should be written to stdout (both presumed to be set up as pipes by the
712     //invoking PHP script).
713     //
714     //This program is designed to operate on *nix systems only and, although
715     //it can probably be ported with no or few source code changes, due to
716     //the technical complexities, I cannot support the use of this program
717     //on other operating systems.
718     //------------------------------------------------------------------------
719     //COMPILATION AND INSTALLATION INSTRUCTIONS
720     //-----------------------------------------
721     // a)Obtain the library (libAuthentication.so) from CryptoCard and
722     // install it as recommended on your *nix system. (The recommended
723     // contact at CryptoCard is Bill LaHam.)
724     //
725     // b)Place this file (cc_kt1_auth_php.c) and the header file from
726     // CryptoCard (Authentication.h) is a working directory of your
727     // choosing.
728     //
729     // c)Compile the program using the command:
730     //
731     // gcc -L. -lAuthentication -occ_kt1_auth_php cc_kt1_auth_php.c
732     //
733     // As an alternative, for development only (not for use from a PHP
734     // script), the program can be compiled with the PG_DEBUG preprocessor
735     // option:
736     //
737     // gcc -L. -lAuthentication -occ_kt1_auth_php -DPG_DEBUG cc_kt1_auth_php.c
738     //
739     // The PG_DEBUG option causes the program to emit much intermediate
740     // information; but this is useful for development or debugging only.
741     //
742     // If there are errors from the compilation to the effect that
743     // "libcrypto.so.4" is missing, it may be necessary to install
744     // openssl-0.9.7a (typically "yum install openssl097a" on a
745     // RedHat system). Recompilation should then be attempted again to
746     // determine if the error is resolved.
747     //
748     // d)Copy the executable (cc_kt1_auth_php) to a location suitable for
749     // invocation from a PHP script and set ownership and permissions
750     // appropriately. "/usr/local/bin" is a suitable location on most
751     // systems.
752     //
753     // e)Set permissions appropriately on the executable. Because disclosure
754     // of the algorithms contained in the CryptoCard library is not a
755     // security risk (these are standard algorithms), there is no reason
756     // that the executable cannot be executable by all. The recommended
757     // ownership with be root:root with permissions r-xr-xr-x ("555").
758     //
759     //Note that this program can be easily tested by file redirection or
760     //by typing input from the console. It will treat stdin and stdout
761     //the same way whether they are pipes or files.
762     //------------------------------------------------------------------------
763     //REQUIRED CRYPTOCARD KT-1 TOKEN SETUP
764     //------------------------------------
765     //The token options used were never analyzed. The default options in
766     //the example initialization program from CryptoCard proved adequate.
767     //
768     //These options are:
769     //
770     // char options[] = {0xB0, 0x9B, 0x83, 0x28, 0x00, 0x00, 0x00, 0x00};
771     //
772     //These seemed to cause the token to operate in an intuitively obvious
773     //manner, and so no further investigation was required. CryptoCard
774     //does provide a document that describes what each bitfield means.
775     //
776     //If anyone would like to reverse-engineer these options and provide
777     //a text description that I can include in this file, please e-mail
778     //me.
779     //
780     //Also, if anyone would like to modify the program to accept token
781     //options, please e-mail me.
782     //------------------------------------------------------------------------
783     //FORMAT OF STDIN
784     //---------------
785     //For simplicity, the arguments via stdin are one per line, each prefixed
786     //with a symbolic tag and a colon. The arguments may appear in any order.
787     //Certain arguments are mandatory (such as the token key), and failing to
788     //supply these arguments will cause this program to declare an unsuccessful
789     //authentication. Other arguments are optional. This program will make
790     //sensible default assumptions about any missing arguments, and will also
791     //modify its behavior somewhat based on which arguments are supplied and
792     //which are not.
793     //
794     //This program authenticates in two fundamental modes:
795     //
796     // OTP: The key, challenge, and OTP are supplied. The key must be
797     // maintained by the PHP application (typically in a database, and
798     // typically encrypted), the challenge is state information that must
799     // be maintained by the PHP script as well, and the OTP is the value
800     // displayed on the token. This program will supply the updated
801     // challenge back to the caller.
802     //
803     // RESYNC: The key, resync string, and OTP are supplied. In this
804     // case, the program will generate the challenge per the behavior
805     // of the token, then authenticate.
806     //
807     //This program determines which mode of operation based on the input
808     //lines supplied to stding.
809     //
810     //The allowable input arguments are:
811     //
812     //TOKEN_KEY: The token key is a hexadecimal representation of the 192-bit
813     //AES-192 key believed to reside in the token. This must consist of
814     //exactly 48 hexadecimal digits. This argument is always required.
815     //
816     //OTP: The 8-character OTP purported to be supplied by the token.
817     //This argument is always required.
818     //
819     //CHALLENGE: The 128-bit incrementing state believed to reside in the
820     //token. This must consist of exactly 32 hexadecimal digits. This
821     //argument is required unless the RESYNC_STRING is supplied (in which case
822     //it is ignored).
823     //
824     //RESYNC_STRING: An 8-digit numeric value that has been supplied to the
825     //token user with instructions to resynchronize the token and to provide
826     //OTP displayed. This value is optional. If this value is
827     //supplied, the challenge output of the program (the conjectured internal
828     //state of the token if the user has followed instructions) will reflect
829     //the string. If this value is not supplied, the challenge will be
830     //incremented as the token does automatically when the front panel button
831     //is pressed to obtain a new OTP.
832     //
833     //OTP_WINDOW: The number of sequential OTPs that this program will test
834     //against the supplied OTP (if a match is found, this program will
835     //indicate where in the window the match lies). The calling PHP script
836     //may implement inner window and outer window functionality using this
837     //parameter. The value of 1 (for example) corresponds to the program
838     //accepting only the expected next value of the token. The value of
839     //2 (for example) corresponds to the program accepting either the
840     //expected next value or the value after that. This parameter is optional,
841     //and a default value of 1 will be used internally if it is not supplied.
842     //------------------------------------------------------------------------
843     //FORMAT OF STDOUT
844     //----------------
845     //For simplicity, the arguments via stdout are one per line, each prefixed
846     //with a symbolic tag and a colon. All arguments will be supplied. No
847     //guarantee is made about the order (the PHP script must parse the lines).
848     //
849     //The arguments that will be provided are described below.
850     //
851     //MAJOR_RESULT: This will be a integer string, with an optional leading
852     //"-", indicating the major result of the call. The possible values are:
853     //
854     // -3 : Internal program error (anything unexpected, particularly
855     // inability to allocate memory).
856     //
857     // -2 : The input arguments to the program were syntactically defective.
858     // No authentication attempt could be made.
859     //
860     // -1 : Authentication failed. The OTP was not within the OTP_WINDOW
861     // specified.
862     //
863     // >=0 : The OTP supplied matched at least one entry in the OTP_WINDOW.
864     // The non-negative integer returned indicates which entry.
865     // 0 corresponds to the first (normally expected) entry, 1
866     // corresponds to the second, etc. This value cannot exceed
867     // OTP_WINDOW - 1.
868     //
869     //CHALLENGE: If MAJOR_RESULT is -2 or -1, the input challenge will be
870     //supplied as output. If MAJOR_RESULT >= 0, the output will be the
871     //challenge corresponding to the matched OTP, incremented and ready
872     //for the next authentication.
873     //
874     //(Note: If a RESYNC_STRING was supplied, the rules above don't change,
875     //except that the first OTP checked against is what would be expected
876     //if the token is properly resynchronized. It is most common to use
877     //OTP_WINDOW=1 when a RESYNC_STRING is supplied, so that only the single
878     //expected OTP based on the RESYNC_STRING will be checked against.)
879     //------------------------------------------------------------------------
880     #include <stdio.h>
881     #include <stdlib.h>
882     #include <string.h>
883     #include <time.h>
884    
885     #include "Authentication.h"
886    
887     #define PG_BUFSIZE (50000)
888     //The buffer size used for both buffering all of stdin, and for each
889     //string. Memory is so big these days, so programming large doesn't
890     //seem to be a disadvantage.
891     //
892     //Additionally, allocated memory is not free()'d, ever. The reason for this
893     //is that when the process terminates, it all gets released, so
894     //no advantage to free()'ing.
895    
896     //Define FALSE and/or TRUE if they haven't been defined somewhere already.
897     //
898     #ifndef TRUE
899     #define TRUE (1)
900     #endif
901    
902     #ifndef FALSE
903     #define FALSE (0)
904     #endif
905    
906    
907     //*******************************************************************************
908     //*** DEBUG FORMATTING/OUTPUT FUNCTIONS *****************************************
909     //*******************************************************************************
910     //
911     //Dumps a thin line to stdout.
912     void PG_hline_thin(void)
913     {
914     printf("---------------------------------------------------------------\n");
915     }
916    
917    
918     //Dumps a thick line to stdout.
919     void PG_hline_thick(void)
920     {
921     printf("===============================================================\n");
922     }
923    
924    
925     //*******************************************************************************
926     //*** FORMATTED DATA OUTPUT FUNCTIONS *******************************************
927     //*******************************************************************************
928     //
929     //Outputs a byte array to stdout.
930     //
931     void PG_byte_array_output(unsigned char *a, int len)
932     {
933     int i;
934    
935     for (i=0; i<len; i++)
936     printf("%02X", a[i]);
937     }
938    
939    
940     //*******************************************************************************
941     //*** CHARACTER FUNCTIONS *******************************************************
942     //*******************************************************************************
943     //
944     //Returns TRUE if the passed character is a valid decimal digit,
945     //or FALSE otherwise.
946     //
947     int PG_is_decimal_digit(unsigned char arg)
948     {
949     int rv;
950    
951     switch (arg)
952     {
953     case '0':
954     case '1':
955     case '2':
956     case '3':
957     case '4':
958     case '5':
959     case '6':
960     case '7':
961     case '8':
962     case '9':
963     rv = TRUE;
964     break;
965     default:
966     rv = FALSE;
967     break;
968     }
969    
970     return(rv);
971     }
972    
973    
974     //Returns the value of the passed character decimal digit.
975     //0 is returned in the case of not a decimal digit.
976     //
977     int PG_decimal_digit_val(unsigned char arg)
978     {
979     int rv;
980    
981     switch (arg)
982     {
983     case '0':
984     rv = 0;
985     break;
986     case '1':
987     rv = 1;
988     break;
989     case '2':
990     rv = 2;
991     break;
992     case '3':
993     rv = 3;
994     break;
995     case '4':
996     rv = 4;
997     break;
998     case '5':
999     rv = 5;
1000     break;
1001     case '6':
1002     rv = 6;
1003     break;
1004     case '7':
1005     rv = 7;
1006     break;
1007     case '8':
1008     rv = 8;
1009     break;
1010     case '9':
1011     rv = 9;
1012     break;
1013     default:
1014     rv = 0;
1015     break;
1016     }
1017    
1018     return(rv);
1019     }
1020     //
1021     //
1022     //Returns TRUE if the passed character is a valid hexadecimal digit,
1023     //or FALSE otherwise.
1024     int PG_is_hex_digit(unsigned char arg)
1025     {
1026     int rv;
1027    
1028     switch (arg)
1029     {
1030     case '0':
1031     case '1':
1032     case '2':
1033     case '3':
1034     case '4':
1035     case '5':
1036     case '6':
1037     case '7':
1038     case '8':
1039     case '9':
1040     case 'a':
1041     case 'b':
1042     case 'c':
1043     case 'd':
1044     case 'e':
1045     case 'f':
1046     case 'A':
1047     case 'B':
1048     case 'C':
1049     case 'D':
1050     case 'E':
1051     case 'F':
1052     rv = TRUE;
1053     break;
1054     default:
1055     rv = FALSE;
1056     break;
1057     }
1058    
1059     return(rv);
1060     }
1061    
1062    
1063     //Returns the value of the passed hexadecimal digit.
1064     //0 is returned in the case of not a hex digit.
1065     int PG_hex_digit_val(unsigned char arg)
1066     {
1067     int rv;
1068    
1069     switch (arg)
1070     {
1071     case '0':
1072     rv = 0;
1073     break;
1074     case '1':
1075     rv = 1;
1076     break;
1077     case '2':
1078     rv = 2;
1079     break;
1080     case '3':
1081     rv = 3;
1082     break;
1083     case '4':
1084     rv = 4;
1085     break;
1086     case '5':
1087     rv = 5;
1088     break;
1089     case '6':
1090     rv = 6;
1091     break;
1092     case '7':
1093     rv = 7;
1094     break;
1095     case '8':
1096     rv = 8;
1097     break;
1098     case '9':
1099     rv = 9;
1100     break;
1101     case 'a':
1102     case 'A':
1103     rv = 10;
1104     break;
1105     case 'b':
1106     case 'B':
1107     rv = 11;
1108     break;
1109     case 'c':
1110     case 'C':
1111     rv = 12;
1112     break;
1113     case 'd':
1114     case 'D':
1115     rv = 13;
1116     break;
1117     case 'e':
1118     case 'E':
1119     rv = 14;
1120     break;
1121     case 'f':
1122     case 'F':
1123     rv = 15;
1124     break;
1125     default:
1126     rv = 0;
1127     break;
1128     }
1129    
1130     return(rv);
1131     }
1132     //
1133     //
1134     //Converts from a lower-case letter to an upper-case letter.
1135     //Characters that are not a lower-case letter are left alone.
1136     //
1137     unsigned char PG_char_to_upper(unsigned char arg)
1138     {
1139     switch (arg)
1140     {
1141     case 'a':
1142     return('A');
1143     break;
1144     case 'b':
1145     return('B');
1146     break;
1147     case 'c':
1148     return('C');
1149     break;
1150     case 'd':
1151     return('D');
1152     break;
1153     case 'e':
1154     return('E');
1155     break;
1156     case 'f':
1157     return('F');
1158     break;
1159     case 'g':
1160     return('G');
1161     break;
1162     case 'h':
1163     return('H');
1164     break;
1165     case 'i':
1166     return('I');
1167     break;
1168     case 'j':
1169     return('J');
1170     break;
1171     case 'k':
1172     return('K');
1173     break;
1174     case 'l':
1175     return('L');
1176     break;
1177     case 'm':
1178     return('M');
1179     break;
1180     case 'n':
1181     return('N');
1182     break;
1183     case 'o':
1184     return('O');
1185     break;
1186     case 'p':
1187     return('P');
1188     break;
1189     case 'q':
1190     return('Q');
1191     break;
1192     case 'r':
1193     return('R');
1194     break;
1195     case 's':
1196     return('S');
1197     break;
1198     case 't':
1199     return('T');
1200     break;
1201     case 'u':
1202     return('U');
1203     break;
1204     case 'v':
1205     return('V');
1206     break;
1207     case 'w':
1208     return('W');
1209     break;
1210     case 'x':
1211     return('X');
1212     break;
1213     case 'y':
1214     return('Y');
1215     break;
1216     case 'z':
1217     return('Z');
1218     break;
1219     default:
1220     return(arg);
1221     break;
1222     }
1223     }
1224     //
1225     //
1226     //*******************************************************************************
1227     //*** STRING FUNCTIONS **********************************************************
1228     //*******************************************************************************
1229     //
1230     //Deletes the first character of a string. If the string is zero length,
1231     //nothing is deleted.
1232     //
1233     void PG_str_first_char_delete(unsigned char *s)
1234     {
1235     int idx = 0;
1236    
1237     if (*s)
1238     {
1239     do
1240     {
1241     idx++;
1242     s[idx - 1] = s[idx];
1243     }
1244     while (s[idx]);
1245     }
1246     }
1247     //
1248     //
1249     //Deletes a number of characters from the start of a string. The string will not be taken
1250     //below zero length.
1251     //
1252     void PG_str_n_char_delete(unsigned char *s, int n)
1253     {
1254     while (n)
1255     {
1256     PG_str_first_char_delete(s);
1257     n--;
1258     }
1259     }
1260     //
1261     //
1262     //Returns TRUE if a string contains characters all consistent with hexadecimal
1263     //digits, or FALSE otherwise.
1264     //
1265     int PG_str_is_all_hex_chars(unsigned char *s)
1266     {
1267     int len, i;
1268    
1269     len = strlen(s);
1270    
1271     for (i=0; i<len; i++)
1272     {
1273     if (! PG_is_hex_digit(s[i]))
1274     return(FALSE);
1275     }
1276    
1277     return(TRUE);
1278     }
1279     //
1280     //
1281     //Translates from a zero-terminated hexadecimal string to an array of bytes.
1282     //They are assigned from [0] and then to ascending indices. The allocated
1283     //memory must be adequate to hold the data.
1284     //
1285     void PG_str_to_uchar_array(unsigned char *s, unsigned char *a)
1286     {
1287     int len, i;
1288    
1289     len = strlen(s);
1290    
1291     if ((len == 0) || ((len & 1) != 0)) //Can't be zero, can't be odd.
1292     return;
1293    
1294     for (i=0; i<(len/2); i++)
1295     {
1296     a[i] = 0;
1297     }
1298    
1299     //printf("PT1\n");
1300    
1301     for (i=0; i<len; i++)
1302     {
1303     if ((i & 1) == 0)
1304     {
1305     //MSB
1306     a[i/2] |= (PG_hex_digit_val(s[i]) << 4);
1307     }
1308     else
1309     {
1310     //MSB
1311     a[i/2] |= (PG_hex_digit_val(s[i]));
1312     }
1313     }
1314     }
1315     //
1316     //
1317     //Converts any lower-case letters in a string to upper-case.
1318     //
1319     void PG_str_to_upper(unsigned char *s)
1320     {
1321     int i, len;
1322    
1323     len = strlen(s);
1324    
1325     for (i=0; i<len; i++)
1326     {
1327     s[i] = PG_char_to_upper(s[i]);
1328     }
1329     }
1330     //
1331     //
1332     //Sanitizes a string (in place) to contain only characters from the
1333     //allowed set. Invalid characters are removed, and the string (processed
1334     //in-place) will be the same length or shorter.
1335     //
1336     void PG_string_sanitize(unsigned char *s, const unsigned char *allowed_set)
1337     {
1338     unsigned char *getptr, *putptr;
1339    
1340     getptr = putptr = s;
1341    
1342     while (*getptr)
1343     {
1344     if (strchr(allowed_set, *getptr) != NULL)
1345     {
1346     //The character was found in the allowed set. Copy it over.
1347     *putptr = *getptr;
1348     putptr++;
1349     }
1350     else
1351     {
1352     //The character wasn't found. Don't copy it.
1353     }
1354    
1355     getptr++;
1356     }
1357    
1358     //Terminate the potentially shortened string.
1359     *putptr = 0;
1360     }
1361     //
1362     //
1363     //*******************************************************************************
1364     //*** STDIN BUFFERING FUNCTIONS *************************************************
1365     //*******************************************************************************
1366     //
1367     //Will buffer all of stdin into a buffer, dynamically allocated, returned.
1368     //On error, NULL is returned. Any extra characters left in stdin
1369     //will be read and discarded.
1370     //
1371     //For simplicity, the string returned is zero-terminated. This means that
1372     //any 0's in the input will interfere with the interpretation of the string.
1373     //However, no catastrophic consequences, so no effort put into preventing this.
1374     //There shouldn't be any 0's in the input, anyway.
1375     //
1376     unsigned char *PG_buffer_stdin(void)
1377     {
1378     unsigned char *p;
1379     int i;
1380     int c;
1381    
1382     p = malloc(PG_BUFSIZE);
1383    
1384     if (!p)
1385     return(NULL);
1386    
1387     i = 0;
1388    
1389     do
1390     {
1391     c = fgetc(stdin);
1392     if (c == EOF)
1393     {
1394     p[i] = 0;
1395     break;
1396     }
1397     else
1398     {
1399     p[i] = c;
1400     }
1401    
1402     i++;
1403     } while (i < PG_BUFSIZE);
1404    
1405     p[PG_BUFSIZE - 1] = 0; //Just in case read to the end.
1406    
1407     //Consume the rest of stdin.
1408     while (! feof(stdin))
1409     fgetc(stdin);
1410    
1411     return(p);
1412     }
1413    
1414     //
1415     //Splits the stdin string into its lines. An array of pointers
1416     //is returned, terminated by a NULL pointer. In the case of an error,
1417     //the master pointer is NULL. Empty lines are discarded. The newline
1418     //characters are discarded.
1419     //
1420     unsigned char **PG_line_split(unsigned char *str_stdin)
1421     {
1422     int n_in_array = 0;
1423     //Number of entries in array, including the terminating NULL.
1424     unsigned char **rv = NULL;
1425     //Pointer to array of pointers to be returned to caller.
1426     unsigned char *cur = NULL;
1427     //Current line buffer.
1428     int getpos = 0, putpos = 0;
1429     //Position in the from array, current line at which copying
1430     //is occurring.
1431     int eolpos = 0;
1432     //Newline, \0, or one past the end of array at which the current line ends.
1433     int da_end = FALSE;
1434     //This is true if we're done.
1435     int i;
1436     //General iteration variable.
1437    
1438     //Allocate an array for the array of pointers, and put in the NULL entry.
1439     rv = malloc(sizeof(unsigned char *));
1440     if (rv == NULL) //Allocation failure.
1441     return(NULL);
1442    
1443     *rv = NULL; //One pointer, which is NULL.
1444     n_in_array = 1; //One element now.
1445    
1446     //printf("PT1\n");
1447    
1448     do
1449     {
1450     //Allocate space for a current working line.
1451     if (cur == NULL)
1452     {
1453     cur = malloc(PG_BUFSIZE);
1454     if (cur == NULL)
1455     return(NULL); //Allocation failure.
1456     }
1457    
1458     //printf("PT2\n");
1459    
1460     //The position at which we put stuff into the line buffer.
1461     putpos = 0;
1462    
1463     //The first character to be obtained from the input buffer is at getpos.
1464     //Walk the eolpos to one past the last character that should be part of
1465     //that line.
1466     eolpos = getpos;
1467     while (
1468     (eolpos < (PG_BUFSIZE - 1))
1469     &&
1470     (str_stdin[eolpos] != '\n')
1471     &&
1472     (str_stdin[eolpos] != '\0')
1473     )
1474     {
1475     eolpos++;
1476     }
1477    
1478     if (eolpos != getpos) //If we have a line of stuff.
1479     {
1480     //Copy and terminate.
1481     memcpy(cur, str_stdin + getpos, (eolpos - getpos) * sizeof(char));
1482     cur[eolpos - getpos] = 0;
1483    
1484     //Add to array.
1485     rv = realloc(rv, (n_in_array + 1) * (sizeof(unsigned char *)) );
1486     if (rv == NULL)
1487     return(NULL); //Allocation failure.
1488    
1489     rv[n_in_array] = NULL;
1490     rv[n_in_array - 1] = cur;
1491    
1492     cur = NULL;
1493    
1494     n_in_array++;
1495     }
1496    
1497     //We are at the end if either we hit the last character or the zero terminator.
1498     if (
1499     (eolpos >= (PG_BUFSIZE - 1))
1500     ||
1501     (str_stdin[eolpos] == '\0')
1502     )
1503     {
1504     da_end = TRUE;
1505     }
1506     else
1507     {
1508     getpos = eolpos + 1;
1509     }
1510     } while (! da_end);
1511    
1512     return(rv);
1513     }
1514     //
1515     //
1516     //*******************************************************************************
1517     //*** INPUT FILE LINE LOCATION FUNCTIONS ****************************************
1518     //*******************************************************************************
1519     //
1520     //Locates the TOKEN_KEY parameter, if it is present in the passed list
1521     //of strings, and if valid, assigns it to both the passed string and
1522     //to the passed array of bytes.
1523     //
1524     //If the TOKEN_KEY parameter is specified more than once, only the first
1525     //parameter will be used, and there will be no error reported.
1526     //
1527     //Any errors will be signalled by the var error variable, which will be
1528     //set FALSE or TRUE (TRUE on error). Not finding the key is not an error.
1529     //Finding it ill-formatted is an error.
1530     //
1531     void PG_par_token_key_locate(unsigned char **slist,
1532     unsigned char **parval,
1533     unsigned char *key, //At least 24 elements required.
1534     int *error_encountered)
1535     {
1536     unsigned char *ref = "TOKEN_KEY:";
1537     unsigned char *source_line;
1538     unsigned char *local_line;
1539    
1540     *error_encountered = FALSE;
1541    
1542     //Try to allocate a buffer for internal use. It won't be released.
1543     local_line = malloc(PG_BUFSIZE);
1544     if (local_line == NULL)
1545     {
1546     *error_encountered = TRUE;
1547     return;
1548     }
1549    
1550     source_line = *slist;
1551    
1552     while (source_line)
1553     {
1554     strcpy(local_line, source_line);
1555    
1556     if (strlen(local_line) >= strlen(ref)) //Must be long enough.
1557     {
1558     if (strncmp(local_line, ref, strlen(ref)) == 0) //First part must match TOKEN_KEY:
1559     {
1560     //If yes, trash the TOKEN_KEY: tag.
1561     PG_str_n_char_delete(local_line, strlen(ref));
1562    
1563     //What remains must be exactly 48 chars.
1564     if (strlen(local_line) == 48)
1565     {
1566     if (PG_str_is_all_hex_chars(local_line))
1567     {
1568     //Success at this point should be assured. Length is right, and they
1569     //are all hex characters. No further failures possible.
1570     *parval = local_line;
1571     PG_str_to_uchar_array(local_line, key);
1572     return;
1573     }
1574     else
1575     {
1576     *error_encountered = TRUE;
1577     return;
1578     }
1579     }
1580     else
1581     {
1582     *error_encountered = TRUE;
1583     return;
1584     }
1585     }
1586     }
1587    
1588     slist++;
1589     source_line = *slist;
1590     }
1591     }
1592    
1593     //Locates the OTP parameter, if it is present in the passed list
1594     //of strings, and if valid, assigns it to both the passed string and
1595     //to the passed array of bytes.
1596     //
1597     //If the OTP parameter is specified more than once, only the first
1598     //parameter will be used, and there will be no error reported.
1599     //
1600     //Any errors will be signalled by the var error variable, which will be
1601     //set FALSE or TRUE (TRUE on error). Not finding the key is not an error.
1602     //Finding it ill-formatted is an error.
1603     //
1604     void PG_par_otp_locate(unsigned char **slist,
1605     unsigned char **parval,
1606     int *error_encountered)
1607     {
1608     unsigned char *ref = "OTP:";
1609     unsigned char *source_line;
1610     unsigned char *local_line;
1611    
1612     *error_encountered = FALSE;
1613    
1614     //Try to allocate a buffer for internal use. It won't be released.
1615     local_line = malloc(PG_BUFSIZE);
1616     if (local_line == NULL)
1617     {
1618     *error_encountered = TRUE;
1619     return;
1620     }
1621    
1622     source_line = *slist;
1623    
1624     while (source_line)
1625     {
1626     strcpy(local_line, source_line);
1627    
1628     //printf("LINE: %s\n", local_line);
1629    
1630     if (strlen(local_line) >= strlen(ref)) //Must be long enough.
1631     {
1632     if (strncmp(local_line, ref, strlen(ref)) == 0) //First part must match OTP:
1633     {
1634     //If yes, trash the OTP: tag.
1635     PG_str_n_char_delete(local_line, strlen(ref));
1636    
1637     //What remains must be exactly 8 chars.
1638     if (strlen(local_line) == 8)
1639     {
1640     PG_str_to_upper(local_line); //All lower-case to upper-case.
1641     PG_string_sanitize(local_line, "0123456789ABCDEFGHJKLMNPRSTUVWXY");
1642     //A token can display letters and numbers except I, O, Q, and Z.
1643     //Remove those.
1644    
1645     if (strlen(local_line) == 8)
1646     {
1647     //Clear to proceed. Looks it was a reasonable OTP.
1648     *parval = local_line;
1649     return;
1650     }
1651     else
1652     {
1653     //Had some bum characters. Can't be valid.
1654     *error_encountered = TRUE;
1655     return;
1656     }
1657     }
1658     else
1659     {
1660     *error_encountered = TRUE;
1661     return;
1662     }
1663     }
1664     }
1665    
1666     slist++;
1667     source_line = *slist;
1668     }
1669     }
1670    
1671    
1672     //Locates the CHALLENGE parameter, if it is present in the passed list
1673     //of strings, and if valid, assigns it to both the passed string and
1674     //to the passed array of bytes.
1675     //
1676     //If the CHALLENGE parameter is specified more than once, only the first
1677     //parameter will be used, and there will be no error reported.
1678     //
1679     //Any errors will be signalled by the var error variable, which will be
1680     //set FALSE or TRUE (TRUE on error). Not finding the key is not an error.
1681     //Finding it ill-formatted is an error.
1682     //
1683     void PG_par_challenge_locate(unsigned char **slist,
1684     unsigned char **parval,
1685     unsigned char *challenge, //At least 16 elements required.
1686     int *error_encountered)
1687     {
1688     unsigned char *ref = "CHALLENGE:";
1689     unsigned char *source_line;
1690     unsigned char *local_line;
1691    
1692     *error_encountered = FALSE;
1693    
1694     //Try to allocate a buffer for internal use. It won't be released.
1695     local_line = malloc(PG_BUFSIZE);
1696     if (local_line == NULL)
1697     {
1698     *error_encountered = TRUE;
1699     return;
1700     }
1701    
1702     source_line = *slist;
1703    
1704     while (source_line)
1705     {
1706     strcpy(local_line, source_line);
1707    
1708     if (strlen(local_line) >= strlen(ref)) //Must be long enough.
1709     {
1710     if (strncmp(local_line, ref, strlen(ref)) == 0) //First part must match TOKEN_KEY:
1711     {
1712     //If yes, trash the CHALLENGE: tag.
1713     PG_str_n_char_delete(local_line, strlen(ref));
1714    
1715     //What remains must be exactly 32 chars.
1716     if (strlen(local_line) == 32)
1717     {
1718     if (PG_str_is_all_hex_chars(local_line))
1719     {
1720     //Success at this point should be assured. Length is right, and they
1721     //are all hex characters. No further failures possible.
1722     *parval = local_line;
1723     PG_str_to_uchar_array(local_line, challenge);
1724     return;
1725     }
1726     else
1727     {
1728     *error_encountered = TRUE;
1729     return;
1730     }
1731     }
1732     else
1733     {
1734     *error_encountered = TRUE;
1735     return;
1736     }
1737     }
1738     }
1739    
1740     slist++;
1741     source_line = *slist;
1742     }
1743     }
1744    
1745    
1746     //Locates the RESYNC_STRING parameter, if it is present in the passed list
1747     //of strings, and if valid, assigns it to both the passed string and
1748     //to the passed array of bytes.
1749     //
1750     //If the RESYNC_STRING parameter is specified more than once, only the first
1751     //parameter will be used, and there will be no error reported.
1752     //
1753     //Any errors will be signalled by the var error variable, which will be
1754     //set FALSE or TRUE (TRUE on error). Not finding the resync string is not an error.
1755     //Finding it ill-formatted is an error.
1756     //
1757     void PG_par_resync_string_locate(unsigned char **slist,
1758     unsigned char **parval,
1759     int *error_encountered)
1760     {
1761     unsigned char *ref = "RESYNC_STRING:";
1762     unsigned char *source_line;
1763     unsigned char *local_line;
1764    
1765     *error_encountered = FALSE;
1766    
1767     //Try to allocate a buffer for internal use. It won't be released.
1768     local_line = malloc(PG_BUFSIZE);
1769     if (local_line == NULL)
1770     {
1771     *error_encountered = TRUE;
1772     return;
1773     }
1774    
1775     source_line = *slist;
1776    
1777     while (source_line)
1778     {
1779     strcpy(local_line, source_line);
1780    
1781     //printf("LINE: %s\n", local_line);
1782    
1783     if (strlen(local_line) >= strlen(ref)) //Must be long enough.
1784     {
1785     if (strncmp(local_line, ref, strlen(ref)) == 0) //First part must match RESYNC_STRING:
1786     {
1787     //If yes, trash the RESYNC_STRING: tag.
1788     PG_str_n_char_delete(local_line, strlen(ref));
1789    
1790     //What remains must be exactly 8 chars.
1791     if (strlen(local_line) == 8)
1792     {
1793     PG_string_sanitize(local_line, "0123456789");
1794     //Resync string can be only digits.
1795    
1796     if (strlen(local_line) == 8)
1797     {
1798     //Clear to proceed. Looks it was a reasonable resync string.
1799     *parval = local_line;
1800     return;
1801     }
1802     else
1803     {
1804     //Had some bum characters. Can't be valid.
1805     *error_encountered = TRUE;
1806     return;
1807     }
1808     }
1809     else
1810     {
1811     *error_encountered = TRUE;
1812     return;
1813     }
1814     }
1815     }
1816    
1817     slist++;
1818     source_line = *slist;
1819     }
1820     }
1821    
1822     //Locates the OTP_WINDOW parameter, if it is present in the passed list
1823     //of strings, and if valid, assigns it to both the passed string and
1824     //to the passed array of bytes.
1825     //
1826     //If the OTP_WINDOW parameter is specified more than once, only the first
1827     //parameter will be used, and there will be no error reported.
1828     //
1829     //Any errors will be signalled by the var error variable, which will be
1830     //set FALSE or TRUE (TRUE on error). Not finding the resync string is not an error.
1831     //Finding it ill-formatted is an error.
1832     //
1833     void PG_par_otp_window_locate(unsigned char **slist,
1834     unsigned char **parval,
1835     int *val,
1836     int *error_encountered)
1837     {
1838     unsigned char *ref = "OTP_WINDOW:";
1839     unsigned char *source_line;
1840     unsigned char *local_line;
1841    
1842     *error_encountered = FALSE;
1843    
1844     //Try to allocate a buffer for internal use. It won't be released.
1845     local_line = malloc(PG_BUFSIZE);
1846     if (local_line == NULL)
1847     {
1848     *error_encountered = TRUE;
1849     return;
1850     }
1851    
1852     source_line = *slist;
1853    
1854     while (source_line)
1855     {
1856     strcpy(local_line, source_line);
1857    
1858     //printf("LINE: %s\n", local_line);
1859    
1860     if (strlen(local_line) >= strlen(ref)) //Must be long enough.
1861     {
1862     if (strncmp(local_line, ref, strlen(ref)) == 0) //First part must match OTP_WINDOW:
1863     {
1864     //If yes, trash the OTP_WINDOW tag.
1865     PG_str_n_char_delete(local_line, strlen(ref));
1866    
1867     //Digits only, please.
1868     PG_string_sanitize(local_line, "0123456789");
1869    
1870     //What remains must be either "0" or else must be 4 characters or less and not begin
1871     //with a "0".
1872     if (
1873     (
1874     (strlen(local_line) == 1)
1875     &&
1876     (strcmp("0", local_line) == 0)
1877     )
1878     ||
1879     (
1880     (strlen(local_line) > 0)
1881     &&
1882     (strlen(local_line) <= 4)
1883     &&
1884     (local_line[0] != '0')
1885     )
1886     )
1887     {
1888     //Clear to proceed. Looks it was a reasonable otp string.
1889     *parval = local_line;
1890     sscanf(local_line, "%d", val);
1891     return;
1892     }
1893     else
1894     {
1895     *error_encountered = TRUE;
1896     return;
1897     }
1898     }
1899     }
1900    
1901     slist++;
1902     source_line = *slist;
1903     }
1904     }
1905    
1906    
1907     //*******************************************************************************
1908     //*** CHALLENGE MANIPULATION ****************************************************
1909     //*******************************************************************************
1910     //
1911     //Increments a challenge, processing carries from byte to byte.
1912     //
1913     void PG_challenge_increment(unsigned char *challenge)
1914     {
1915     int i;
1916    
1917     for (i = 15; i >= 0; i--)
1918     {
1919     if (challenge[i] < 255)
1920     {
1921     challenge[i] = challenge[i] + 1;
1922     break;
1923     }
1924     else
1925     {
1926     challenge[i] = 0;
1927     }
1928     }
1929     }
1930    
1931    
1932     //*******************************************************************************
1933     //*** MAIN FUNCTION *************************************************************
1934     //*******************************************************************************
1935     //
1936     int main ( int argc, char *argv[] )
1937     {
1938     unsigned char *stdin_buffer = NULL;
1939     //The fully consumed standard input as a string, or NULL if it couldn't
1940     //be obtained.
1941     unsigned char **stdin_split = NULL;
1942     //The stdin, split into lines. This is a pointer to an array of pointers,
1943     //each of which points to a line.
1944     unsigned char *str_token_key = NULL;
1945     //The AES-192 token key as a string of hexadecimal digits, or NULL if
1946     //the token key wasn't supplied or couldn't be parsed.
1947     unsigned char *str_otp = NULL;
1948     //The token OTP supplied, or NULL if the OTP wasn't supplied or
1949     //couldn't be parsed.
1950     unsigned char *str_challenge = NULL;
1951     //A hexadecimal representation of the challenge, or NULL if it wasn't
1952     //supplied or couldn't be parsed.
1953     unsigned char *str_resync = NULL;
1954     //The resynchronization string that was given to the user to input into
1955     //the token, or NULL if it wasn't supplied or couldn't be parsed.
1956     unsigned char *str_otp_window = NULL;
1957     //A string representation of the otp window (an integer), or NULL if it
1958     //wasn't supplied or couldn't be parsed.
1959     int otp_window = 1;
1960     //The size of the window of allowed OTPs, as an integer.
1961     int error_local_encountered;
1962     //Local error flag.
1963     char token_key[24] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
1964     //The AES-192 token key. Only assigned if the string could be parsed.
1965     char challenge[16] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
1966     //The challenge, in binary form.
1967     char options[] = {0xB0, 0x9B, 0x83, 0x28, 0x00, 0x00, 0x00, 0x00};
1968     //Token options to be used when calling into the CryptoCard library.
1969     char response_otp[9];
1970     //What the token should display. Left at 9 so can be zero-terminated.
1971     char status[110];
1972     //This dimension came from the original CryptoCard code. Have no idea how it
1973     //was determined.
1974    
1975     //Grab the standard input.
1976     //
1977     stdin_buffer = PG_buffer_stdin();
1978    
1979     #ifdef PG_DEBUG
1980     printf("\n*** STDIN BEFORE FILTERING START ***\n");
1981     if (stdin_buffer == NULL)
1982     printf("stdin_buffer is NULL.\n");
1983     else
1984     printf("%s\n", stdin_buffer);
1985     printf("\n*** STDIN BEFORE FILTERING END ***\n");
1986     PG_hline_thin();
1987     #endif
1988    
1989     //Trim all invalid characters from the buffered standard input. No
1990     //errors are possible. Removing all the spaces makes parsing decisions
1991     //very easy. This is the lazy-man's way to do it.
1992     //
1993     if (stdin_buffer != NULL)
1994     PG_string_sanitize(stdin_buffer, ":_\nabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789");
1995    
1996     #ifdef PG_DEBUG
1997     printf("\n*** STDIN AFTER FILTERING START ***\n");
1998     if (stdin_buffer == NULL)
1999     printf("stdin_buffer is NULL.\n");
2000     else
2001     printf("%s\n", stdin_buffer);
2002     printf("\n*** STDIN AFTER FILTERING END ***\n");
2003     PG_hline_thin();
2004     #endif
2005    
2006     //Split the standard input into lines. In the process, empty lines are
2007     //removed. This creates an array of pointers, each pointing to a line,
2008     //NULL terminated.
2009     //
2010     if (stdin_buffer != NULL)
2011     stdin_split = PG_line_split(stdin_buffer);
2012    
2013     #ifdef PG_DEBUG
2014     {
2015     int i = 0;
2016     unsigned char *p;
2017    
2018     printf("\n*** STDIN AFTER LINE SPLIT START ***\n");
2019    
2020     if (stdin_split != NULL)
2021     {
2022     do
2023     {
2024     p = stdin_split[i];
2025     if (p != NULL)
2026     printf("Line %6d: %s\n", i + 1, p);
2027     else
2028     printf("Line %6d: NULL\n", i + 1);
2029     i++;
2030     }
2031     while (p != NULL);
2032     }
2033     else
2034     {
2035     printf("stdin_split is NULL.\n");
2036     }
2037    
2038     printf("\n*** STDIN AFTER LINE SPLIT END ***\n");
2039     PG_hline_thin();
2040     }
2041     #endif
2042    
2043     //Try to obtain/parse the token key. If there is an error
2044     //or it isn't found, the string pointer will be left NULL.
2045     //
2046     if (stdin_split != NULL)
2047     PG_par_token_key_locate( stdin_split,
2048     &str_token_key,
2049     token_key,
2050     &error_local_encountered);
2051    
2052    
2053     #ifdef PG_DEBUG
2054     printf("\n*** TOKEN_KEY PARSE RESULTS START ***\n");
2055    
2056     if (str_token_key)
2057     printf("Token key string: %s.\n", str_token_key);
2058     else
2059     printf("Token key string is NULL.\n");
2060    
2061     if (str_token_key)
2062     PG_byte_array_output(token_key, sizeof(token_key)/sizeof(token_key[0]));
2063    
2064     printf("\n*** TOKEN_KEY PARSE RESULTS END ***\n");
2065     PG_hline_thin();
2066     #endif
2067    
2068     //Try to obtain/parse the OTP (one-time password) parameter. If it can't
2069     //be found or can't be parsed, the string pointer is left NULL.
2070     //
2071     if (stdin_split != NULL)
2072     PG_par_otp_locate( stdin_split,
2073     &str_otp,
2074     &error_local_encountered);
2075    
2076     #ifdef PG_DEBUG
2077     printf("\n*** OTP PARSE RESULTS START ***\n");
2078    
2079     if (str_otp)
2080     printf("OTP string: %s.\n", str_otp);
2081     else
2082     printf("OTP string is NULL.\n");
2083    
2084     printf("\n*** OTP PARSE RESULTS END ***\n");
2085     PG_hline_thin();
2086     #endif
2087    
2088     //Try to parse/locate the challenge parameter. If not
2089     //found or can't be parsed, leave the string pointer NULL.
2090     //
2091     if (stdin_split != NULL)
2092     PG_par_challenge_locate( stdin_split,
2093     &str_challenge,
2094     challenge,
2095     &error_local_encountered);
2096    
2097     #ifdef PG_DEBUG
2098     printf("\n*** CHALLENGE PARSE RESULTS START ***\n");
2099    
2100     if (str_challenge)
2101     printf("Challenge string: %s.\n", str_challenge);
2102     else
2103     printf("Challenge string is NULL.\n");
2104    
2105     if (str_challenge != NULL)
2106     PG_byte_array_output(challenge, sizeof(challenge)/sizeof(challenge[0]));
2107    
2108     printf("\n*** CHALLENGE PARSE RESULTS END ***\n");
2109     PG_hline_thin();
2110     #endif
2111    
2112     //Try to locate/parse the resynchronization value string. If it can't
2113     //be located or parses as an error, the string pointer will be left
2114     //NULL.
2115     //
2116     if (stdin_split != NULL)
2117     PG_par_resync_string_locate( stdin_split,
2118     &str_resync,
2119     &error_local_encountered);
2120    
2121     #ifdef PG_DEBUG
2122     printf("\n*** RESYNC STRING PARSE RESULTS START ***\n");
2123    
2124     if (str_resync)
2125     printf("RESYNC_STRING string: %s.\n", str_resync);
2126     else
2127     printf("RESYNC_STRING string is NULL.\n");
2128    
2129     printf("\n*** RESYNC STRING PARSE RESULTS END ***\n");
2130     PG_hline_thin();
2131     #endif
2132    
2133     //Try to locate/parse the OTP_WINDOW parameter. If it can't
2134     //be located or can't be parsed, the string pointer will be
2135     //left NULL.
2136     //
2137     if (stdin_split != NULL)
2138     PG_par_otp_window_locate( stdin_split,
2139     &str_otp_window,
2140     &otp_window,
2141     &error_local_encountered);
2142    
2143     #ifdef PG_DEBUG
2144     printf("\n*** OTP_WINDOW PARSE RESULTS START ***\n");
2145    
2146     if (str_otp_window)
2147     printf("OTP_WINDOW string: %s.\n", str_otp_window);
2148     else
2149     printf("OTP_WINDOW string is NULL.\n");
2150    
2151     printf("OTP_WINDOW integer : %d.\n", otp_window);
2152    
2153     printf("\n*** OTP_WINDOW PARSE RESULTS END ***\n");
2154     PG_hline_thin();
2155     #endif
2156    
2157     //At this point, all of the data is in. We decide what to do based on what was supplied
2158     //and what was not.
2159     //
2160     if (str_token_key == NULL)
2161     {
2162     //We can't proceed without the token key. We can do nothing. Fail the authentication.
2163     //
2164     #ifdef PG_DEBUG
2165     PG_hline_thick();
2166     printf("*** CASE: NO KEY ***\n");
2167     PG_hline_thick();
2168     #endif
2169     //
2170     printf("MAJOR_RESULT:-2\n");
2171     }
2172     else if (str_otp == NULL)
2173     {
2174     //We can't proceed without an OTP. Even for resynchronizing, an OTP is required. Fail
2175     //the authentication.
2176     //
2177     #ifdef PG_DEBUG
2178     PG_hline_thick();
2179     printf("*** CASE: NO OTP ***\n");
2180     PG_hline_thick();
2181     #endif
2182     //
2183     printf("MAJOR_RESULT:-2\n");
2184     }
2185     else if (str_resync != NULL)
2186     {
2187     int auth_success = FALSE;
2188     int i;
2189    
2190     //We have a key, we have an OTP, and we have the resynchronization string that the user
2191     //was supposed to enter into the token. This is enough to authenticate. We don't need
2192     //a challenge, because that falls out of the key and the resynchronization string.
2193     //
2194     #ifdef PG_DEBUG
2195     PG_hline_thick();
2196     printf("*** CASE: RESYNCHRONIZATION ***\n");
2197     PG_hline_thick();
2198     #endif
2199    
2200     //Generate the challenge that comes about from that resynchronization
2201     //string.
2202     //
2203     Generate_Challenge(str_resync, token_key, 24, 1, challenge);
2204    
2205     #ifdef PG_DEBUG
2206     printf("Challenge generated: ");
2207     PG_byte_array_output(challenge, sizeof(challenge)/sizeof(challenge[0]));
2208     printf("\n");
2209     PG_hline_thin();
2210     #endif
2211    
2212     //Try to match the OTP that was supplied. This will involve looping and repeatedly
2213     //checking the value against the OTP.
2214     //
2215     for (i=0; i<otp_window; i++)
2216     {
2217     #ifdef PG_DEBUG
2218     printf("OTP check loop, iteration %d of %d.\n", i+1, otp_window);
2219     #endif
2220    
2221     //Try to get the value that should be displayed on the token.
2222     Authenticate(token_key, challenge, 24, 1, options, response_otp, status);
2223     response_otp[8] = 0; //Be sure zero-terminated.
2224    
2225     #ifdef PG_DEBUG
2226     printf("OTP value generated from CryptoCard library: %s\n", response_otp);
2227     #endif
2228    
2229     PG_challenge_increment(challenge);
2230     //Canonically, the convention used is that the value that should be stored in the
2231     //user's database is the one that will lead to the next OTP. This is not the
2232     //only convention possible.
2233    
2234     if (! strcmp(str_otp, response_otp))
2235     {
2236     auth_success = TRUE;
2237     break;
2238     }
2239     }
2240    
2241     if (auth_success)
2242     {
2243     //We have a match. Output the fields to indicate this.
2244     //
2245     printf("MAJOR_RESULT:%d\n", i);
2246     printf("CHALLENGE:");
2247     PG_byte_array_output(challenge, sizeof(challenge)/sizeof(challenge[0]));
2248     printf("\n");
2249     }
2250     else
2251     {
2252     //We failed to authenticate.
2253     printf("MAJOR_RESULT:-1\n");
2254     if (str_challenge != NULL)
2255     printf("CHALLENGE:%s\n", str_challenge); //If not supplied in, don't provide out.
2256     }
2257     }
2258     else if (str_challenge != NULL)
2259     {
2260     int auth_success = FALSE;
2261     int i;
2262    
2263     //We have a key, we have an OTP, we don't have a resync string, and we have a challenge.
2264     //This is an ordinary authentication request.
2265     //
2266     #ifdef PG_DEBUG
2267     PG_hline_thick();
2268     printf("*** CASE: NORMAL AUTHENTICATION ***\n");
2269     PG_hline_thick();
2270     #endif
2271    
2272     //Try to match the OTP that was supplied. This will involve looping and repeatedly
2273     //checking the value against the OTP.
2274     //
2275     for (i=0; i<otp_window; i++)
2276     {
2277     #ifdef PG_DEBUG
2278     printf("OTP check loop, iteration %d of %d.\n", i+1, otp_window);
2279     #endif
2280    
2281     //Try to get the value that should be displayed on the token.
2282     Authenticate(token_key, challenge, 24, 1, options, response_otp, status);
2283     response_otp[8] = 0; //Be sure zero-terminated.
2284    
2285     #ifdef PG_DEBUG
2286     printf("OTP value generated from CryptoCard library: %s\n", response_otp);
2287     #endif
2288    
2289     PG_challenge_increment(challenge);
2290     //Canonically, the convention used is that the value that should be stored in the
2291     //user's database is the one that will lead to the next OTP. This is not the
2292     //only convention possible.
2293    
2294     if (! strcmp(str_otp, response_otp))
2295     {
2296     auth_success = TRUE;
2297     break;
2298     }
2299     }
2300    
2301     if (auth_success)
2302     {
2303     //We have a match. Output the fields to indicate this.
2304     //
2305     printf("MAJOR_RESULT:%d\n", i);
2306     printf("CHALLENGE:");
2307     PG_byte_array_output(challenge, sizeof(challenge)/sizeof(challenge[0]));
2308     printf("\n");
2309     }
2310     else
2311     {
2312     //We failed to authenticate.
2313     printf("MAJOR_RESULT:-1\n");
2314     printf("CHALLENGE:%s\n", str_challenge);
2315     }
2316     }
2317     else
2318     {
2319     //This didn't fall into any of the clauses above and is very odd. This is an authentication
2320     //failure.
2321     //
2322     #ifdef PG_DEBUG
2323     PG_hline_thick();
2324     printf("*** CASE: FALLTHROUGH ERROR ***\n");
2325     PG_hline_thick();
2326     #endif
2327     //
2328     printf("MAJOR_RESULT:-2\n");
2329     }
2330    
2331     return(0);
2332     }
2333     //
2334     //------------------------------------------------------------------------
2335     // GNU GENERAL PUBLIC LICENSE
2336     // Version 2, June 1991
2337     //
2338     // Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
2339     // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
2340     // Everyone is permitted to copy and distribute verbatim copies
2341     // of this license document, but changing it is not allowed.
2342     //
2343     // Preamble
2344     //
2345     // The licenses for most software are designed to take away your
2346     //freedom to share and change it. By contrast, the GNU General Public
2347     //License is intended to guarantee your freedom to share and change free
2348     //software--to make sure the software is free for all its users. This
2349     //General Public License applies to most of the Free Software
2350     //Foundation's software and to any other program whose authors commit to
2351     //using it. (Some other Free Software Foundation software is covered by
2352     //the GNU Lesser General Public License instead.) You can apply it to
2353     //your programs, too.
2354     //
2355     // When we speak of free software, we are referring to freedom, not
2356     //price. Our General Public Licenses are designed to make sure that you
2357     //have the freedom to distribute copies of free software (and charge for
2358     //this service if you wish), that you receive source code or can get it
2359     //if you want it, that you can change the software or use pieces of it
2360     //in new free programs; and that you know you can do these things.
2361     //
2362     // To protect your rights, we need to make restrictions that forbid
2363     //anyone to deny you these rights or to ask you to surrender the rights.
2364     //These restrictions translate to certain responsibilities for you if you
2365     //distribute copies of the software, or if you modify it.
2366     //
2367     // For example, if you distribute copies of such a program, whether
2368     //gratis or for a fee, you must give the recipients all the rights that
2369     //you have. You must make sure that they, too, receive or can get the
2370     //source code. And you must show them these terms so they know their
2371     //rights.
2372     //
2373     // We protect your rights with two steps: (1) copyright the software, and
2374     //(2) offer you this license which gives you legal permission to copy,
2375     //distribute and/or modify the software.
2376     //
2377     // Also, for each author's protection and ours, we want to make certain
2378     //that everyone understands that there is no warranty for this free
2379     //software. If the software is modified by someone else and passed on, we
2380     //want its recipients to know that what they have is not the original, so
2381     //that any problems introduced by others will not reflect on the original
2382     //authors' reputations.
2383     //
2384     // Finally, any free program is threatened constantly by software
2385     //patents. We wish to avoid the danger that redistributors of a free
2386     //program will individually obtain patent licenses, in effect making the
2387     //program proprietary. To prevent this, we have made it clear that any
2388     //patent must be licensed for everyone's free use or not licensed at all.
2389     //
2390     // The precise terms and conditions for copying, distribution and
2391     //modification follow.
2392     //
2393     // GNU GENERAL PUBLIC LICENSE
2394     // TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
2395     //
2396     // 0. This License applies to any program or other work which contains
2397     //a notice placed by the copyright holder saying it may be distributed
2398     //under the terms of this General Public License. The "Program", below,
2399     //refers to any such program or work, and a "work based on the Program"
2400     //means either the Program or any derivative work under copyright law:
2401     //that is to say, a work containing the Program or a portion of it,
2402     //either verbatim or with modifications and/or translated into another
2403     //language. (Hereinafter, translation is included without limitation in
2404     //the term "modification".) Each licensee is addressed as "you".
2405     //
2406     //Activities other than copying, distribution and modification are not
2407     //covered by this License; they are outside its scope. The act of
2408     //running the Program is not restricted, and the output from the Program
2409     //is covered only if its contents constitute a work based on the
2410     //Program (independent of having been made by running the Program).
2411     //Whether that is true depends on what the Program does.
2412     //
2413     // 1. You may copy and distribute verbatim copies of the Program's
2414     //source code as you receive it, in any medium, provided that you
2415     //conspicuously and appropriately publish on each copy an appropriate
2416     //copyright notice and disclaimer of warranty; keep intact all the
2417     //notices that refer to this License and to the absence of any warranty;
2418     //and give any other recipients of the Program a copy of this License
2419     //along with the Program.
2420     //
2421     //You may charge a fee for the physical act of transferring a copy, and
2422     //you may at your option offer warranty protection in exchange for a fee.
2423     //
2424     // 2. You may modify your copy or copies of the Program or any portion
2425     //of it, thus forming a work based on the Program, and copy and
2426     //distribute such modifications or work under the terms of Section 1
2427     //above, provided that you also meet all of these conditions:
2428     //
2429     // a) You must cause the modified files to carry prominent notices
2430     // stating that you changed the files and the date of any change.
2431     //
2432     // b) You must cause any work that you distribute or publish, that in
2433     // whole or in part contains or is derived from the Program or any
2434     // part thereof, to be licensed as a whole at no charge to all third
2435     // parties under the terms of this License.
2436     //
2437     // c) If the modified program normally reads commands interactively
2438     // when run, you must cause it, when started running for such
2439     // interactive use in the most ordinary way, to print or display an
2440     // announcement including an appropriate copyright notice and a
2441     // notice that there is no warranty (or else, saying that you provide
2442     // a warranty) and that users may redistribute the program under
2443     // these conditions, and telling the user how to view a copy of this
2444     // License. (Exception: if the Program itself is interactive but
2445     // does not normally print such an announcement, your work based on
2446     // the Program is not required to print an announcement.)
2447     //
2448     //These requirements apply to the modified work as a whole. If
2449     //identifiable sections of that work are not derived from the Program,
2450     //and can be reasonably considered independent and separate works in
2451     //themselves, then this License, and its terms, do not apply to those
2452     //sections when you distribute them as separate works. But when you
2453     //distribute the same sections as part of a whole which is a work based
2454     //on the Program, the distribution of the whole must be on the terms of
2455     //this License, whose permissions for other licensees extend to the
2456     //entire whole, and thus to each and every part regardless of who wrote it.
2457     //
2458     //Thus, it is not the intent of this section to claim rights or contest
2459     //your rights to work written entirely by you; rather, the intent is to
2460     //exercise the right to control the distribution of derivative or
2461     //collective works based on the Program.
2462     //
2463     //In addition, mere aggregation of another work not based on the Program
2464     //with the Program (or with a work based on the Program) on a volume of
2465     //a storage or distribution medium does not bring the other work under
2466     //the scope of this License.
2467     //
2468     // 3. You may copy and distribute the Program (or a work based on it,
2469     //under Section 2) in object code or executable form under the terms of
2470     //Sections 1 and 2 above provided that you also do one of the following:
2471     //
2472     // a) Accompany it with the complete corresponding machine-readable
2473     // source code, which must be distributed under the terms of Sections
2474     // 1 and 2 above on a medium customarily used for software interchange; or,
2475     //
2476     // b) Accompany it with a written offer, valid for at least three
2477     // years, to give any third party, for a charge no more than your
2478     // cost of physically performing source distribution, a complete
2479     // machine-readable copy of the corresponding source code, to be
2480     // distributed under the terms of Sections 1 and 2 above on a medium
2481     // customarily used for software interchange; or,
2482     //
2483     // c) Accompany it with the information you received as to the offer
2484     // to distribute corresponding source code. (This alternative is
2485     // allowed only for noncommercial distribution and only if you
2486     // received the program in object code or executable form with such
2487     // an offer, in accord with Subsection b above.)
2488     //
2489     //The source code for a work means the preferred form of the work for
2490     //making modifications to it. For an executable work, complete source
2491     //code means all the source code for all modules it contains, plus any
2492     //associated interface definition files, plus the scripts used to
2493     //control compilation and installation of the executable. However, as a
2494     //special exception, the source code distributed need not include
2495     //anything that is normally distributed (in either source or binary
2496     //form) with the major components (compiler, kernel, and so on) of the
2497     //operating system on which the executable runs, unless that component
2498     //itself accompanies the executable.
2499     //
2500     //If distribution of executable or object code is made by offering
2501     //access to copy from a designated place, then offering equivalent
2502     //access to copy the source code from the same place counts as
2503     //distribution of the source code, even though third parties are not
2504     //compelled to copy the source along with the object code.
2505     //
2506     // 4. You may not copy, modify, sublicense, or distribute the Program
2507     //except as expressly provided under this License. Any attempt
2508     //otherwise to copy, modify, sublicense or distribute the Program is
2509     //void, and will automatically terminate your rights under this License.
2510     //However, parties who have received copies, or rights, from you under
2511     //this License will not have their licenses terminated so long as such
2512     //parties remain in full compliance.
2513     //
2514     // 5. You are not required to accept this License, since you have not
2515     //signed it. However, nothing else grants you permission to modify or
2516     //distribute the Program or its derivative works. These actions are
2517     //prohibited by law if you do not accept this License. Therefore, by
2518     //modifying or distributing the Program (or any work based on the
2519     //Program), you indicate your acceptance of this License to do so, and
2520     //all its terms and conditions for copying, distributing or modifying
2521     //the Program or works based on it.
2522     //
2523     // 6. Each time you redistribute the Program (or any work based on the
2524     //Program), the recipient automatically receives a license from the
2525     //original licensor to copy, distribute or modify the Program subject to
2526     //these terms and conditions. You may not impose any further
2527     //restrictions on the recipients' exercise of the rights granted herein.
2528     //You are not responsible for enforcing compliance by third parties to
2529     //this License.
2530     //
2531     // 7. If, as a consequence of a court judgment or allegation of patent
2532     //infringement or for any other reason (not limited to patent issues),
2533     //conditions are imposed on you (whether by court order, agreement or
2534     //otherwise) that contradict the conditions of this License, they do not
2535     //excuse you from the conditions of this License. If you cannot
2536     //distribute so as to satisfy simultaneously your obligations under this
2537     //License and any other pertinent obligations, then as a consequence you
2538     //may not distribute the Program at all. For example, if a patent
2539     //license would not permit royalty-free redistribution of the Program by
2540     //all those who receive copies directly or indirectly through you, then
2541     //the only way you could satisfy both it and this License would be to
2542     //refrain entirely from distribution of the Program.
2543     //
2544     //If any portion of this section is held invalid or unenforceable under
2545     //any particular circumstance, the balance of the section is intended to
2546     //apply and the section as a whole is intended to apply in other
2547     //circumstances.
2548     //
2549     //It is not the purpose of this section to induce you to infringe any
2550     //patents or other property right claims or to contest validity of any
2551     //such claims; this section has the sole purpose of protecting the
2552     //integrity of the free software distribution system, which is
2553     //implemented by public license practices. Many people have made
2554     //generous contributions to the wide range of software distributed
2555     //through that system in reliance on consistent application of that
2556     //system; it is up to the author/donor to decide if he or she is willing
2557     //to distribute software through any other system and a licensee cannot
2558     //impose that choice.
2559     //
2560     //This section is intended to make thoroughly clear what is believed to
2561     //be a consequence of the rest of this License.
2562     //
2563     // 8. If the distribution and/or use of the Program is restricted in
2564     //certain countries either by patents or by copyrighted interfaces, the
2565     //original copyright holder who places the Program under this License
2566     //may add an explicit geographical distribution limitation excluding
2567     //those countries, so that distribution is permitted only in or among
2568     //countries not thus excluded. In such case, this License incorporates
2569     //the limitation as if written in the body of this License.
2570     //
2571     // 9. The Free Software Foundation may publish revised and/or new versions
2572     //of the General Public License from time to time. Such new versions will
2573     //be similar in spirit to the present version, but may differ in detail to
2574     //address new problems or concerns.
2575     //
2576     //Each version is given a distinguishing version number. If the Program
2577     //specifies a version number of this License which applies to it and "any
2578     //later version", you have the option of following the terms and conditions
2579     //either of that version or of any later version published by the Free
2580     //Software Foundation. If the Program does not specify a version number of
2581     //this License, you may choose any version ever published by the Free Software
2582     //Foundation.
2583     //
2584     // 10. If you wish to incorporate parts of the Program into other free
2585     //programs whose distribution conditions are different, write to the author
2586     //to ask for permission. For software which is copyrighted by the Free
2587     //Software Foundation, write to the Free Software Foundation; we sometimes
2588     //make exceptions for this. Our decision will be guided by the two goals
2589     //of preserving the free status of all derivatives of our free software and
2590     //of promoting the sharing and reuse of software generally.
2591     //
2592     // NO WARRANTY
2593     //
2594     // 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
2595     //FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
2596     //OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
2597     //PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
2598     //OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
2599     //MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
2600     //TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
2601     //PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
2602     //REPAIR OR CORRECTION.
2603     //
2604     // 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
2605     //WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
2606     //REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
2607     //INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
2608     //OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
2609     //TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
2610     //YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
2611     //PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
2612     //POSSIBILITY OF SUCH DAMAGES.
2613     //
2614     // END OF TERMS AND CONDITIONS
2615     //------------------------------------------------------------------------
2616     //$Log: cc_kt1_auth_php.c,v $
2617     //Revision 1.11 2009/11/04 16:27:11 dashley
2618     //Information about how to work around missing "libcrypto.so.4" added.
2619     //Only comments were changed.
2620     //
2621     //Revision 1.10 2009/11/04 15:38:54 dashley
2622     //Contact information, copyright, and one or two technical details in
2623     //comments updated. Changes were to comments only.
2624     //
2625     //Revision 1.9 2007/05/23 18:20:21 dashley
2626     //Cosmetic edits.
2627     //
2628     //Revision 1.8 2007/05/23 17:42:12 dashley
2629     //Addition of GPL text.
2630     //
2631     //Revision 1.7 2007/05/23 17:24:54 dashley
2632     //Safety checkin before trying to append the GPL using curl.
2633     //
2634     //Revision 1.6 2007/05/20 04:13:51 dashley
2635     //Edits.
2636     //
2637     //Revision 1.5 2007/05/20 03:47:37 dashley
2638     //Edits.
2639     //
2640     //End of $RCSfile: cc_kt1_auth_php.c,v $
2641     //------------------------------------------------------------------------

dashley@gmail.com
ViewVC Help
Powered by ViewVC 1.1.25