Imported Upstream version 1.8.2
Sophie Brun
9 years ago
0 | Changelog | |
1 | ========= | |
2 | ||
3 | Version: 1.8.2 | |
4 | Date : 19/06/2009 | |
5 | Author : Ian Ventura-Whiting (Fizz) | |
6 | Changes: The following are a list of changes | |
7 | since the previous version: | |
8 | > Fixed output with HTML disabled | |
9 | > Fixed XML critical | |
10 | ||
11 | Version: 1.8.1 | |
12 | Date : 25/05/2009 | |
13 | Author : Ian Ventura-Whiting (Fizz) | |
14 | Changes: The following are a list of changes | |
15 | since the previous version: | |
16 | > Fixed some compiler warnings. | |
17 | ||
18 | Version: 1.8.0 | |
19 | Date : 19/05/2009 | |
20 | Author : Ian Ventura-Whiting (Fizz) | |
21 | Thanks : John Nichols | |
22 | Changes: The following are a list of changes | |
23 | since the previous version: | |
24 | > Added SSL implementation workaround | |
25 | option. | |
26 | > Added HTTP connection testing. | |
27 | > Fixed Certification validation XML | |
28 | output. | |
29 | ||
30 | Version: 1.7.1 | |
31 | Date : 20/04/2008 | |
32 | Author : Ian Ventura-Whiting (Fizz) | |
33 | Thanks : Mark Lowe | |
34 | Changes: The following are a list of changes | |
35 | since the previous version: | |
36 | > Added HELO for SMTP checks | |
37 | > Increased read buffer size | |
38 | ||
39 | ||
40 | Version: 1.7 | |
41 | Date : 18/04/2008 | |
42 | Author : Ian Ventura-Whiting (Fizz) | |
43 | Changes: The following are a list of changes | |
44 | since the previous version: | |
45 | > Added STARTTLS SMTP capability | |
46 | > Fixed XML output format bug | |
47 | ||
48 | Version: 1.6 | |
49 | Date : 30/12/2007 | |
50 | Author : Ian Ventura-Whiting (Fizz) | |
51 | Changes: The following are a list of changes | |
52 | since the previous version: | |
53 | > Added man page. | |
54 | > Improved certificate checking | |
55 | > Added Makefile | |
56 | ||
57 | Version: 1.5 | |
58 | Date : 25/09/2007 | |
59 | Author : Ian Ventura-Whiting (Fizz) | |
60 | Changes: The following are a list of changes | |
61 | since the previous version: | |
62 | > Update to the license to make it | |
63 | BINARY compatible with OpenSSL. Its | |
64 | then easier for the packagers. | |
65 | ||
66 | Version: 1.4 | |
67 | Date : 03/09/2007 | |
68 | Author : Ian Ventura-Whiting (Fizz) | |
69 | Changes: The following are a list of changes | |
70 | since the previous version: | |
71 | > Added Server Certificate ouput. | |
72 | > Added support for client certs. | |
73 | > Added support for private keys | |
74 | and password. | |
75 | > Added support for PKCS#12. | |
76 | > Fixed xml output. | |
77 | ||
78 | Version: 1.3 | |
79 | Date : 06/08/2007 | |
80 | Author : Ian Ventura-Whiting (Fizz) | |
81 | Changes: The following are a list of changes | |
82 | since the previous version: | |
83 | > Added XML file output option. | |
84 | > Improved help text. | |
85 | > Added program URL. | |
86 | ||
87 | Version: 1.2 | |
88 | Date : 16/07/2007 | |
89 | Author : Ian Ventura-Whiting (Fizz) | |
90 | Changes: The following are a list of changes | |
91 | since the previous version: | |
92 | > Removed unused variable | |
93 | > Other minor changes. | |
94 | ||
95 | Version: 1.1 | |
96 | Date : 13/07/2007 | |
97 | Author : Ian Ventura-Whiting (Fizz) | |
98 | Changes: The following are a list of changes | |
99 | since the previous version: | |
100 | > Correction in banner text | |
101 | > Host:Port now directly from the | |
102 | command-line. | |
103 | ||
104 | Version: 1.0 | |
105 | Date : 13/07/2007 | |
106 | Author : Ian Ventura-Whiting (Fizz) | |
107 | Notes : Initial version of sslscan⏎ |
0 | Requirements: | |
1 | OpenSSL | |
2 | ||
3 | Makefile build: | |
4 | make | |
5 | make install (as root) | |
6 | ||
7 | Manual Build: | |
8 | sslscan can be built manually using the following | |
9 | command: | |
10 | ||
11 | gcc -lssl -o sslscan sslscan.c | |
12 |
0 | GNU GENERAL PUBLIC LICENSE | |
1 | Version 3, 29 June 2007 | |
2 | ||
3 | Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/> | |
4 | Everyone is permitted to copy and distribute verbatim copies | |
5 | of this license document, but changing it is not allowed. | |
6 | ||
7 | Preamble | |
8 | ||
9 | The GNU General Public License is a free, copyleft license for | |
10 | software and other kinds of works. | |
11 | ||
12 | The licenses for most software and other practical works are designed | |
13 | to take away your freedom to share and change the works. By contrast, | |
14 | the GNU General Public License is intended to guarantee your freedom to | |
15 | share and change all versions of a program--to make sure it remains free | |
16 | software for all its users. We, the Free Software Foundation, use the | |
17 | GNU General Public License for most of our software; it applies also to | |
18 | any other work released this way by its authors. You can apply it to | |
19 | your programs, too. | |
20 | ||
21 | When we speak of free software, we are referring to freedom, not | |
22 | price. Our General Public Licenses are designed to make sure that you | |
23 | have the freedom to distribute copies of free software (and charge for | |
24 | them if you wish), that you receive source code or can get it if you | |
25 | want it, that you can change the software or use pieces of it in new | |
26 | free programs, and that you know you can do these things. | |
27 | ||
28 | To protect your rights, we need to prevent others from denying you | |
29 | these rights or asking you to surrender the rights. Therefore, you have | |
30 | certain responsibilities if you distribute copies of the software, or if | |
31 | you modify it: responsibilities to respect the freedom of others. | |
32 | ||
33 | For example, if you distribute copies of such a program, whether | |
34 | gratis or for a fee, you must pass on to the recipients the same | |
35 | freedoms that you received. You must make sure that they, too, receive | |
36 | or can get the source code. And you must show them these terms so they | |
37 | know their rights. | |
38 | ||
39 | Developers that use the GNU GPL protect your rights with two steps: | |
40 | (1) assert copyright on the software, and (2) offer you this License | |
41 | giving you legal permission to copy, distribute and/or modify it. | |
42 | ||
43 | For the developers' and authors' protection, the GPL clearly explains | |
44 | that there is no warranty for this free software. For both users' and | |
45 | authors' sake, the GPL requires that modified versions be marked as | |
46 | changed, so that their problems will not be attributed erroneously to | |
47 | authors of previous versions. | |
48 | ||
49 | Some devices are designed to deny users access to install or run | |
50 | modified versions of the software inside them, although the manufacturer | |
51 | can do so. This is fundamentally incompatible with the aim of | |
52 | protecting users' freedom to change the software. The systematic | |
53 | pattern of such abuse occurs in the area of products for individuals to | |
54 | use, which is precisely where it is most unacceptable. Therefore, we | |
55 | have designed this version of the GPL to prohibit the practice for those | |
56 | products. If such problems arise substantially in other domains, we | |
57 | stand ready to extend this provision to those domains in future versions | |
58 | of the GPL, as needed to protect the freedom of users. | |
59 | ||
60 | Finally, every program is threatened constantly by software patents. | |
61 | States should not allow patents to restrict development and use of | |
62 | software on general-purpose computers, but in those that do, we wish to | |
63 | avoid the special danger that patents applied to a free program could | |
64 | make it effectively proprietary. To prevent this, the GPL assures that | |
65 | patents cannot be used to render the program non-free. | |
66 | ||
67 | The precise terms and conditions for copying, distribution and | |
68 | modification follow. | |
69 | ||
70 | TERMS AND CONDITIONS | |
71 | ||
72 | 0. Definitions. | |
73 | ||
74 | "This License" refers to version 3 of the GNU General Public License. | |
75 | ||
76 | "Copyright" also means copyright-like laws that apply to other kinds of | |
77 | works, such as semiconductor masks. | |
78 | ||
79 | "The Program" refers to any copyrightable work licensed under this | |
80 | License. Each licensee is addressed as "you". "Licensees" and | |
81 | "recipients" may be individuals or organizations. | |
82 | ||
83 | To "modify" a work means to copy from or adapt all or part of the work | |
84 | in a fashion requiring copyright permission, other than the making of an | |
85 | exact copy. The resulting work is called a "modified version" of the | |
86 | earlier work or a work "based on" the earlier work. | |
87 | ||
88 | A "covered work" means either the unmodified Program or a work based | |
89 | on the Program. | |
90 | ||
91 | To "propagate" a work means to do anything with it that, without | |
92 | permission, would make you directly or secondarily liable for | |
93 | infringement under applicable copyright law, except executing it on a | |
94 | computer or modifying a private copy. Propagation includes copying, | |
95 | distribution (with or without modification), making available to the | |
96 | public, and in some countries other activities as well. | |
97 | ||
98 | To "convey" a work means any kind of propagation that enables other | |
99 | parties to make or receive copies. Mere interaction with a user through | |
100 | a computer network, with no transfer of a copy, is not conveying. | |
101 | ||
102 | An interactive user interface displays "Appropriate Legal Notices" | |
103 | to the extent that it includes a convenient and prominently visible | |
104 | feature that (1) displays an appropriate copyright notice, and (2) | |
105 | tells the user that there is no warranty for the work (except to the | |
106 | extent that warranties are provided), that licensees may convey the | |
107 | work under this License, and how to view a copy of this License. If | |
108 | the interface presents a list of user commands or options, such as a | |
109 | menu, a prominent item in the list meets this criterion. | |
110 | ||
111 | 1. Source Code. | |
112 | ||
113 | The "source code" for a work means the preferred form of the work | |
114 | for making modifications to it. "Object code" means any non-source | |
115 | form of a work. | |
116 | ||
117 | A "Standard Interface" means an interface that either is an official | |
118 | standard defined by a recognized standards body, or, in the case of | |
119 | interfaces specified for a particular programming language, one that | |
120 | is widely used among developers working in that language. | |
121 | ||
122 | The "System Libraries" of an executable work include anything, other | |
123 | than the work as a whole, that (a) is included in the normal form of | |
124 | packaging a Major Component, but which is not part of that Major | |
125 | Component, and (b) serves only to enable use of the work with that | |
126 | Major Component, or to implement a Standard Interface for which an | |
127 | implementation is available to the public in source code form. A | |
128 | "Major Component", in this context, means a major essential component | |
129 | (kernel, window system, and so on) of the specific operating system | |
130 | (if any) on which the executable work runs, or a compiler used to | |
131 | produce the work, or an object code interpreter used to run it. | |
132 | ||
133 | The "Corresponding Source" for a work in object code form means all | |
134 | the source code needed to generate, install, and (for an executable | |
135 | work) run the object code and to modify the work, including scripts to | |
136 | control those activities. However, it does not include the work's | |
137 | System Libraries, or general-purpose tools or generally available free | |
138 | programs which are used unmodified in performing those activities but | |
139 | which are not part of the work. For example, Corresponding Source | |
140 | includes interface definition files associated with source files for | |
141 | the work, and the source code for shared libraries and dynamically | |
142 | linked subprograms that the work is specifically designed to require, | |
143 | such as by intimate data communication or control flow between those | |
144 | subprograms and other parts of the work. | |
145 | ||
146 | The Corresponding Source need not include anything that users | |
147 | can regenerate automatically from other parts of the Corresponding | |
148 | Source. | |
149 | ||
150 | The Corresponding Source for a work in source code form is that | |
151 | same work. | |
152 | ||
153 | 2. Basic Permissions. | |
154 | ||
155 | All rights granted under this License are granted for the term of | |
156 | copyright on the Program, and are irrevocable provided the stated | |
157 | conditions are met. This License explicitly affirms your unlimited | |
158 | permission to run the unmodified Program. The output from running a | |
159 | covered work is covered by this License only if the output, given its | |
160 | content, constitutes a covered work. This License acknowledges your | |
161 | rights of fair use or other equivalent, as provided by copyright law. | |
162 | ||
163 | You may make, run and propagate covered works that you do not | |
164 | convey, without conditions so long as your license otherwise remains | |
165 | in force. You may convey covered works to others for the sole purpose | |
166 | of having them make modifications exclusively for you, or provide you | |
167 | with facilities for running those works, provided that you comply with | |
168 | the terms of this License in conveying all material for which you do | |
169 | not control copyright. Those thus making or running the covered works | |
170 | for you must do so exclusively on your behalf, under your direction | |
171 | and control, on terms that prohibit them from making any copies of | |
172 | your copyrighted material outside their relationship with you. | |
173 | ||
174 | Conveying under any other circumstances is permitted solely under | |
175 | the conditions stated below. Sublicensing is not allowed; section 10 | |
176 | makes it unnecessary. | |
177 | ||
178 | 3. Protecting Users' Legal Rights From Anti-Circumvention Law. | |
179 | ||
180 | No covered work shall be deemed part of an effective technological | |
181 | measure under any applicable law fulfilling obligations under article | |
182 | 11 of the WIPO copyright treaty adopted on 20 December 1996, or | |
183 | similar laws prohibiting or restricting circumvention of such | |
184 | measures. | |
185 | ||
186 | When you convey a covered work, you waive any legal power to forbid | |
187 | circumvention of technological measures to the extent such circumvention | |
188 | is effected by exercising rights under this License with respect to | |
189 | the covered work, and you disclaim any intention to limit operation or | |
190 | modification of the work as a means of enforcing, against the work's | |
191 | users, your or third parties' legal rights to forbid circumvention of | |
192 | technological measures. | |
193 | ||
194 | 4. Conveying Verbatim Copies. | |
195 | ||
196 | You may convey verbatim copies of the Program's source code as you | |
197 | receive it, in any medium, provided that you conspicuously and | |
198 | appropriately publish on each copy an appropriate copyright notice; | |
199 | keep intact all notices stating that this License and any | |
200 | non-permissive terms added in accord with section 7 apply to the code; | |
201 | keep intact all notices of the absence of any warranty; and give all | |
202 | recipients a copy of this License along with the Program. | |
203 | ||
204 | You may charge any price or no price for each copy that you convey, | |
205 | and you may offer support or warranty protection for a fee. | |
206 | ||
207 | 5. Conveying Modified Source Versions. | |
208 | ||
209 | You may convey a work based on the Program, or the modifications to | |
210 | produce it from the Program, in the form of source code under the | |
211 | terms of section 4, provided that you also meet all of these conditions: | |
212 | ||
213 | a) The work must carry prominent notices stating that you modified | |
214 | it, and giving a relevant date. | |
215 | ||
216 | b) The work must carry prominent notices stating that it is | |
217 | released under this License and any conditions added under section | |
218 | 7. This requirement modifies the requirement in section 4 to | |
219 | "keep intact all notices". | |
220 | ||
221 | c) You must license the entire work, as a whole, under this | |
222 | License to anyone who comes into possession of a copy. This | |
223 | License will therefore apply, along with any applicable section 7 | |
224 | additional terms, to the whole of the work, and all its parts, | |
225 | regardless of how they are packaged. This License gives no | |
226 | permission to license the work in any other way, but it does not | |
227 | invalidate such permission if you have separately received it. | |
228 | ||
229 | d) If the work has interactive user interfaces, each must display | |
230 | Appropriate Legal Notices; however, if the Program has interactive | |
231 | interfaces that do not display Appropriate Legal Notices, your | |
232 | work need not make them do so. | |
233 | ||
234 | A compilation of a covered work with other separate and independent | |
235 | works, which are not by their nature extensions of the covered work, | |
236 | and which are not combined with it such as to form a larger program, | |
237 | in or on a volume of a storage or distribution medium, is called an | |
238 | "aggregate" if the compilation and its resulting copyright are not | |
239 | used to limit the access or legal rights of the compilation's users | |
240 | beyond what the individual works permit. Inclusion of a covered work | |
241 | in an aggregate does not cause this License to apply to the other | |
242 | parts of the aggregate. | |
243 | ||
244 | 6. Conveying Non-Source Forms. | |
245 | ||
246 | You may convey a covered work in object code form under the terms | |
247 | of sections 4 and 5, provided that you also convey the | |
248 | machine-readable Corresponding Source under the terms of this License, | |
249 | in one of these ways: | |
250 | ||
251 | a) Convey the object code in, or embodied in, a physical product | |
252 | (including a physical distribution medium), accompanied by the | |
253 | Corresponding Source fixed on a durable physical medium | |
254 | customarily used for software interchange. | |
255 | ||
256 | b) Convey the object code in, or embodied in, a physical product | |
257 | (including a physical distribution medium), accompanied by a | |
258 | written offer, valid for at least three years and valid for as | |
259 | long as you offer spare parts or customer support for that product | |
260 | model, to give anyone who possesses the object code either (1) a | |
261 | copy of the Corresponding Source for all the software in the | |
262 | product that is covered by this License, on a durable physical | |
263 | medium customarily used for software interchange, for a price no | |
264 | more than your reasonable cost of physically performing this | |
265 | conveying of source, or (2) access to copy the | |
266 | Corresponding Source from a network server at no charge. | |
267 | ||
268 | c) Convey individual copies of the object code with a copy of the | |
269 | written offer to provide the Corresponding Source. This | |
270 | alternative is allowed only occasionally and noncommercially, and | |
271 | only if you received the object code with such an offer, in accord | |
272 | with subsection 6b. | |
273 | ||
274 | d) Convey the object code by offering access from a designated | |
275 | place (gratis or for a charge), and offer equivalent access to the | |
276 | Corresponding Source in the same way through the same place at no | |
277 | further charge. You need not require recipients to copy the | |
278 | Corresponding Source along with the object code. If the place to | |
279 | copy the object code is a network server, the Corresponding Source | |
280 | may be on a different server (operated by you or a third party) | |
281 | that supports equivalent copying facilities, provided you maintain | |
282 | clear directions next to the object code saying where to find the | |
283 | Corresponding Source. Regardless of what server hosts the | |
284 | Corresponding Source, you remain obligated to ensure that it is | |
285 | available for as long as needed to satisfy these requirements. | |
286 | ||
287 | e) Convey the object code using peer-to-peer transmission, provided | |
288 | you inform other peers where the object code and Corresponding | |
289 | Source of the work are being offered to the general public at no | |
290 | charge under subsection 6d. | |
291 | ||
292 | A separable portion of the object code, whose source code is excluded | |
293 | from the Corresponding Source as a System Library, need not be | |
294 | included in conveying the object code work. | |
295 | ||
296 | A "User Product" is either (1) a "consumer product", which means any | |
297 | tangible personal property which is normally used for personal, family, | |
298 | or household purposes, or (2) anything designed or sold for incorporation | |
299 | into a dwelling. In determining whether a product is a consumer product, | |
300 | doubtful cases shall be resolved in favor of coverage. For a particular | |
301 | product received by a particular user, "normally used" refers to a | |
302 | typical or common use of that class of product, regardless of the status | |
303 | of the particular user or of the way in which the particular user | |
304 | actually uses, or expects or is expected to use, the product. A product | |
305 | is a consumer product regardless of whether the product has substantial | |
306 | commercial, industrial or non-consumer uses, unless such uses represent | |
307 | the only significant mode of use of the product. | |
308 | ||
309 | "Installation Information" for a User Product means any methods, | |
310 | procedures, authorization keys, or other information required to install | |
311 | and execute modified versions of a covered work in that User Product from | |
312 | a modified version of its Corresponding Source. The information must | |
313 | suffice to ensure that the continued functioning of the modified object | |
314 | code is in no case prevented or interfered with solely because | |
315 | modification has been made. | |
316 | ||
317 | If you convey an object code work under this section in, or with, or | |
318 | specifically for use in, a User Product, and the conveying occurs as | |
319 | part of a transaction in which the right of possession and use of the | |
320 | User Product is transferred to the recipient in perpetuity or for a | |
321 | fixed term (regardless of how the transaction is characterized), the | |
322 | Corresponding Source conveyed under this section must be accompanied | |
323 | by the Installation Information. But this requirement does not apply | |
324 | if neither you nor any third party retains the ability to install | |
325 | modified object code on the User Product (for example, the work has | |
326 | been installed in ROM). | |
327 | ||
328 | The requirement to provide Installation Information does not include a | |
329 | requirement to continue to provide support service, warranty, or updates | |
330 | for a work that has been modified or installed by the recipient, or for | |
331 | the User Product in which it has been modified or installed. Access to a | |
332 | network may be denied when the modification itself materially and | |
333 | adversely affects the operation of the network or violates the rules and | |
334 | protocols for communication across the network. | |
335 | ||
336 | Corresponding Source conveyed, and Installation Information provided, | |
337 | in accord with this section must be in a format that is publicly | |
338 | documented (and with an implementation available to the public in | |
339 | source code form), and must require no special password or key for | |
340 | unpacking, reading or copying. | |
341 | ||
342 | 7. Additional Terms. | |
343 | ||
344 | "Additional permissions" are terms that supplement the terms of this | |
345 | License by making exceptions from one or more of its conditions. | |
346 | Additional permissions that are applicable to the entire Program shall | |
347 | be treated as though they were included in this License, to the extent | |
348 | that they are valid under applicable law. If additional permissions | |
349 | apply only to part of the Program, that part may be used separately | |
350 | under those permissions, but the entire Program remains governed by | |
351 | this License without regard to the additional permissions. | |
352 | ||
353 | When you convey a copy of a covered work, you may at your option | |
354 | remove any additional permissions from that copy, or from any part of | |
355 | it. (Additional permissions may be written to require their own | |
356 | removal in certain cases when you modify the work.) You may place | |
357 | additional permissions on material, added by you to a covered work, | |
358 | for which you have or can give appropriate copyright permission. | |
359 | ||
360 | Notwithstanding any other provision of this License, for material you | |
361 | add to a covered work, you may (if authorized by the copyright holders of | |
362 | that material) supplement the terms of this License with terms: | |
363 | ||
364 | a) Disclaiming warranty or limiting liability differently from the | |
365 | terms of sections 15 and 16 of this License; or | |
366 | ||
367 | b) Requiring preservation of specified reasonable legal notices or | |
368 | author attributions in that material or in the Appropriate Legal | |
369 | Notices displayed by works containing it; or | |
370 | ||
371 | c) Prohibiting misrepresentation of the origin of that material, or | |
372 | requiring that modified versions of such material be marked in | |
373 | reasonable ways as different from the original version; or | |
374 | ||
375 | d) Limiting the use for publicity purposes of names of licensors or | |
376 | authors of the material; or | |
377 | ||
378 | e) Declining to grant rights under trademark law for use of some | |
379 | trade names, trademarks, or service marks; or | |
380 | ||
381 | f) Requiring indemnification of licensors and authors of that | |
382 | material by anyone who conveys the material (or modified versions of | |
383 | it) with contractual assumptions of liability to the recipient, for | |
384 | any liability that these contractual assumptions directly impose on | |
385 | those licensors and authors. | |
386 | ||
387 | All other non-permissive additional terms are considered "further | |
388 | restrictions" within the meaning of section 10. If the Program as you | |
389 | received it, or any part of it, contains a notice stating that it is | |
390 | governed by this License along with a term that is a further | |
391 | restriction, you may remove that term. If a license document contains | |
392 | a further restriction but permits relicensing or conveying under this | |
393 | License, you may add to a covered work material governed by the terms | |
394 | of that license document, provided that the further restriction does | |
395 | not survive such relicensing or conveying. | |
396 | ||
397 | If you add terms to a covered work in accord with this section, you | |
398 | must place, in the relevant source files, a statement of the | |
399 | additional terms that apply to those files, or a notice indicating | |
400 | where to find the applicable terms. | |
401 | ||
402 | Additional terms, permissive or non-permissive, may be stated in the | |
403 | form of a separately written license, or stated as exceptions; | |
404 | the above requirements apply either way. | |
405 | ||
406 | 8. Termination. | |
407 | ||
408 | You may not propagate or modify a covered work except as expressly | |
409 | provided under this License. Any attempt otherwise to propagate or | |
410 | modify it is void, and will automatically terminate your rights under | |
411 | this License (including any patent licenses granted under the third | |
412 | paragraph of section 11). | |
413 | ||
414 | However, if you cease all violation of this License, then your | |
415 | license from a particular copyright holder is reinstated (a) | |
416 | provisionally, unless and until the copyright holder explicitly and | |
417 | finally terminates your license, and (b) permanently, if the copyright | |
418 | holder fails to notify you of the violation by some reasonable means | |
419 | prior to 60 days after the cessation. | |
420 | ||
421 | Moreover, your license from a particular copyright holder is | |
422 | reinstated permanently if the copyright holder notifies you of the | |
423 | violation by some reasonable means, this is the first time you have | |
424 | received notice of violation of this License (for any work) from that | |
425 | copyright holder, and you cure the violation prior to 30 days after | |
426 | your receipt of the notice. | |
427 | ||
428 | Termination of your rights under this section does not terminate the | |
429 | licenses of parties who have received copies or rights from you under | |
430 | this License. If your rights have been terminated and not permanently | |
431 | reinstated, you do not qualify to receive new licenses for the same | |
432 | material under section 10. | |
433 | ||
434 | 9. Acceptance Not Required for Having Copies. | |
435 | ||
436 | You are not required to accept this License in order to receive or | |
437 | run a copy of the Program. Ancillary propagation of a covered work | |
438 | occurring solely as a consequence of using peer-to-peer transmission | |
439 | to receive a copy likewise does not require acceptance. However, | |
440 | nothing other than this License grants you permission to propagate or | |
441 | modify any covered work. These actions infringe copyright if you do | |
442 | not accept this License. Therefore, by modifying or propagating a | |
443 | covered work, you indicate your acceptance of this License to do so. | |
444 | ||
445 | 10. Automatic Licensing of Downstream Recipients. | |
446 | ||
447 | Each time you convey a covered work, the recipient automatically | |
448 | receives a license from the original licensors, to run, modify and | |
449 | propagate that work, subject to this License. You are not responsible | |
450 | for enforcing compliance by third parties with this License. | |
451 | ||
452 | An "entity transaction" is a transaction transferring control of an | |
453 | organization, or substantially all assets of one, or subdividing an | |
454 | organization, or merging organizations. If propagation of a covered | |
455 | work results from an entity transaction, each party to that | |
456 | transaction who receives a copy of the work also receives whatever | |
457 | licenses to the work the party's predecessor in interest had or could | |
458 | give under the previous paragraph, plus a right to possession of the | |
459 | Corresponding Source of the work from the predecessor in interest, if | |
460 | the predecessor has it or can get it with reasonable efforts. | |
461 | ||
462 | You may not impose any further restrictions on the exercise of the | |
463 | rights granted or affirmed under this License. For example, you may | |
464 | not impose a license fee, royalty, or other charge for exercise of | |
465 | rights granted under this License, and you may not initiate litigation | |
466 | (including a cross-claim or counterclaim in a lawsuit) alleging that | |
467 | any patent claim is infringed by making, using, selling, offering for | |
468 | sale, or importing the Program or any portion of it. | |
469 | ||
470 | 11. Patents. | |
471 | ||
472 | A "contributor" is a copyright holder who authorizes use under this | |
473 | License of the Program or a work on which the Program is based. The | |
474 | work thus licensed is called the contributor's "contributor version". | |
475 | ||
476 | A contributor's "essential patent claims" are all patent claims | |
477 | owned or controlled by the contributor, whether already acquired or | |
478 | hereafter acquired, that would be infringed by some manner, permitted | |
479 | by this License, of making, using, or selling its contributor version, | |
480 | but do not include claims that would be infringed only as a | |
481 | consequence of further modification of the contributor version. For | |
482 | purposes of this definition, "control" includes the right to grant | |
483 | patent sublicenses in a manner consistent with the requirements of | |
484 | this License. | |
485 | ||
486 | Each contributor grants you a non-exclusive, worldwide, royalty-free | |
487 | patent license under the contributor's essential patent claims, to | |
488 | make, use, sell, offer for sale, import and otherwise run, modify and | |
489 | propagate the contents of its contributor version. | |
490 | ||
491 | In the following three paragraphs, a "patent license" is any express | |
492 | agreement or commitment, however denominated, not to enforce a patent | |
493 | (such as an express permission to practice a patent or covenant not to | |
494 | sue for patent infringement). To "grant" such a patent license to a | |
495 | party means to make such an agreement or commitment not to enforce a | |
496 | patent against the party. | |
497 | ||
498 | If you convey a covered work, knowingly relying on a patent license, | |
499 | and the Corresponding Source of the work is not available for anyone | |
500 | to copy, free of charge and under the terms of this License, through a | |
501 | publicly available network server or other readily accessible means, | |
502 | then you must either (1) cause the Corresponding Source to be so | |
503 | available, or (2) arrange to deprive yourself of the benefit of the | |
504 | patent license for this particular work, or (3) arrange, in a manner | |
505 | consistent with the requirements of this License, to extend the patent | |
506 | license to downstream recipients. "Knowingly relying" means you have | |
507 | actual knowledge that, but for the patent license, your conveying the | |
508 | covered work in a country, or your recipient's use of the covered work | |
509 | in a country, would infringe one or more identifiable patents in that | |
510 | country that you have reason to believe are valid. | |
511 | ||
512 | If, pursuant to or in connection with a single transaction or | |
513 | arrangement, you convey, or propagate by procuring conveyance of, a | |
514 | covered work, and grant a patent license to some of the parties | |
515 | receiving the covered work authorizing them to use, propagate, modify | |
516 | or convey a specific copy of the covered work, then the patent license | |
517 | you grant is automatically extended to all recipients of the covered | |
518 | work and works based on it. | |
519 | ||
520 | A patent license is "discriminatory" if it does not include within | |
521 | the scope of its coverage, prohibits the exercise of, or is | |
522 | conditioned on the non-exercise of one or more of the rights that are | |
523 | specifically granted under this License. You may not convey a covered | |
524 | work if you are a party to an arrangement with a third party that is | |
525 | in the business of distributing software, under which you make payment | |
526 | to the third party based on the extent of your activity of conveying | |
527 | the work, and under which the third party grants, to any of the | |
528 | parties who would receive the covered work from you, a discriminatory | |
529 | patent license (a) in connection with copies of the covered work | |
530 | conveyed by you (or copies made from those copies), or (b) primarily | |
531 | for and in connection with specific products or compilations that | |
532 | contain the covered work, unless you entered into that arrangement, | |
533 | or that patent license was granted, prior to 28 March 2007. | |
534 | ||
535 | Nothing in this License shall be construed as excluding or limiting | |
536 | any implied license or other defenses to infringement that may | |
537 | otherwise be available to you under applicable patent law. | |
538 | ||
539 | 12. No Surrender of Others' Freedom. | |
540 | ||
541 | If conditions are imposed on you (whether by court order, agreement or | |
542 | otherwise) that contradict the conditions of this License, they do not | |
543 | excuse you from the conditions of this License. If you cannot convey a | |
544 | covered work so as to satisfy simultaneously your obligations under this | |
545 | License and any other pertinent obligations, then as a consequence you may | |
546 | not convey it at all. For example, if you agree to terms that obligate you | |
547 | to collect a royalty for further conveying from those to whom you convey | |
548 | the Program, the only way you could satisfy both those terms and this | |
549 | License would be to refrain entirely from conveying the Program. | |
550 | ||
551 | 13. Use with the GNU Affero General Public License. | |
552 | ||
553 | Notwithstanding any other provision of this License, you have | |
554 | permission to link or combine any covered work with a work licensed | |
555 | under version 3 of the GNU Affero General Public License into a single | |
556 | combined work, and to convey the resulting work. The terms of this | |
557 | License will continue to apply to the part which is the covered work, | |
558 | but the special requirements of the GNU Affero General Public License, | |
559 | section 13, concerning interaction through a network will apply to the | |
560 | combination as such. | |
561 | ||
562 | 14. Revised Versions of this License. | |
563 | ||
564 | The Free Software Foundation may publish revised and/or new versions of | |
565 | the GNU General Public License from time to time. Such new versions will | |
566 | be similar in spirit to the present version, but may differ in detail to | |
567 | address new problems or concerns. | |
568 | ||
569 | Each version is given a distinguishing version number. If the | |
570 | Program specifies that a certain numbered version of the GNU General | |
571 | Public License "or any later version" applies to it, you have the | |
572 | option of following the terms and conditions either of that numbered | |
573 | version or of any later version published by the Free Software | |
574 | Foundation. If the Program does not specify a version number of the | |
575 | GNU General Public License, you may choose any version ever published | |
576 | by the Free Software Foundation. | |
577 | ||
578 | If the Program specifies that a proxy can decide which future | |
579 | versions of the GNU General Public License can be used, that proxy's | |
580 | public statement of acceptance of a version permanently authorizes you | |
581 | to choose that version for the Program. | |
582 | ||
583 | Later license versions may give you additional or different | |
584 | permissions. However, no additional obligations are imposed on any | |
585 | author or copyright holder as a result of your choosing to follow a | |
586 | later version. | |
587 | ||
588 | 15. Disclaimer of Warranty. | |
589 | ||
590 | THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY | |
591 | APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT | |
592 | HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY | |
593 | OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, | |
594 | THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR | |
595 | PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM | |
596 | IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF | |
597 | ALL NECESSARY SERVICING, REPAIR OR CORRECTION. | |
598 | ||
599 | 16. Limitation of Liability. | |
600 | ||
601 | IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING | |
602 | WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS | |
603 | THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY | |
604 | GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE | |
605 | USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF | |
606 | DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD | |
607 | PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), | |
608 | EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF | |
609 | SUCH DAMAGES. | |
610 | ||
611 | 17. Interpretation of Sections 15 and 16. | |
612 | ||
613 | If the disclaimer of warranty and limitation of liability provided | |
614 | above cannot be given local legal effect according to their terms, | |
615 | reviewing courts shall apply local law that most closely approximates | |
616 | an absolute waiver of all civil liability in connection with the | |
617 | Program, unless a warranty or assumption of liability accompanies a | |
618 | copy of the Program in return for a fee. | |
619 | ||
620 | END OF TERMS AND CONDITIONS | |
621 |
0 | SRCS = sslscan.c | |
1 | BINPATH = /usr/bin/ | |
2 | MANPATH = /usr/share/man/ | |
3 | ||
4 | all: | |
5 | gcc -g -Wall -lssl -o sslscan $(SRCS) $(LDFLAGS) $(CFLAGS) | |
6 | ||
7 | install: | |
8 | cp sslscan $(BINPATH) | |
9 | cp sslscan.1 $(MANPATH)man1 | |
10 | ||
11 | uninstall: | |
12 | rm -f $(BINPATH)sslscan | |
13 | rm -f $(MANPATH)man1/sslscan.1 | |
14 | ||
15 | clean: | |
16 | rm -f sslscan |
0 | .TH SSLSCAN 1 "May 19, 2009" | |
1 | .SH NAME | |
2 | sslscan \- Fast SSL scanner | |
3 | .SH SYNOPSIS | |
4 | .B sslscan | |
5 | .RI [ options ] " [host:port | host]" | |
6 | .SH DESCRIPTION | |
7 | This manual page documents briefly the | |
8 | .B sslscan | |
9 | command | |
10 | .PP | |
11 | \fBsslscan\fP queries SSL services, such as HTTPS, in order to determine the | |
12 | ciphers that are supported. | |
13 | .br | |
14 | SSLScan is designed to be easy, lean and fast. The output includes preferred | |
15 | ciphers of the SSL service, | |
16 | .br | |
17 | the certificate and output is in text and XML formats. | |
18 | .SH OPTIONS | |
19 | .TP | |
20 | .B \-\-help | |
21 | .br | |
22 | Show summary of options. | |
23 | .TP | |
24 | .B \-\-version | |
25 | Show version of program. | |
26 | .TP | |
27 | .B \-\-targets=<file> | |
28 | A file containing a list of hosts to | |
29 | check. Hosts can be supplied with | |
30 | ports (i.e. host:port). One target per line. | |
31 | .TP | |
32 | .B \-\-no\-failed | |
33 | List only accepted ciphers | |
34 | (default is to listing all ciphers). | |
35 | .TP | |
36 | .B \-\-ssl2 | |
37 | .br | |
38 | Only check SSLv2 ciphers. | |
39 | .TP | |
40 | .B \-\-ssl3 | |
41 | .br | |
42 | Only check SSLv3 ciphers. | |
43 | .TP | |
44 | .B \-\-pk=<file> | |
45 | A file containing the private key or | |
46 | a PKCS#12 file containing a private | |
47 | key/certificate pair (as produced by | |
48 | MSIE and Netscape). | |
49 | .TP | |
50 | .B \-\-pkpass=<password> | |
51 | The password for the private key or PKCS#12 file. | |
52 | .TP | |
53 | .B \-\-certs=<file> | |
54 | A file containing PEM/ASN1 formatted client certificates. | |
55 | .TP | |
56 | .B \-\-starttls | |
57 | Executes a STARTTLS in order to test the SSL capabilities | |
58 | of an SMTP service with TLS support. This option automatically | |
59 | forces TLS only ciphers, no need to specify it. | |
60 | .TP | |
61 | .B \-\-html | |
62 | Makes a HTML request after a successful connection and returns | |
63 | the server response code. | |
64 | .TP | |
65 | .B \-\-bugs | |
66 | Enables workarounds for SSL bugs. | |
67 | .TP | |
68 | .B \-\-xml=<file> | |
69 | Output results to an XML file. | |
70 | .br | |
71 | .SH AUTHOR | |
72 | sslscan was written by Ian Ventura-Whiting <[email protected]>. | |
73 | .br | |
74 | This manual page was originally written by Marvin Stark <[email protected]>. |
0 | /*************************************************************************** | |
1 | * sslscan - A SSL cipher scanning tool * | |
2 | * Copyright 2007-2009 by Ian Ventura-Whiting (Fizz) * | |
3 | * [email protected] * | |
4 | * * | |
5 | * This program is free software; you can redistribute it and/or modify * | |
6 | * it under the terms of the GNU General Public License as published by * | |
7 | * the Free Software Foundation; either version 3 of the License, or * | |
8 | * (at your option) any later version. * | |
9 | * * | |
10 | * This program is distributed in the hope that it will be useful, * | |
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of * | |
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * | |
13 | * GNU General Public License for more details. * | |
14 | * * | |
15 | * You should have received a copy of the GNU General Public License * | |
16 | * along with this program. If not, see <http://www.gnu.org/licenses/>. * | |
17 | * * | |
18 | * In addition, as a special exception, the copyright holders give * | |
19 | * permission to link the code of portions of this program with the * | |
20 | * OpenSSL library under certain conditions as described in each * | |
21 | * individual source file, and distribute linked combinations * | |
22 | * including the two. * | |
23 | * You must obey the GNU General Public License in all respects * | |
24 | * for all of the code used other than OpenSSL. If you modify * | |
25 | * file(s) with this exception, you may extend this exception to your * | |
26 | * version of the file(s), but you are not obligated to do so. If you * | |
27 | * do not wish to do so, delete this exception statement from your * | |
28 | * version. If you delete this exception statement from all source * | |
29 | * files in the program, then also delete it here. * | |
30 | ***************************************************************************/ | |
31 | ||
32 | // Includes... | |
33 | #include <string.h> | |
34 | #include <netdb.h> | |
35 | #include <unistd.h> | |
36 | #include <sys/stat.h> | |
37 | #include <sys/socket.h> | |
38 | #include <openssl/err.h> | |
39 | #include <openssl/ssl.h> | |
40 | #include <openssl/pkcs12.h> | |
41 | #include <openssl/x509.h> | |
42 | #include <openssl/x509v3.h> | |
43 | ||
44 | // Defines... | |
45 | #define false 0 | |
46 | #define true 1 | |
47 | ||
48 | #define mode_help 0 | |
49 | #define mode_version 1 | |
50 | #define mode_single 2 | |
51 | #define mode_multiple 3 | |
52 | ||
53 | #define BUFFERSIZE 1024 | |
54 | ||
55 | #define ssl_all 0 | |
56 | #define ssl_v2 1 | |
57 | #define ssl_v3 2 | |
58 | #define tls_v1 3 | |
59 | ||
60 | // Colour Console Output... | |
61 | #if !defined(__WIN32__) | |
62 | const char *RESET = "[0m"; // DEFAULT | |
63 | const char *COL_RED = "[31m"; // RED | |
64 | const char *COL_BLUE = "[34m"; // BLUE | |
65 | const char *COL_GREEN = "[32m"; // GREEN | |
66 | #else | |
67 | const char *RESET = ""; | |
68 | const char *COL_RED = ""; | |
69 | const char *COL_BLUE = ""; | |
70 | const char *COL_GREEN = ""; | |
71 | #endif | |
72 | ||
73 | ||
74 | const char *program_banner = " _\n" | |
75 | " ___ ___| |___ ___ __ _ _ __\n" | |
76 | " / __/ __| / __|/ __/ _` | '_ \\\n" | |
77 | " \\__ \\__ \\ \\__ \\ (_| (_| | | | |\n" | |
78 | " |___/___/_|___/\\___\\__,_|_| |_|\n\n" | |
79 | " Version 1.8.2\n" | |
80 | " http://www.titania.co.uk\n" | |
81 | " Copyright Ian Ventura-Whiting 2009\n"; | |
82 | const char *program_version = "sslscan version 1.8.2\nhttp://www.titania.co.uk\nCopyright (C) Ian Ventura-Whiting 2009\n"; | |
83 | const char *xml_version = "1.8.2"; | |
84 | ||
85 | ||
86 | struct sslCipher | |
87 | { | |
88 | // Cipher Properties... | |
89 | const char *name; | |
90 | char *version; | |
91 | int bits; | |
92 | char description[512]; | |
93 | SSL_METHOD *sslMethod; | |
94 | struct sslCipher *next; | |
95 | }; | |
96 | ||
97 | struct sslCheckOptions | |
98 | { | |
99 | // Program Options... | |
100 | char host[512]; | |
101 | int port; | |
102 | int noFailed; | |
103 | int starttls; | |
104 | int sslVersion; | |
105 | int targets; | |
106 | int pout; | |
107 | int sslbugs; | |
108 | int http; | |
109 | ||
110 | // File Handles... | |
111 | FILE *xmlOutput; | |
112 | ||
113 | // TCP Connection Variables... | |
114 | struct hostent *hostStruct; | |
115 | struct sockaddr_in serverAddress; | |
116 | ||
117 | // SSL Variables... | |
118 | SSL_CTX *ctx; | |
119 | struct sslCipher *ciphers; | |
120 | char *clientCertsFile; | |
121 | char *privateKeyFile; | |
122 | char *privateKeyPassword; | |
123 | }; | |
124 | ||
125 | ||
126 | // Adds Ciphers to the Cipher List structure | |
127 | int populateCipherList(struct sslCheckOptions *options, SSL_METHOD *sslMethod) | |
128 | { | |
129 | // Variables... | |
130 | int returnCode = true; | |
131 | struct sslCipher *sslCipherPointer; | |
132 | int tempInt; | |
133 | int loop; | |
134 | STACK_OF(SSL_CIPHER) *cipherList; | |
135 | SSL *ssl = NULL; | |
136 | ||
137 | // Setup Context Object... | |
138 | options->ctx = SSL_CTX_new(sslMethod); | |
139 | if (options->ctx != NULL) | |
140 | { | |
141 | SSL_CTX_set_cipher_list(options->ctx, "ALL:COMPLEMENTOFALL"); | |
142 | ||
143 | // Create new SSL object | |
144 | ssl = SSL_new(options->ctx); | |
145 | if (ssl != NULL) | |
146 | { | |
147 | // Get List of Ciphers | |
148 | cipherList = SSL_get_ciphers(ssl); | |
149 | ||
150 | // Create Cipher Struct Entries... | |
151 | for (loop = 0; loop < sk_SSL_CIPHER_num(cipherList); loop++) | |
152 | { | |
153 | // Create Structure... | |
154 | if (options->ciphers == 0) | |
155 | { | |
156 | options->ciphers = malloc(sizeof(struct sslCipher)); | |
157 | sslCipherPointer = options->ciphers; | |
158 | } | |
159 | else | |
160 | { | |
161 | sslCipherPointer = options->ciphers; | |
162 | while (sslCipherPointer->next != 0) | |
163 | sslCipherPointer = sslCipherPointer->next; | |
164 | sslCipherPointer->next = malloc(sizeof(struct sslCipher)); | |
165 | sslCipherPointer = sslCipherPointer->next; | |
166 | } | |
167 | ||
168 | // Init | |
169 | memset(sslCipherPointer, 0, sizeof(struct sslCipher)); | |
170 | ||
171 | // Add cipher information... | |
172 | sslCipherPointer->sslMethod = sslMethod; | |
173 | sslCipherPointer->name = SSL_CIPHER_get_name(sk_SSL_CIPHER_value(cipherList, loop)); | |
174 | sslCipherPointer->version = SSL_CIPHER_get_version(sk_SSL_CIPHER_value(cipherList, loop)); | |
175 | SSL_CIPHER_description(sk_SSL_CIPHER_value(cipherList, loop), sslCipherPointer->description, sizeof(sslCipherPointer->description) - 1); | |
176 | sslCipherPointer->bits = SSL_CIPHER_get_bits(sk_SSL_CIPHER_value(cipherList, loop), &tempInt); | |
177 | } | |
178 | ||
179 | // Free SSL object | |
180 | SSL_free(ssl); | |
181 | } | |
182 | else | |
183 | { | |
184 | returnCode = false; | |
185 | printf("%sERROR: Could not create SSL object.%s\n", COL_RED, RESET); | |
186 | } | |
187 | ||
188 | // Free CTX Object | |
189 | SSL_CTX_free(options->ctx); | |
190 | } | |
191 | ||
192 | // Error Creating Context Object | |
193 | else | |
194 | { | |
195 | returnCode = false; | |
196 | printf("%sERROR: Could not create CTX object.%s\n", COL_RED, RESET); | |
197 | } | |
198 | ||
199 | return returnCode; | |
200 | } | |
201 | ||
202 | ||
203 | // File Exists | |
204 | int fileExists(char *fileName) | |
205 | { | |
206 | // Variables... | |
207 | struct stat fileStats; | |
208 | ||
209 | if (stat(fileName, &fileStats) == 0) | |
210 | return true; | |
211 | else | |
212 | return false; | |
213 | } | |
214 | ||
215 | ||
216 | // Read a line from the input... | |
217 | void readLine(FILE *input, char *lineFromFile, int maxSize) | |
218 | { | |
219 | // Variables... | |
220 | int stripPointer; | |
221 | ||
222 | // Read line from file... | |
223 | fgets(lineFromFile, maxSize, input); | |
224 | ||
225 | // Clear the end-of-line stuff... | |
226 | stripPointer = strlen(lineFromFile) -1; | |
227 | while ((lineFromFile[stripPointer] == '\r') || (lineFromFile[stripPointer] == '\n') || (lineFromFile[stripPointer] == ' ')) | |
228 | { | |
229 | lineFromFile[stripPointer] = 0; | |
230 | stripPointer--; | |
231 | } | |
232 | } | |
233 | ||
234 | ||
235 | // Create a TCP socket | |
236 | int tcpConnect(struct sslCheckOptions *options) | |
237 | { | |
238 | // Variables... | |
239 | int socketDescriptor; | |
240 | char buffer[BUFFERSIZE]; | |
241 | struct sockaddr_in localAddress; | |
242 | int status; | |
243 | ||
244 | // Create Socket | |
245 | socketDescriptor = socket(AF_INET, SOCK_STREAM, 0); | |
246 | if(socketDescriptor < 0) | |
247 | { | |
248 | printf("%s ERROR: Could not open a socket.%s\n", COL_RED, RESET); | |
249 | return 0; | |
250 | } | |
251 | ||
252 | // Configure Local Port | |
253 | localAddress.sin_family = AF_INET; | |
254 | localAddress.sin_addr.s_addr = htonl(INADDR_ANY); | |
255 | localAddress.sin_port = htons(0); | |
256 | status = bind(socketDescriptor, (struct sockaddr *) &localAddress, sizeof(localAddress)); | |
257 | if(status < 0) | |
258 | { | |
259 | printf("%s ERROR: Could not bind to port.%s\n", COL_RED, RESET); | |
260 | return 0; | |
261 | } | |
262 | ||
263 | // Connect | |
264 | status = connect(socketDescriptor, (struct sockaddr *) &options->serverAddress, sizeof(options->serverAddress)); | |
265 | if(status < 0) | |
266 | { | |
267 | printf("%s ERROR: Could not open a connection to host %s on port %d.%s\n", COL_RED, options->host, options->port, RESET); | |
268 | return 0; | |
269 | } | |
270 | ||
271 | // If STARTTLS is required... | |
272 | if (options->starttls == true) | |
273 | { | |
274 | memset(buffer, 0, BUFFERSIZE); | |
275 | recv(socketDescriptor, buffer, BUFFERSIZE - 1, 0); | |
276 | if (strncmp(buffer, "220", 3) != 0) | |
277 | { | |
278 | close(socketDescriptor); | |
279 | printf("%s ERROR: The host %s on port %d did not appear to be an SMTP service.%s\n", COL_RED, options->host, options->port, RESET); | |
280 | return 0; | |
281 | } | |
282 | send(socketDescriptor, "EHLO titania.co.uk\r\n", 20, 0); | |
283 | memset(buffer, 0, BUFFERSIZE); | |
284 | recv(socketDescriptor, buffer, BUFFERSIZE - 1, 0); | |
285 | if (strncmp(buffer, "250", 3) != 0) | |
286 | { | |
287 | close(socketDescriptor); | |
288 | printf("%s ERROR: The SMTP service on %s port %d did not respond with status 250 to our HELO.%s\n", COL_RED, options->host, options->port, RESET); | |
289 | return 0; | |
290 | } | |
291 | send(socketDescriptor, "STARTTLS\r\n", 10, 0); | |
292 | memset(buffer, 0, BUFFERSIZE); | |
293 | recv(socketDescriptor, buffer, BUFFERSIZE - 1, 0); | |
294 | if (strncmp(buffer, "220", 3) != 0) | |
295 | { | |
296 | close(socketDescriptor); | |
297 | printf("%s ERROR: The SMTP service on %s port %d did not appear to support STARTTLS.%s\n", COL_RED, options->host, options->port, RESET); | |
298 | return 0; | |
299 | } | |
300 | } | |
301 | ||
302 | // Return | |
303 | return socketDescriptor; | |
304 | } | |
305 | ||
306 | ||
307 | // Private Key Password Callback... | |
308 | static int password_callback(char *buf, int size, int rwflag, void *userdata) | |
309 | { | |
310 | strncpy(buf, (char *)userdata, size); | |
311 | buf[strlen(userdata)] = 0; | |
312 | return strlen(userdata); | |
313 | } | |
314 | ||
315 | ||
316 | // Load client certificates/private keys... | |
317 | int loadCerts(struct sslCheckOptions *options) | |
318 | { | |
319 | // Variables... | |
320 | int status = 1; | |
321 | PKCS12 *pk12 = NULL; | |
322 | FILE *pk12File = NULL; | |
323 | X509 *cert = NULL; | |
324 | EVP_PKEY *pkey = NULL; | |
325 | STACK_OF(X509) *ca = NULL; | |
326 | ||
327 | // Configure PKey password... | |
328 | if (options->privateKeyPassword != 0) | |
329 | { | |
330 | SSL_CTX_set_default_passwd_cb_userdata(options->ctx, (void *)options->privateKeyPassword); | |
331 | SSL_CTX_set_default_passwd_cb(options->ctx, password_callback); | |
332 | } | |
333 | ||
334 | // Seperate Certs and PKey Files... | |
335 | if ((options->clientCertsFile != 0) && (options->privateKeyFile != 0)) | |
336 | { | |
337 | // Load Cert... | |
338 | if (!SSL_CTX_use_certificate_file(options->ctx, options->clientCertsFile, SSL_FILETYPE_PEM)) | |
339 | { | |
340 | if (!SSL_CTX_use_certificate_file(options->ctx, options->clientCertsFile, SSL_FILETYPE_ASN1)) | |
341 | { | |
342 | if (!SSL_CTX_use_certificate_chain_file(options->ctx, options->clientCertsFile)) | |
343 | { | |
344 | printf("%s Could not configure certificate(s).%s\n", COL_RED, RESET); | |
345 | status = 0; | |
346 | } | |
347 | } | |
348 | } | |
349 | ||
350 | // Load PKey... | |
351 | if (status != 0) | |
352 | { | |
353 | if (!SSL_CTX_use_PrivateKey_file(options->ctx, options->privateKeyFile, SSL_FILETYPE_PEM)) | |
354 | { | |
355 | if (!SSL_CTX_use_PrivateKey_file(options->ctx, options->privateKeyFile, SSL_FILETYPE_ASN1)) | |
356 | { | |
357 | if (!SSL_CTX_use_RSAPrivateKey_file(options->ctx, options->privateKeyFile, SSL_FILETYPE_PEM)) | |
358 | { | |
359 | if (!SSL_CTX_use_RSAPrivateKey_file(options->ctx, options->privateKeyFile, SSL_FILETYPE_ASN1)) | |
360 | { | |
361 | printf("%s Could not configure private key.%s\n", COL_RED, RESET); | |
362 | status = 0; | |
363 | } | |
364 | } | |
365 | } | |
366 | } | |
367 | } | |
368 | } | |
369 | ||
370 | // PKCS Cert and PKey File... | |
371 | else if (options->privateKeyFile != 0) | |
372 | { | |
373 | pk12File = fopen(options->privateKeyFile, "rb"); | |
374 | if (pk12File != NULL) | |
375 | { | |
376 | pk12 = d2i_PKCS12_fp(pk12File, NULL); | |
377 | if (!pk12) | |
378 | { | |
379 | status = 0; | |
380 | printf("%s Could not read PKCS#12 file.%s\n", COL_RED, RESET); | |
381 | } | |
382 | else | |
383 | { | |
384 | if (!PKCS12_parse(pk12, options->privateKeyPassword, &pkey, &cert, &ca)) | |
385 | { | |
386 | status = 0; | |
387 | printf("%s Error parsing PKCS#12. Are you sure that password was correct?%s\n", COL_RED, RESET); | |
388 | } | |
389 | else | |
390 | { | |
391 | if (!SSL_CTX_use_certificate(options->ctx, cert)) | |
392 | { | |
393 | status = 0; | |
394 | printf("%s Could not configure certificate.%s\n", COL_RED, RESET); | |
395 | } | |
396 | if (!SSL_CTX_use_PrivateKey(options->ctx, pkey)) | |
397 | { | |
398 | status = 0; | |
399 | printf("%s Could not configure private key.%s\n", COL_RED, RESET); | |
400 | } | |
401 | } | |
402 | PKCS12_free(pk12); | |
403 | } | |
404 | fclose(pk12File); | |
405 | } | |
406 | else | |
407 | { | |
408 | printf("%s Could not open PKCS#12 file.%s\n", COL_RED, RESET); | |
409 | status = 0; | |
410 | } | |
411 | } | |
412 | ||
413 | // Check Cert/Key... | |
414 | if (status != 0) | |
415 | { | |
416 | if (!SSL_CTX_check_private_key(options->ctx)) | |
417 | { | |
418 | printf("%s Prvate key does not match certificate.%s\n", COL_RED, RESET); | |
419 | return false; | |
420 | } | |
421 | else | |
422 | return true; | |
423 | } | |
424 | else | |
425 | return false; | |
426 | } | |
427 | ||
428 | ||
429 | // Test a cipher... | |
430 | int testCipher(struct sslCheckOptions *options, struct sslCipher *sslCipherPointer) | |
431 | { | |
432 | // Variables... | |
433 | int cipherStatus; | |
434 | int status = true; | |
435 | int socketDescriptor = 0; | |
436 | SSL *ssl = NULL; | |
437 | BIO *cipherConnectionBio; | |
438 | BIO *stdoutBIO = NULL; | |
439 | int tempInt; | |
440 | char requestBuffer[200]; | |
441 | char buffer[50]; | |
442 | int resultSize = 0; | |
443 | ||
444 | // Create request buffer... | |
445 | memset(requestBuffer, 0, 200); | |
446 | snprintf(requestBuffer, 199, "GET / HTTP/1.0\r\nUser-Agent: SSLScan\r\nHost: %s\r\n\r\n", options->host); | |
447 | ||
448 | // Connect to host | |
449 | socketDescriptor = tcpConnect(options); | |
450 | if (socketDescriptor != 0) | |
451 | { | |
452 | if (SSL_CTX_set_cipher_list(options->ctx, sslCipherPointer->name) != 0) | |
453 | { | |
454 | ||
455 | // Create SSL object... | |
456 | ssl = SSL_new(options->ctx); | |
457 | if (ssl != NULL) | |
458 | { | |
459 | // Connect socket and BIO | |
460 | cipherConnectionBio = BIO_new_socket(socketDescriptor, BIO_NOCLOSE); | |
461 | ||
462 | // Connect SSL and BIO | |
463 | SSL_set_bio(ssl, cipherConnectionBio, cipherConnectionBio); | |
464 | ||
465 | // Connect SSL over socket | |
466 | cipherStatus = SSL_connect(ssl); | |
467 | ||
468 | // Show Cipher Status | |
469 | if (!((options->noFailed == true) && (cipherStatus != 1))) | |
470 | { | |
471 | if (options->xmlOutput != 0) | |
472 | fprintf(options->xmlOutput, " <cipher status=\""); | |
473 | if (cipherStatus == 1) | |
474 | { | |
475 | if (options->xmlOutput != 0) | |
476 | fprintf(options->xmlOutput, "accepted\""); | |
477 | if (options->pout == true) | |
478 | printf("|| Accepted || "); | |
479 | else | |
480 | printf(" Accepted "); | |
481 | if (options->http == true) | |
482 | { | |
483 | ||
484 | // Stdout BIO... | |
485 | stdoutBIO = BIO_new(BIO_s_file()); | |
486 | BIO_set_fp(stdoutBIO, stdout, BIO_NOCLOSE); | |
487 | ||
488 | // HTTP Get... | |
489 | SSL_write(ssl, requestBuffer, sizeof(requestBuffer)); | |
490 | memset(buffer ,0 , 50); | |
491 | resultSize = SSL_read(ssl, buffer, 49); | |
492 | if (resultSize > 9) | |
493 | { | |
494 | int loop = 0; | |
495 | for (loop = 9; (loop < 49) && (buffer[loop] != 0) && (buffer[loop] != '\r') && (buffer[loop] != '\n'); loop++) | |
496 | { } | |
497 | buffer[loop] = 0; | |
498 | ||
499 | // Output HTTP code... | |
500 | if (options->pout == true) | |
501 | printf("%s || ", buffer + 9); | |
502 | else | |
503 | { | |
504 | printf("%s", buffer + 9); | |
505 | loop = strlen(buffer + 9); | |
506 | while (loop < 17) | |
507 | { | |
508 | loop++; | |
509 | printf(" "); | |
510 | } | |
511 | } | |
512 | if (options->xmlOutput != 0) | |
513 | fprintf(options->xmlOutput, " http=\"%s\"", buffer + 9); | |
514 | } | |
515 | else | |
516 | { | |
517 | // Output HTTP code... | |
518 | if (options->pout == true) | |
519 | printf("|| || "); | |
520 | else | |
521 | printf(" "); | |
522 | } | |
523 | } | |
524 | } | |
525 | else if (cipherStatus == 0) | |
526 | { | |
527 | if (options->xmlOutput != 0) | |
528 | fprintf(options->xmlOutput, "rejected\""); | |
529 | if (options->http == true) | |
530 | { | |
531 | if (options->pout == true) | |
532 | printf("|| Rejected || N/A || "); | |
533 | else | |
534 | printf(" Rejected N/A "); | |
535 | } | |
536 | else | |
537 | { | |
538 | if (options->pout == true) | |
539 | printf("|| Rejected || "); | |
540 | else | |
541 | printf(" Rejected "); | |
542 | } | |
543 | } | |
544 | else | |
545 | { | |
546 | if (options->xmlOutput != 0) | |
547 | fprintf(options->xmlOutput, "failed\""); | |
548 | if (options->http == true) | |
549 | { | |
550 | if (options->pout == true) | |
551 | printf("|| Failed || N/A || "); | |
552 | else | |
553 | printf(" Failed N/A "); | |
554 | } | |
555 | else | |
556 | { | |
557 | if (options->pout == true) | |
558 | printf("|| Failed || "); | |
559 | else | |
560 | printf(" Failed "); | |
561 | } | |
562 | } | |
563 | if (options->xmlOutput != 0) | |
564 | fprintf(options->xmlOutput, " sslversion=\""); | |
565 | if (sslCipherPointer->sslMethod == SSLv2_client_method()) | |
566 | { | |
567 | if (options->xmlOutput != 0) | |
568 | fprintf(options->xmlOutput, "SSLv2\" bits=\""); | |
569 | if (options->pout == true) | |
570 | printf("SSLv2 || "); | |
571 | else | |
572 | printf("SSLv2 "); | |
573 | } | |
574 | else if (sslCipherPointer->sslMethod == SSLv3_client_method()) | |
575 | { | |
576 | if (options->xmlOutput != 0) | |
577 | fprintf(options->xmlOutput, "SSLv3\" bits=\""); | |
578 | if (options->pout == true) | |
579 | printf("SSLv3 || "); | |
580 | else | |
581 | printf("SSLv3 "); | |
582 | } | |
583 | else | |
584 | { | |
585 | if (options->xmlOutput != 0) | |
586 | fprintf(options->xmlOutput, "TLSv1\" bits=\""); | |
587 | if (options->pout == true) | |
588 | printf("TLSv1 || "); | |
589 | else | |
590 | printf("TLSv1 "); | |
591 | } | |
592 | if (sslCipherPointer->bits < 10) | |
593 | tempInt = 2; | |
594 | else if (sslCipherPointer->bits < 100) | |
595 | tempInt = 1; | |
596 | else | |
597 | tempInt = 0; | |
598 | if (options->pout == true) | |
599 | printf("%d || ", sslCipherPointer->bits); | |
600 | else | |
601 | printf("%d bits ", sslCipherPointer->bits); | |
602 | while (tempInt != 0) | |
603 | { | |
604 | tempInt--; | |
605 | printf(" "); | |
606 | } | |
607 | if (options->xmlOutput != 0) | |
608 | fprintf(options->xmlOutput, "%d\" cipher=\"%s\" />\n", sslCipherPointer->bits, sslCipherPointer->name); | |
609 | if (options->pout == true) | |
610 | printf("%s ||\n", sslCipherPointer->name); | |
611 | else | |
612 | printf("%s\n", sslCipherPointer->name); | |
613 | } | |
614 | ||
615 | // Disconnect SSL over socket | |
616 | if (cipherStatus == 1) | |
617 | SSL_shutdown(ssl); | |
618 | ||
619 | // Free SSL object | |
620 | SSL_free(ssl); | |
621 | } | |
622 | else | |
623 | { | |
624 | status = false; | |
625 | printf("%s ERROR: Could create SSL object.%s\n", COL_RED, RESET); | |
626 | } | |
627 | } | |
628 | else | |
629 | { | |
630 | status = false; | |
631 | printf("%s ERROR: Could set cipher %s.%s\n", COL_RED, sslCipherPointer->name, RESET); | |
632 | } | |
633 | ||
634 | // Disconnect from host | |
635 | close(socketDescriptor); | |
636 | } | |
637 | ||
638 | // Could not connect | |
639 | else | |
640 | status = false; | |
641 | ||
642 | return status; | |
643 | } | |
644 | ||
645 | ||
646 | // Test for prefered ciphers | |
647 | int defaultCipher(struct sslCheckOptions *options, SSL_METHOD *sslMethod) | |
648 | { | |
649 | // Variables... | |
650 | int cipherStatus; | |
651 | int status = true; | |
652 | int socketDescriptor = 0; | |
653 | SSL *ssl = NULL; | |
654 | BIO *cipherConnectionBio; | |
655 | int tempInt; | |
656 | int tempInt2; | |
657 | ||
658 | // Connect to host | |
659 | socketDescriptor = tcpConnect(options); | |
660 | if (socketDescriptor != 0) | |
661 | { | |
662 | ||
663 | // Setup Context Object... | |
664 | options->ctx = SSL_CTX_new(sslMethod); | |
665 | if (options->ctx != NULL) | |
666 | { | |
667 | if (SSL_CTX_set_cipher_list(options->ctx, "ALL:COMPLEMENTOFALL") != 0) | |
668 | { | |
669 | ||
670 | // Load Certs if required... | |
671 | if ((options->clientCertsFile != 0) || (options->privateKeyFile != 0)) | |
672 | status = loadCerts(options); | |
673 | ||
674 | if (status == true) | |
675 | { | |
676 | // Create SSL object... | |
677 | ssl = SSL_new(options->ctx); | |
678 | if (ssl != NULL) | |
679 | { | |
680 | // Connect socket and BIO | |
681 | cipherConnectionBio = BIO_new_socket(socketDescriptor, BIO_NOCLOSE); | |
682 | ||
683 | // Connect SSL and BIO | |
684 | SSL_set_bio(ssl, cipherConnectionBio, cipherConnectionBio); | |
685 | ||
686 | // Connect SSL over socket | |
687 | cipherStatus = SSL_connect(ssl); | |
688 | if (cipherStatus == 1) | |
689 | { | |
690 | if (sslMethod == SSLv2_client_method()) | |
691 | { | |
692 | if (options->xmlOutput != 0) | |
693 | fprintf(options->xmlOutput, " <defaultcipher sslversion=\"SSLv2\" bits=\""); | |
694 | if (options->pout == true) | |
695 | printf("|| SSLv2 || "); | |
696 | else | |
697 | printf(" SSLv2 "); | |
698 | } | |
699 | else if (sslMethod == SSLv3_client_method()) | |
700 | { | |
701 | if (options->xmlOutput != 0) | |
702 | fprintf(options->xmlOutput, " <defaultcipher sslversion=\"SSLv3\" bits=\""); | |
703 | if (options->pout == true) | |
704 | printf("|| SSLv3 || "); | |
705 | else | |
706 | printf(" SSLv3 "); | |
707 | } | |
708 | else | |
709 | { | |
710 | if (options->xmlOutput != 0) | |
711 | fprintf(options->xmlOutput, " <defaultcipher sslversion=\"TLSv1\" bits=\""); | |
712 | if (options->pout == true) | |
713 | printf("|| TLSv1 || "); | |
714 | else | |
715 | printf(" TLSv1 "); | |
716 | } | |
717 | if (SSL_get_cipher_bits(ssl, &tempInt2) < 10) | |
718 | tempInt = 2; | |
719 | else if (SSL_get_cipher_bits(ssl, &tempInt2) < 100) | |
720 | tempInt = 1; | |
721 | else | |
722 | tempInt = 0; | |
723 | if (options->pout == true) | |
724 | printf("%d bits || ", SSL_get_cipher_bits(ssl, &tempInt2)); | |
725 | else | |
726 | printf("%d bits ", SSL_get_cipher_bits(ssl, &tempInt2)); | |
727 | while (tempInt != 0) | |
728 | { | |
729 | tempInt--; | |
730 | printf(" "); | |
731 | } | |
732 | if (options->xmlOutput != 0) | |
733 | fprintf(options->xmlOutput, "%d\" cipher=\"%s\" />\n", SSL_get_cipher_bits(ssl, &tempInt2), SSL_get_cipher_name(ssl)); | |
734 | if (options->pout == true) | |
735 | printf("%s ||\n", SSL_get_cipher_name(ssl)); | |
736 | else | |
737 | printf("%s\n", SSL_get_cipher_name(ssl)); | |
738 | ||
739 | // Disconnect SSL over socket | |
740 | SSL_shutdown(ssl); | |
741 | } | |
742 | ||
743 | // Free SSL object | |
744 | SSL_free(ssl); | |
745 | } | |
746 | else | |
747 | { | |
748 | status = false; | |
749 | printf("%s ERROR: Could create SSL object.%s\n", COL_RED, RESET); | |
750 | } | |
751 | } | |
752 | } | |
753 | else | |
754 | { | |
755 | status = false; | |
756 | printf("%s ERROR: Could set cipher.%s\n", COL_RED, RESET); | |
757 | } | |
758 | ||
759 | // Free CTX Object | |
760 | SSL_CTX_free(options->ctx); | |
761 | } | |
762 | ||
763 | // Error Creating Context Object | |
764 | else | |
765 | { | |
766 | status = false; | |
767 | printf("%sERROR: Could not create CTX object.%s\n", COL_RED, RESET); | |
768 | } | |
769 | ||
770 | // Disconnect from host | |
771 | close(socketDescriptor); | |
772 | } | |
773 | ||
774 | // Could not connect | |
775 | else | |
776 | status = false; | |
777 | ||
778 | return status; | |
779 | } | |
780 | ||
781 | ||
782 | // Get certificate... | |
783 | int getCertificate(struct sslCheckOptions *options) | |
784 | { | |
785 | // Variables... | |
786 | int cipherStatus = 0; | |
787 | int status = true; | |
788 | int socketDescriptor = 0; | |
789 | SSL *ssl = NULL; | |
790 | BIO *cipherConnectionBio = NULL; | |
791 | BIO *stdoutBIO = NULL; | |
792 | BIO *fileBIO = NULL; | |
793 | X509 *x509Cert = NULL; | |
794 | EVP_PKEY *publicKey = NULL; | |
795 | SSL_METHOD *sslMethod = NULL; | |
796 | ASN1_OBJECT *asn1Object = NULL; | |
797 | X509_EXTENSION *extension = NULL; | |
798 | char buffer[1024]; | |
799 | long tempLong = 0; | |
800 | int tempInt = 0; | |
801 | int tempInt2 = 0; | |
802 | long verifyError = 0; | |
803 | ||
804 | // Connect to host | |
805 | socketDescriptor = tcpConnect(options); | |
806 | if (socketDescriptor != 0) | |
807 | { | |
808 | ||
809 | // Setup Context Object... | |
810 | sslMethod = SSLv23_method(); | |
811 | options->ctx = SSL_CTX_new(sslMethod); | |
812 | if (options->ctx != NULL) | |
813 | { | |
814 | ||
815 | if (SSL_CTX_set_cipher_list(options->ctx, "ALL:COMPLEMENTOFALL") != 0) | |
816 | { | |
817 | ||
818 | // Load Certs if required... | |
819 | if ((options->clientCertsFile != 0) || (options->privateKeyFile != 0)) | |
820 | status = loadCerts(options); | |
821 | ||
822 | if (status == true) | |
823 | { | |
824 | // Create SSL object... | |
825 | ssl = SSL_new(options->ctx); | |
826 | if (ssl != NULL) | |
827 | { | |
828 | ||
829 | // Connect socket and BIO | |
830 | cipherConnectionBio = BIO_new_socket(socketDescriptor, BIO_NOCLOSE); | |
831 | ||
832 | // Connect SSL and BIO | |
833 | SSL_set_bio(ssl, cipherConnectionBio, cipherConnectionBio); | |
834 | ||
835 | // Connect SSL over socket | |
836 | cipherStatus = SSL_connect(ssl); | |
837 | if (cipherStatus == 1) | |
838 | { | |
839 | ||
840 | // Setup BIO's | |
841 | stdoutBIO = BIO_new(BIO_s_file()); | |
842 | BIO_set_fp(stdoutBIO, stdout, BIO_NOCLOSE); | |
843 | if (options->xmlOutput != 0) | |
844 | { | |
845 | fileBIO = BIO_new(BIO_s_file()); | |
846 | BIO_set_fp(fileBIO, options->xmlOutput, BIO_NOCLOSE); | |
847 | } | |
848 | ||
849 | // Get Certificate... | |
850 | printf("\n %sSSL Certificate:%s\n", COL_BLUE, RESET); | |
851 | if (options->xmlOutput != 0) | |
852 | fprintf(options->xmlOutput, " <certificate>\n"); | |
853 | x509Cert = SSL_get_peer_certificate(ssl); | |
854 | if (x509Cert != NULL) | |
855 | { | |
856 | ||
857 | //SSL_set_verify(ssl, SSL_VERIFY_NONE|SSL_VERIFY_CLIENT_ONCE, NULL); | |
858 | ||
859 | // Cert Version | |
860 | if (!(X509_FLAG_COMPAT & X509_FLAG_NO_VERSION)) | |
861 | { | |
862 | tempLong = X509_get_version(x509Cert); | |
863 | printf(" Version: %lu\n", tempLong); | |
864 | if (options->xmlOutput != 0) | |
865 | fprintf(options->xmlOutput, " <version>%lu</version>\n", tempLong); | |
866 | } | |
867 | ||
868 | // Cert Serial No. | |
869 | if (!(X509_FLAG_COMPAT & X509_FLAG_NO_SERIAL)) | |
870 | { | |
871 | tempLong = ASN1_INTEGER_get(X509_get_serialNumber(x509Cert)); | |
872 | if (tempLong < 1) | |
873 | { | |
874 | printf(" Serial Number: -%lu\n", tempLong); | |
875 | if (options->xmlOutput != 0) | |
876 | fprintf(options->xmlOutput, " <serial>-%lu</serial>\n", tempLong); | |
877 | } | |
878 | else | |
879 | { | |
880 | printf(" Serial Number: %lu\n", tempLong); | |
881 | if (options->xmlOutput != 0) | |
882 | fprintf(options->xmlOutput, " <serial>%lu</serial>\n", tempLong); | |
883 | } | |
884 | } | |
885 | ||
886 | // Signature Algo... | |
887 | if (!(X509_FLAG_COMPAT & X509_FLAG_NO_SIGNAME)) | |
888 | { | |
889 | printf(" Signature Algorithm: "); | |
890 | i2a_ASN1_OBJECT(stdoutBIO, x509Cert->cert_info->signature->algorithm); | |
891 | printf("\n"); | |
892 | if (options->xmlOutput != 0) | |
893 | { | |
894 | fprintf(options->xmlOutput, " <signature-algorithm>"); | |
895 | i2a_ASN1_OBJECT(fileBIO, x509Cert->cert_info->signature->algorithm); | |
896 | fprintf(options->xmlOutput, "</signature-algorithm>\n"); | |
897 | } | |
898 | } | |
899 | ||
900 | // SSL Certificate Issuer... | |
901 | if (!(X509_FLAG_COMPAT & X509_FLAG_NO_ISSUER)) | |
902 | { | |
903 | X509_NAME_oneline(X509_get_issuer_name(x509Cert), buffer, sizeof(buffer) - 1); | |
904 | printf(" Issuer: %s\n", buffer); | |
905 | if (options->xmlOutput != 0) | |
906 | fprintf(options->xmlOutput, " <issuer>%s</issuer>\n", buffer); | |
907 | } | |
908 | ||
909 | // Validity... | |
910 | if (!(X509_FLAG_COMPAT & X509_FLAG_NO_VALIDITY)) | |
911 | { | |
912 | printf(" Not valid before: "); | |
913 | ASN1_TIME_print(stdoutBIO, X509_get_notBefore(x509Cert)); | |
914 | if (options->xmlOutput != 0) | |
915 | { | |
916 | fprintf(options->xmlOutput, " <not-valid-before>"); | |
917 | ASN1_TIME_print(fileBIO, X509_get_notBefore(x509Cert)); | |
918 | fprintf(options->xmlOutput, "</not-valid-before>\n"); | |
919 | } | |
920 | printf("\n Not valid after: "); | |
921 | ASN1_TIME_print(stdoutBIO, X509_get_notAfter(x509Cert)); | |
922 | printf("\n"); | |
923 | if (options->xmlOutput != 0) | |
924 | { | |
925 | fprintf(options->xmlOutput, " <not-valid-after>"); | |
926 | ASN1_TIME_print(fileBIO, X509_get_notAfter(x509Cert)); | |
927 | fprintf(options->xmlOutput, "</not-valid-after>\n"); | |
928 | } | |
929 | } | |
930 | ||
931 | // SSL Certificate Subject... | |
932 | if (!(X509_FLAG_COMPAT & X509_FLAG_NO_SUBJECT)) | |
933 | { | |
934 | X509_NAME_oneline(X509_get_subject_name(x509Cert), buffer, sizeof(buffer) - 1); | |
935 | printf(" Subject: %s\n", buffer); | |
936 | if (options->xmlOutput != 0) | |
937 | fprintf(options->xmlOutput, " <subject>%s</subject>\n", buffer); | |
938 | } | |
939 | ||
940 | // Public Key Algo... | |
941 | if (!(X509_FLAG_COMPAT & X509_FLAG_NO_PUBKEY)) | |
942 | { | |
943 | printf(" Public Key Algorithm: "); | |
944 | i2a_ASN1_OBJECT(stdoutBIO, x509Cert->cert_info->key->algor->algorithm); | |
945 | printf("\n"); | |
946 | if (options->xmlOutput != 0) | |
947 | { | |
948 | fprintf(options->xmlOutput, " <pk-algorithm>"); | |
949 | i2a_ASN1_OBJECT(fileBIO, x509Cert->cert_info->key->algor->algorithm); | |
950 | fprintf(options->xmlOutput, "</pk-algorithm>\n"); | |
951 | } | |
952 | ||
953 | // Public Key... | |
954 | publicKey = X509_get_pubkey(x509Cert); | |
955 | if (publicKey == NULL) | |
956 | { | |
957 | printf(" Public Key: Could not load\n"); | |
958 | if (options->xmlOutput != 0) | |
959 | fprintf(options->xmlOutput, " <pk error=\"true\" />\n"); | |
960 | } | |
961 | else | |
962 | { | |
963 | switch (publicKey->type) | |
964 | { | |
965 | case EVP_PKEY_RSA: | |
966 | printf(" RSA Public Key: (%d bit)\n", BN_num_bits(publicKey->pkey.rsa->n)); | |
967 | if (options->xmlOutput != 0) | |
968 | fprintf(options->xmlOutput, " <pk error=\"false\" type=\"RSA\" bits=\"%d\">\n", BN_num_bits(publicKey->pkey.rsa->n)); | |
969 | RSA_print(stdoutBIO, publicKey->pkey.rsa, 6); | |
970 | if (options->xmlOutput != 0) | |
971 | { | |
972 | RSA_print(fileBIO, publicKey->pkey.rsa, 4); | |
973 | fprintf(options->xmlOutput, " </pk>\n"); | |
974 | } | |
975 | break; | |
976 | case EVP_PKEY_DSA: | |
977 | printf(" DSA Public Key:\n"); | |
978 | if (options->xmlOutput != 0) | |
979 | fprintf(options->xmlOutput, " <pk error=\"false\" type=\"DSA\">\n"); | |
980 | DSA_print(stdoutBIO, publicKey->pkey.dsa, 6); | |
981 | if (options->xmlOutput != 0) | |
982 | { | |
983 | DSA_print(fileBIO, publicKey->pkey.dsa, 4); | |
984 | fprintf(options->xmlOutput, " </pk>\n"); | |
985 | } | |
986 | break; | |
987 | case EVP_PKEY_EC: | |
988 | printf(" EC Public Key:\n"); | |
989 | if (options->xmlOutput != 0) | |
990 | fprintf(options->xmlOutput, " <pk error=\"false\" type=\"EC\">\n"); | |
991 | EC_KEY_print(stdoutBIO, publicKey->pkey.ec, 6); | |
992 | if (options->xmlOutput != 0) | |
993 | { | |
994 | EC_KEY_print(fileBIO, publicKey->pkey.ec, 4); | |
995 | fprintf(options->xmlOutput, " </pk>\n"); | |
996 | } | |
997 | break; | |
998 | default: | |
999 | printf(" Public Key: Unknown\n"); | |
1000 | if (options->xmlOutput != 0) | |
1001 | fprintf(options->xmlOutput, " <pk error=\"true\" type=\"unknown\" />\n"); | |
1002 | break; | |
1003 | } | |
1004 | ||
1005 | EVP_PKEY_free(publicKey); | |
1006 | } | |
1007 | } | |
1008 | ||
1009 | // X509 v3... | |
1010 | if (!(X509_FLAG_COMPAT & X509_FLAG_NO_EXTENSIONS)) | |
1011 | { | |
1012 | if (sk_X509_EXTENSION_num(x509Cert->cert_info->extensions) > 0) | |
1013 | { | |
1014 | printf(" X509v3 Extensions:\n"); | |
1015 | if (options->xmlOutput != 0) | |
1016 | fprintf(options->xmlOutput, " <X509v3-Extensions>\n"); | |
1017 | for (tempInt = 0; tempInt < sk_X509_EXTENSION_num(x509Cert->cert_info->extensions); tempInt++) | |
1018 | { | |
1019 | // Get Extension... | |
1020 | extension = sk_X509_EXTENSION_value(x509Cert->cert_info->extensions, tempInt); | |
1021 | ||
1022 | // Print Extension name... | |
1023 | printf(" "); | |
1024 | asn1Object = X509_EXTENSION_get_object(extension); | |
1025 | i2a_ASN1_OBJECT(stdoutBIO, asn1Object); | |
1026 | tempInt2 = X509_EXTENSION_get_critical(extension); | |
1027 | BIO_printf(stdoutBIO, ": %s\n", tempInt2 ? "critical" : ""); | |
1028 | if (options->xmlOutput != 0) | |
1029 | { | |
1030 | fprintf(options->xmlOutput, " <extension name=\""); | |
1031 | i2a_ASN1_OBJECT(fileBIO, asn1Object); | |
1032 | BIO_printf(fileBIO, "\"%s>", tempInt2 ? " level=\"critical\"" : ""); | |
1033 | } | |
1034 | ||
1035 | // Print Extension value... | |
1036 | if (!X509V3_EXT_print(stdoutBIO, extension, X509_FLAG_COMPAT, 8)) | |
1037 | { | |
1038 | printf(" "); | |
1039 | M_ASN1_OCTET_STRING_print(stdoutBIO, extension->value); | |
1040 | } | |
1041 | if (options->xmlOutput != 0) | |
1042 | { | |
1043 | if (!X509V3_EXT_print(fileBIO, extension, X509_FLAG_COMPAT, 0)) | |
1044 | M_ASN1_OCTET_STRING_print(fileBIO, extension->value); | |
1045 | fprintf(options->xmlOutput, "</extension>\n"); | |
1046 | } | |
1047 | printf("\n"); | |
1048 | } | |
1049 | if (options->xmlOutput != 0) | |
1050 | fprintf(options->xmlOutput, " </X509v3-Extensions>\n"); | |
1051 | } | |
1052 | } | |
1053 | ||
1054 | // Verify Certificate... | |
1055 | printf(" Verify Certificate:\n"); | |
1056 | verifyError = SSL_get_verify_result(ssl); | |
1057 | if (verifyError == X509_V_OK) | |
1058 | printf(" Certificate passed verification\n"); | |
1059 | else | |
1060 | printf(" %s\n", X509_verify_cert_error_string(verifyError)); | |
1061 | ||
1062 | // Free X509 Certificate... | |
1063 | X509_free(x509Cert); | |
1064 | } | |
1065 | ||
1066 | if (options->xmlOutput != 0) | |
1067 | fprintf(options->xmlOutput, " </certificate>\n"); | |
1068 | ||
1069 | // Free BIO | |
1070 | BIO_free(stdoutBIO); | |
1071 | if (options->xmlOutput != 0) | |
1072 | BIO_free(fileBIO); | |
1073 | ||
1074 | // Disconnect SSL over socket | |
1075 | SSL_shutdown(ssl); | |
1076 | } | |
1077 | ||
1078 | // Free SSL object | |
1079 | SSL_free(ssl); | |
1080 | } | |
1081 | else | |
1082 | { | |
1083 | status = false; | |
1084 | printf("%s ERROR: Could create SSL object.%s\n", COL_RED, RESET); | |
1085 | } | |
1086 | } | |
1087 | } | |
1088 | else | |
1089 | { | |
1090 | status = false; | |
1091 | printf("%s ERROR: Could set cipher.%s\n", COL_RED, RESET); | |
1092 | } | |
1093 | ||
1094 | // Free CTX Object | |
1095 | SSL_CTX_free(options->ctx); | |
1096 | } | |
1097 | ||
1098 | // Error Creating Context Object | |
1099 | else | |
1100 | { | |
1101 | status = false; | |
1102 | printf("%sERROR: Could not create CTX object.%s\n", COL_RED, RESET); | |
1103 | } | |
1104 | ||
1105 | // Disconnect from host | |
1106 | close(socketDescriptor); | |
1107 | } | |
1108 | ||
1109 | // Could not connect | |
1110 | else | |
1111 | status = false; | |
1112 | ||
1113 | return status; | |
1114 | } | |
1115 | ||
1116 | ||
1117 | // Test a single host and port for ciphers... | |
1118 | int testHost(struct sslCheckOptions *options) | |
1119 | { | |
1120 | // Variables... | |
1121 | struct sslCipher *sslCipherPointer; | |
1122 | int status = true; | |
1123 | ||
1124 | // Resolve Host Name | |
1125 | options->hostStruct = gethostbyname(options->host); | |
1126 | if (options->hostStruct == NULL) | |
1127 | { | |
1128 | printf("%sERROR: Could not resolve hostname %s.%s\n", COL_RED, options->host, RESET); | |
1129 | return false; | |
1130 | } | |
1131 | ||
1132 | // Configure Server Address and Port | |
1133 | options->serverAddress.sin_family = options->hostStruct->h_addrtype; | |
1134 | memcpy((char *) &options->serverAddress.sin_addr.s_addr, options->hostStruct->h_addr_list[0], options->hostStruct->h_length); | |
1135 | options->serverAddress.sin_port = htons(options->port); | |
1136 | ||
1137 | // XML Output... | |
1138 | if (options->xmlOutput != 0) | |
1139 | fprintf(options->xmlOutput, " <ssltest host=\"%s\" port=\"%d\">\n", options->host, options->port); | |
1140 | ||
1141 | // Test supported ciphers... | |
1142 | printf("\n%sTesting SSL server %s on port %d%s\n\n", COL_GREEN, options->host, options->port, RESET); | |
1143 | printf(" %sSupported Server Cipher(s):%s\n", COL_BLUE, RESET); | |
1144 | if ((options->http == true) && (options->pout == true)) | |
1145 | printf("|| Status || HTTP Code || Version || Bits || Cipher ||\n"); | |
1146 | else if (options->pout == true) | |
1147 | printf("|| Status || Version || Bits || Cipher ||\n"); | |
1148 | sslCipherPointer = options->ciphers; | |
1149 | while ((sslCipherPointer != 0) && (status == true)) | |
1150 | { | |
1151 | ||
1152 | // Setup Context Object... | |
1153 | options->ctx = SSL_CTX_new(sslCipherPointer->sslMethod); | |
1154 | if (options->ctx != NULL) | |
1155 | { | |
1156 | ||
1157 | // SSL implementation bugs/workaround | |
1158 | if (options->sslbugs) | |
1159 | SSL_CTX_set_options(options->ctx, SSL_OP_ALL | 0); | |
1160 | else | |
1161 | SSL_CTX_set_options(options->ctx, 0); | |
1162 | ||
1163 | // Load Certs if required... | |
1164 | if ((options->clientCertsFile != 0) || (options->privateKeyFile != 0)) | |
1165 | status = loadCerts(options); | |
1166 | ||
1167 | // Test | |
1168 | if (status == true) | |
1169 | status = testCipher(options, sslCipherPointer); | |
1170 | ||
1171 | // Free CTX Object | |
1172 | SSL_CTX_free(options->ctx); | |
1173 | } | |
1174 | ||
1175 | // Error Creating Context Object | |
1176 | else | |
1177 | { | |
1178 | status = false; | |
1179 | printf("%sERROR: Could not create CTX object.%s\n", COL_RED, RESET); | |
1180 | } | |
1181 | ||
1182 | sslCipherPointer = sslCipherPointer->next; | |
1183 | } | |
1184 | ||
1185 | if (status == true) | |
1186 | { | |
1187 | // Test prefered ciphers... | |
1188 | printf("\n %sPrefered Server Cipher(s):%s\n", COL_BLUE, RESET); | |
1189 | if (options->pout == true) | |
1190 | printf("|| Version || Bits || Cipher ||\n"); | |
1191 | switch (options->sslVersion) | |
1192 | { | |
1193 | case ssl_all: | |
1194 | status = defaultCipher(options, SSLv2_client_method()); | |
1195 | if (status != false) | |
1196 | status = defaultCipher(options, SSLv3_client_method()); | |
1197 | if (status != false) | |
1198 | status = defaultCipher(options, TLSv1_client_method()); | |
1199 | break; | |
1200 | case ssl_v2: | |
1201 | status = defaultCipher(options, SSLv2_client_method()); | |
1202 | break; | |
1203 | case ssl_v3: | |
1204 | status = defaultCipher(options, SSLv3_client_method()); | |
1205 | break; | |
1206 | case tls_v1: | |
1207 | status = defaultCipher(options, TLSv1_client_method()); | |
1208 | break; | |
1209 | } | |
1210 | } | |
1211 | ||
1212 | if (status == true) | |
1213 | { | |
1214 | status = getCertificate(options); | |
1215 | } | |
1216 | ||
1217 | // XML Output... | |
1218 | if (options->xmlOutput != 0) | |
1219 | fprintf(options->xmlOutput, " </ssltest>\n"); | |
1220 | ||
1221 | // Return status... | |
1222 | return status; | |
1223 | } | |
1224 | ||
1225 | ||
1226 | int main(int argc, char *argv[]) | |
1227 | { | |
1228 | // Variables... | |
1229 | struct sslCheckOptions options; | |
1230 | struct sslCipher *sslCipherPointer; | |
1231 | int status; | |
1232 | int argLoop; | |
1233 | int tempInt; | |
1234 | int maxSize; | |
1235 | int xmlArg; | |
1236 | int mode = mode_help; | |
1237 | FILE *targetsFile; | |
1238 | char line[1024]; | |
1239 | ||
1240 | // Init... | |
1241 | memset(&options, 0, sizeof(struct sslCheckOptions)); | |
1242 | options.port = 443; | |
1243 | xmlArg = 0; | |
1244 | strcpy(options.host, "127.0.0.1"); | |
1245 | options.noFailed = false; | |
1246 | options.starttls = false; | |
1247 | options.sslVersion = ssl_all; | |
1248 | options.pout = false; | |
1249 | SSL_library_init(); | |
1250 | ||
1251 | // Get program parameters | |
1252 | for (argLoop = 1; argLoop < argc; argLoop++) | |
1253 | { | |
1254 | // Help | |
1255 | if (strcmp("--help", argv[argLoop]) == 0) | |
1256 | mode = mode_help; | |
1257 | ||
1258 | // targets | |
1259 | else if ((strncmp("--targets=", argv[argLoop], 10) == 0) && (strlen(argv[argLoop]) > 10)) | |
1260 | { | |
1261 | mode = mode_multiple; | |
1262 | options.targets = argLoop; | |
1263 | } | |
1264 | ||
1265 | // Show only supported | |
1266 | else if (strcmp("--no-failed", argv[argLoop]) == 0) | |
1267 | options.noFailed = true; | |
1268 | ||
1269 | // Version | |
1270 | else if (strcmp("--version", argv[argLoop]) == 0) | |
1271 | mode = mode_version; | |
1272 | ||
1273 | // XML Output | |
1274 | else if (strncmp("--xml=", argv[argLoop], 6) == 0) | |
1275 | xmlArg = argLoop; | |
1276 | ||
1277 | // P Output | |
1278 | else if (strcmp("-p", argv[argLoop]) == 0) | |
1279 | options.pout = true; | |
1280 | ||
1281 | // Client Certificates | |
1282 | else if (strncmp("--certs=", argv[argLoop], 8) == 0) | |
1283 | options.clientCertsFile = argv[argLoop] +8; | |
1284 | ||
1285 | // Private Key File | |
1286 | else if (strncmp("--pk=", argv[argLoop], 5) == 0) | |
1287 | options.privateKeyFile = argv[argLoop] +5; | |
1288 | ||
1289 | // Private Key Password | |
1290 | else if (strncmp("--pkpass=", argv[argLoop], 9) == 0) | |
1291 | options.privateKeyPassword = argv[argLoop] +9; | |
1292 | ||
1293 | // StartTLS... | |
1294 | else if (strcmp("--starttls", argv[argLoop]) == 0) | |
1295 | { | |
1296 | options.sslVersion = tls_v1; | |
1297 | options.starttls = true; | |
1298 | } | |
1299 | ||
1300 | // SSL v2 only... | |
1301 | else if (strcmp("--ssl2", argv[argLoop]) == 0) | |
1302 | options.sslVersion = ssl_v2; | |
1303 | ||
1304 | // SSL v3 only... | |
1305 | else if (strcmp("--ssl3", argv[argLoop]) == 0) | |
1306 | options.sslVersion = ssl_v3; | |
1307 | ||
1308 | // TLS v1 only... | |
1309 | else if (strcmp("--tls1", argv[argLoop]) == 0) | |
1310 | options.sslVersion = tls_v1; | |
1311 | ||
1312 | // SSL Bugs... | |
1313 | else if (strcmp("--bugs", argv[argLoop]) == 0) | |
1314 | options.sslbugs = 1; | |
1315 | ||
1316 | // SSL HTTP Get... | |
1317 | else if (strcmp("--http", argv[argLoop]) == 0) | |
1318 | options.http = 1; | |
1319 | ||
1320 | // Host (maybe port too)... | |
1321 | else if (argLoop + 1 == argc) | |
1322 | { | |
1323 | mode = mode_single; | |
1324 | ||
1325 | // Get host... | |
1326 | tempInt = 0; | |
1327 | maxSize = strlen(argv[argLoop]); | |
1328 | while ((argv[argLoop][tempInt] != 0) && (argv[argLoop][tempInt] != ':')) | |
1329 | tempInt++; | |
1330 | argv[argLoop][tempInt] = 0; | |
1331 | strncpy(options.host, argv[argLoop], sizeof(options.host) -1); | |
1332 | ||
1333 | // Get port (if it exists)... | |
1334 | tempInt++; | |
1335 | if (tempInt < maxSize) | |
1336 | options.port = atoi(argv[argLoop] + tempInt); | |
1337 | } | |
1338 | ||
1339 | // Not too sure what the user is doing... | |
1340 | else | |
1341 | mode = mode_help; | |
1342 | } | |
1343 | ||
1344 | // Open XML file output... | |
1345 | if ((xmlArg > 0) && (mode != mode_help)) | |
1346 | { | |
1347 | options.xmlOutput = fopen(argv[xmlArg] + 6, "w"); | |
1348 | if (options.xmlOutput == NULL) | |
1349 | { | |
1350 | printf("%sERROR: Could not open XML output file %s.%s\n", COL_RED, argv[xmlArg] + 6, RESET); | |
1351 | exit(0); | |
1352 | } | |
1353 | ||
1354 | // Output file header... | |
1355 | fprintf(options.xmlOutput, "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<document title=\"SSLScan Results\" version=\"%s\" web=\"http://www.titania.co.uk\">\n", xml_version); | |
1356 | } | |
1357 | ||
1358 | switch (mode) | |
1359 | { | |
1360 | case mode_version: | |
1361 | printf("%s%s%s", COL_BLUE, program_version, RESET); | |
1362 | break; | |
1363 | ||
1364 | case mode_help: | |
1365 | // Program version banner... | |
1366 | printf("%s%s%s\n", COL_BLUE, program_banner, RESET); | |
1367 | printf("SSLScan is a fast SSL port scanner. SSLScan connects to SSL\n"); | |
1368 | printf("ports and determines what ciphers are supported, which are\n"); | |
1369 | printf("the servers prefered ciphers, which SSL protocols are\n"); | |
1370 | printf("supported and returns the SSL certificate. Client\n"); | |
1371 | printf("certificates / private key can be configured and output is\n"); | |
1372 | printf("to text / XML.\n\n"); | |
1373 | printf("%sCommand:%s\n", COL_BLUE, RESET); | |
1374 | printf(" %s%s [Options] [host:port | host]%s\n\n", COL_GREEN, argv[0], RESET); | |
1375 | printf("%sOptions:%s\n", COL_BLUE, RESET); | |
1376 | printf(" %s--targets=<file>%s A file containing a list of hosts to\n", COL_GREEN, RESET); | |
1377 | printf(" check. Hosts can be supplied with\n"); | |
1378 | printf(" ports (i.e. host:port).\n"); | |
1379 | printf(" %s--no-failed%s List only accepted ciphers (default\n", COL_GREEN, RESET); | |
1380 | printf(" is to listing all ciphers).\n"); | |
1381 | printf(" %s--ssl2%s Only check SSLv2 ciphers.\n", COL_GREEN, RESET); | |
1382 | printf(" %s--ssl3%s Only check SSLv3 ciphers.\n", COL_GREEN, RESET); | |
1383 | printf(" %s--tls1%s Only check TLSv1 ciphers.\n", COL_GREEN, RESET); | |
1384 | printf(" %s--pk=<file>%s A file containing the private key or\n", COL_GREEN, RESET); | |
1385 | printf(" a PKCS#12 file containing a private\n"); | |
1386 | printf(" key/certificate pair (as produced by\n"); | |
1387 | printf(" MSIE and Netscape).\n"); | |
1388 | printf(" %s--pkpass=<password>%s The password for the private key or\n", COL_GREEN, RESET); | |
1389 | printf(" PKCS#12 file.\n"); | |
1390 | printf(" %s--certs=<file>%s A file containing PEM/ASN1 formatted\n", COL_GREEN, RESET); | |
1391 | printf(" client certificates.\n"); | |
1392 | printf(" %s--starttls%s If a STARTTLS is required to kick an\n", COL_GREEN, RESET); | |
1393 | printf(" SMTP service into action.\n"); | |
1394 | printf(" %s--http%s Test a HTTP connection.\n", COL_GREEN, RESET); | |
1395 | printf(" %s--bugs%s Enable SSL implementation bug work-\n", COL_GREEN, RESET); | |
1396 | printf(" arounds.\n"); | |
1397 | printf(" %s--xml=<file>%s Output results to an XML file.\n", COL_GREEN, RESET); | |
1398 | printf(" %s--version%s Display the program version.\n", COL_GREEN, RESET); | |
1399 | printf(" %s--help%s Display the help text you are now\n", COL_GREEN, RESET); | |
1400 | printf(" reading.\n"); | |
1401 | printf("%sExample:%s\n", COL_BLUE, RESET); | |
1402 | printf(" %s%s 127.0.0.1%s\n\n", COL_GREEN, argv[0], RESET); | |
1403 | break; | |
1404 | ||
1405 | // Check a single host/port ciphers... | |
1406 | case mode_single: | |
1407 | case mode_multiple: | |
1408 | printf("%s%s%s", COL_BLUE, program_banner, RESET); | |
1409 | ||
1410 | SSLeay_add_all_algorithms(); | |
1411 | ERR_load_crypto_strings(); | |
1412 | ||
1413 | // Build a list of ciphers... | |
1414 | switch (options.sslVersion) | |
1415 | { | |
1416 | case ssl_all: | |
1417 | populateCipherList(&options, SSLv2_client_method()); | |
1418 | populateCipherList(&options, SSLv3_client_method()); | |
1419 | populateCipherList(&options, TLSv1_client_method()); | |
1420 | break; | |
1421 | case ssl_v2: | |
1422 | populateCipherList(&options, SSLv2_client_method()); | |
1423 | break; | |
1424 | case ssl_v3: | |
1425 | populateCipherList(&options, SSLv3_client_method()); | |
1426 | break; | |
1427 | case tls_v1: | |
1428 | populateCipherList(&options, TLSv1_client_method()); | |
1429 | break; | |
1430 | } | |
1431 | ||
1432 | // Do the testing... | |
1433 | if (mode == mode_single) | |
1434 | status = testHost(&options); | |
1435 | else | |
1436 | { | |
1437 | if (fileExists(argv[options.targets] + 10) == true) | |
1438 | { | |
1439 | // Open targets file... | |
1440 | targetsFile = fopen(argv[options.targets] + 10, "r"); | |
1441 | if (targetsFile == NULL) | |
1442 | printf("%sERROR: Could not open targets file %s.%s\n", COL_RED, argv[options.targets] + 10, RESET); | |
1443 | else | |
1444 | { | |
1445 | readLine(targetsFile, line, sizeof(line)); | |
1446 | while (feof(targetsFile) == 0) | |
1447 | { | |
1448 | if (strlen(line) != 0) | |
1449 | { | |
1450 | // Get host... | |
1451 | tempInt = 0; | |
1452 | while ((line[tempInt] != 0) && (line[tempInt] != ':')) | |
1453 | tempInt++; | |
1454 | line[tempInt] = 0; | |
1455 | strncpy(options.host, line, sizeof(options.host) -1); | |
1456 | ||
1457 | // Get port (if it exists)... | |
1458 | tempInt++; | |
1459 | if (strlen(line + tempInt) > 0) | |
1460 | options.port = atoi(line + tempInt); | |
1461 | ||
1462 | // Test the host... | |
1463 | status = testHost(&options); | |
1464 | } | |
1465 | readLine(targetsFile, line, sizeof(line)); | |
1466 | } | |
1467 | } | |
1468 | } | |
1469 | else | |
1470 | printf("%sERROR: Targets file %s does not exist.%s\n", COL_RED, argv[options.targets] + 10, RESET); | |
1471 | } | |
1472 | ||
1473 | // Free Structures | |
1474 | while (options.ciphers != 0) | |
1475 | { | |
1476 | sslCipherPointer = options.ciphers->next; | |
1477 | free(options.ciphers); | |
1478 | options.ciphers = sslCipherPointer; | |
1479 | } | |
1480 | break; | |
1481 | } | |
1482 | ||
1483 | // Close XML file, if required... | |
1484 | if ((xmlArg > 0) && (mode != mode_help)) | |
1485 | { | |
1486 | fprintf(options.xmlOutput, "</document>\n"); | |
1487 | fclose(options.xmlOutput); | |
1488 | } | |
1489 | ||
1490 | return 0; | |
1491 | } | |
1492 |