├── COPYING
├── INSTALL
├── Makefile.am
├── README
├── autogen.sh
├── build-static-gpg.sh
├── configure.ac
├── gluster-lic-info.in
├── gluster-lic-install.in
├── gluster-lic-register.in
├── gluster-lic-request.in
├── gluster-lic-setup.in
├── gluster-lic-sign.in
├── gluster-lic-uninstall.c
├── gluster-lic.sh.in
├── gluster-lic.spec.in
├── libevil.c
├── libevil.h
├── md5.c
├── md5.h
├── permits-create.sh.in
├── permits-install.sh.in
└── pubring.gpg
/COPYING:
--------------------------------------------------------------------------------
1 | GNU AFFERO GENERAL PUBLIC LICENSE
2 | Version 3, 19 November 2007
3 |
4 | Copyright (C) 2007 Free Software Foundation, Inc.
5 | Everyone is permitted to copy and distribute verbatim copies
6 | of this license document, but changing it is not allowed.
7 |
8 | Preamble
9 |
10 | The GNU Affero General Public License is a free, copyleft license for
11 | software and other kinds of works, specifically designed to ensure
12 | cooperation with the community in the case of network server software.
13 |
14 | The licenses for most software and other practical works are designed
15 | to take away your freedom to share and change the works. By contrast,
16 | our General Public Licenses are intended to guarantee your freedom to
17 | share and change all versions of a program--to make sure it remains free
18 | software for all its users.
19 |
20 | When we speak of free software, we are referring to freedom, not
21 | price. Our General Public Licenses are designed to make sure that you
22 | have the freedom to distribute copies of free software (and charge for
23 | them if you wish), that you receive source code or can get it if you
24 | want it, that you can change the software or use pieces of it in new
25 | free programs, and that you know you can do these things.
26 |
27 | Developers that use our General Public Licenses protect your rights
28 | with two steps: (1) assert copyright on the software, and (2) offer
29 | you this License which gives you legal permission to copy, distribute
30 | and/or modify the software.
31 |
32 | A secondary benefit of defending all users' freedom is that
33 | improvements made in alternate versions of the program, if they
34 | receive widespread use, become available for other developers to
35 | incorporate. Many developers of free software are heartened and
36 | encouraged by the resulting cooperation. However, in the case of
37 | software used on network servers, this result may fail to come about.
38 | The GNU General Public License permits making a modified version and
39 | letting the public access it on a server without ever releasing its
40 | source code to the public.
41 |
42 | The GNU Affero General Public License is designed specifically to
43 | ensure that, in such cases, the modified source code becomes available
44 | to the community. It requires the operator of a network server to
45 | provide the source code of the modified version running there to the
46 | users of that server. Therefore, public use of a modified version, on
47 | a publicly accessible server, gives the public access to the source
48 | code of the modified version.
49 |
50 | An older license, called the Affero General Public License and
51 | published by Affero, was designed to accomplish similar goals. This is
52 | a different license, not a version of the Affero GPL, but Affero has
53 | released a new version of the Affero GPL which permits relicensing under
54 | this license.
55 |
56 | The precise terms and conditions for copying, distribution and
57 | modification follow.
58 |
59 | TERMS AND CONDITIONS
60 |
61 | 0. Definitions.
62 |
63 | "This License" refers to version 3 of the GNU Affero General Public License.
64 |
65 | "Copyright" also means copyright-like laws that apply to other kinds of
66 | works, such as semiconductor masks.
67 |
68 | "The Program" refers to any copyrightable work licensed under this
69 | License. Each licensee is addressed as "you". "Licensees" and
70 | "recipients" may be individuals or organizations.
71 |
72 | To "modify" a work means to copy from or adapt all or part of the work
73 | in a fashion requiring copyright permission, other than the making of an
74 | exact copy. The resulting work is called a "modified version" of the
75 | earlier work or a work "based on" the earlier work.
76 |
77 | A "covered work" means either the unmodified Program or a work based
78 | on the Program.
79 |
80 | To "propagate" a work means to do anything with it that, without
81 | permission, would make you directly or secondarily liable for
82 | infringement under applicable copyright law, except executing it on a
83 | computer or modifying a private copy. Propagation includes copying,
84 | distribution (with or without modification), making available to the
85 | public, and in some countries other activities as well.
86 |
87 | To "convey" a work means any kind of propagation that enables other
88 | parties to make or receive copies. Mere interaction with a user through
89 | a computer network, with no transfer of a copy, is not conveying.
90 |
91 | An interactive user interface displays "Appropriate Legal Notices"
92 | to the extent that it includes a convenient and prominently visible
93 | feature that (1) displays an appropriate copyright notice, and (2)
94 | tells the user that there is no warranty for the work (except to the
95 | extent that warranties are provided), that licensees may convey the
96 | work under this License, and how to view a copy of this License. If
97 | the interface presents a list of user commands or options, such as a
98 | menu, a prominent item in the list meets this criterion.
99 |
100 | 1. Source Code.
101 |
102 | The "source code" for a work means the preferred form of the work
103 | for making modifications to it. "Object code" means any non-source
104 | form of a work.
105 |
106 | A "Standard Interface" means an interface that either is an official
107 | standard defined by a recognized standards body, or, in the case of
108 | interfaces specified for a particular programming language, one that
109 | is widely used among developers working in that language.
110 |
111 | The "System Libraries" of an executable work include anything, other
112 | than the work as a whole, that (a) is included in the normal form of
113 | packaging a Major Component, but which is not part of that Major
114 | Component, and (b) serves only to enable use of the work with that
115 | Major Component, or to implement a Standard Interface for which an
116 | implementation is available to the public in source code form. A
117 | "Major Component", in this context, means a major essential component
118 | (kernel, window system, and so on) of the specific operating system
119 | (if any) on which the executable work runs, or a compiler used to
120 | produce the work, or an object code interpreter used to run it.
121 |
122 | The "Corresponding Source" for a work in object code form means all
123 | the source code needed to generate, install, and (for an executable
124 | work) run the object code and to modify the work, including scripts to
125 | control those activities. However, it does not include the work's
126 | System Libraries, or general-purpose tools or generally available free
127 | programs which are used unmodified in performing those activities but
128 | which are not part of the work. For example, Corresponding Source
129 | includes interface definition files associated with source files for
130 | the work, and the source code for shared libraries and dynamically
131 | linked subprograms that the work is specifically designed to require,
132 | such as by intimate data communication or control flow between those
133 | subprograms and other parts of the work.
134 |
135 | The Corresponding Source need not include anything that users
136 | can regenerate automatically from other parts of the Corresponding
137 | Source.
138 |
139 | The Corresponding Source for a work in source code form is that
140 | same work.
141 |
142 | 2. Basic Permissions.
143 |
144 | All rights granted under this License are granted for the term of
145 | copyright on the Program, and are irrevocable provided the stated
146 | conditions are met. This License explicitly affirms your unlimited
147 | permission to run the unmodified Program. The output from running a
148 | covered work is covered by this License only if the output, given its
149 | content, constitutes a covered work. This License acknowledges your
150 | rights of fair use or other equivalent, as provided by copyright law.
151 |
152 | You may make, run and propagate covered works that you do not
153 | convey, without conditions so long as your license otherwise remains
154 | in force. You may convey covered works to others for the sole purpose
155 | of having them make modifications exclusively for you, or provide you
156 | with facilities for running those works, provided that you comply with
157 | the terms of this License in conveying all material for which you do
158 | not control copyright. Those thus making or running the covered works
159 | for you must do so exclusively on your behalf, under your direction
160 | and control, on terms that prohibit them from making any copies of
161 | your copyrighted material outside their relationship with you.
162 |
163 | Conveying under any other circumstances is permitted solely under
164 | the conditions stated below. Sublicensing is not allowed; section 10
165 | makes it unnecessary.
166 |
167 | 3. Protecting Users' Legal Rights From Anti-Circumvention Law.
168 |
169 | No covered work shall be deemed part of an effective technological
170 | measure under any applicable law fulfilling obligations under article
171 | 11 of the WIPO copyright treaty adopted on 20 December 1996, or
172 | similar laws prohibiting or restricting circumvention of such
173 | measures.
174 |
175 | When you convey a covered work, you waive any legal power to forbid
176 | circumvention of technological measures to the extent such circumvention
177 | is effected by exercising rights under this License with respect to
178 | the covered work, and you disclaim any intention to limit operation or
179 | modification of the work as a means of enforcing, against the work's
180 | users, your or third parties' legal rights to forbid circumvention of
181 | technological measures.
182 |
183 | 4. Conveying Verbatim Copies.
184 |
185 | You may convey verbatim copies of the Program's source code as you
186 | receive it, in any medium, provided that you conspicuously and
187 | appropriately publish on each copy an appropriate copyright notice;
188 | keep intact all notices stating that this License and any
189 | non-permissive terms added in accord with section 7 apply to the code;
190 | keep intact all notices of the absence of any warranty; and give all
191 | recipients a copy of this License along with the Program.
192 |
193 | You may charge any price or no price for each copy that you convey,
194 | and you may offer support or warranty protection for a fee.
195 |
196 | 5. Conveying Modified Source Versions.
197 |
198 | You may convey a work based on the Program, or the modifications to
199 | produce it from the Program, in the form of source code under the
200 | terms of section 4, provided that you also meet all of these conditions:
201 |
202 | a) The work must carry prominent notices stating that you modified
203 | it, and giving a relevant date.
204 |
205 | b) The work must carry prominent notices stating that it is
206 | released under this License and any conditions added under section
207 | 7. This requirement modifies the requirement in section 4 to
208 | "keep intact all notices".
209 |
210 | c) You must license the entire work, as a whole, under this
211 | License to anyone who comes into possession of a copy. This
212 | License will therefore apply, along with any applicable section 7
213 | additional terms, to the whole of the work, and all its parts,
214 | regardless of how they are packaged. This License gives no
215 | permission to license the work in any other way, but it does not
216 | invalidate such permission if you have separately received it.
217 |
218 | d) If the work has interactive user interfaces, each must display
219 | Appropriate Legal Notices; however, if the Program has interactive
220 | interfaces that do not display Appropriate Legal Notices, your
221 | work need not make them do so.
222 |
223 | A compilation of a covered work with other separate and independent
224 | works, which are not by their nature extensions of the covered work,
225 | and which are not combined with it such as to form a larger program,
226 | in or on a volume of a storage or distribution medium, is called an
227 | "aggregate" if the compilation and its resulting copyright are not
228 | used to limit the access or legal rights of the compilation's users
229 | beyond what the individual works permit. Inclusion of a covered work
230 | in an aggregate does not cause this License to apply to the other
231 | parts of the aggregate.
232 |
233 | 6. Conveying Non-Source Forms.
234 |
235 | You may convey a covered work in object code form under the terms
236 | of sections 4 and 5, provided that you also convey the
237 | machine-readable Corresponding Source under the terms of this License,
238 | in one of these ways:
239 |
240 | a) Convey the object code in, or embodied in, a physical product
241 | (including a physical distribution medium), accompanied by the
242 | Corresponding Source fixed on a durable physical medium
243 | customarily used for software interchange.
244 |
245 | b) Convey the object code in, or embodied in, a physical product
246 | (including a physical distribution medium), accompanied by a
247 | written offer, valid for at least three years and valid for as
248 | long as you offer spare parts or customer support for that product
249 | model, to give anyone who possesses the object code either (1) a
250 | copy of the Corresponding Source for all the software in the
251 | product that is covered by this License, on a durable physical
252 | medium customarily used for software interchange, for a price no
253 | more than your reasonable cost of physically performing this
254 | conveying of source, or (2) access to copy the
255 | Corresponding Source from a network server at no charge.
256 |
257 | c) Convey individual copies of the object code with a copy of the
258 | written offer to provide the Corresponding Source. This
259 | alternative is allowed only occasionally and noncommercially, and
260 | only if you received the object code with such an offer, in accord
261 | with subsection 6b.
262 |
263 | d) Convey the object code by offering access from a designated
264 | place (gratis or for a charge), and offer equivalent access to the
265 | Corresponding Source in the same way through the same place at no
266 | further charge. You need not require recipients to copy the
267 | Corresponding Source along with the object code. If the place to
268 | copy the object code is a network server, the Corresponding Source
269 | may be on a different server (operated by you or a third party)
270 | that supports equivalent copying facilities, provided you maintain
271 | clear directions next to the object code saying where to find the
272 | Corresponding Source. Regardless of what server hosts the
273 | Corresponding Source, you remain obligated to ensure that it is
274 | available for as long as needed to satisfy these requirements.
275 |
276 | e) Convey the object code using peer-to-peer transmission, provided
277 | you inform other peers where the object code and Corresponding
278 | Source of the work are being offered to the general public at no
279 | charge under subsection 6d.
280 |
281 | A separable portion of the object code, whose source code is excluded
282 | from the Corresponding Source as a System Library, need not be
283 | included in conveying the object code work.
284 |
285 | A "User Product" is either (1) a "consumer product", which means any
286 | tangible personal property which is normally used for personal, family,
287 | or household purposes, or (2) anything designed or sold for incorporation
288 | into a dwelling. In determining whether a product is a consumer product,
289 | doubtful cases shall be resolved in favor of coverage. For a particular
290 | product received by a particular user, "normally used" refers to a
291 | typical or common use of that class of product, regardless of the status
292 | of the particular user or of the way in which the particular user
293 | actually uses, or expects or is expected to use, the product. A product
294 | is a consumer product regardless of whether the product has substantial
295 | commercial, industrial or non-consumer uses, unless such uses represent
296 | the only significant mode of use of the product.
297 |
298 | "Installation Information" for a User Product means any methods,
299 | procedures, authorization keys, or other information required to install
300 | and execute modified versions of a covered work in that User Product from
301 | a modified version of its Corresponding Source. The information must
302 | suffice to ensure that the continued functioning of the modified object
303 | code is in no case prevented or interfered with solely because
304 | modification has been made.
305 |
306 | If you convey an object code work under this section in, or with, or
307 | specifically for use in, a User Product, and the conveying occurs as
308 | part of a transaction in which the right of possession and use of the
309 | User Product is transferred to the recipient in perpetuity or for a
310 | fixed term (regardless of how the transaction is characterized), the
311 | Corresponding Source conveyed under this section must be accompanied
312 | by the Installation Information. But this requirement does not apply
313 | if neither you nor any third party retains the ability to install
314 | modified object code on the User Product (for example, the work has
315 | been installed in ROM).
316 |
317 | The requirement to provide Installation Information does not include a
318 | requirement to continue to provide support service, warranty, or updates
319 | for a work that has been modified or installed by the recipient, or for
320 | the User Product in which it has been modified or installed. Access to a
321 | network may be denied when the modification itself materially and
322 | adversely affects the operation of the network or violates the rules and
323 | protocols for communication across the network.
324 |
325 | Corresponding Source conveyed, and Installation Information provided,
326 | in accord with this section must be in a format that is publicly
327 | documented (and with an implementation available to the public in
328 | source code form), and must require no special password or key for
329 | unpacking, reading or copying.
330 |
331 | 7. Additional Terms.
332 |
333 | "Additional permissions" are terms that supplement the terms of this
334 | License by making exceptions from one or more of its conditions.
335 | Additional permissions that are applicable to the entire Program shall
336 | be treated as though they were included in this License, to the extent
337 | that they are valid under applicable law. If additional permissions
338 | apply only to part of the Program, that part may be used separately
339 | under those permissions, but the entire Program remains governed by
340 | this License without regard to the additional permissions.
341 |
342 | When you convey a copy of a covered work, you may at your option
343 | remove any additional permissions from that copy, or from any part of
344 | it. (Additional permissions may be written to require their own
345 | removal in certain cases when you modify the work.) You may place
346 | additional permissions on material, added by you to a covered work,
347 | for which you have or can give appropriate copyright permission.
348 |
349 | Notwithstanding any other provision of this License, for material you
350 | add to a covered work, you may (if authorized by the copyright holders of
351 | that material) supplement the terms of this License with terms:
352 |
353 | a) Disclaiming warranty or limiting liability differently from the
354 | terms of sections 15 and 16 of this License; or
355 |
356 | b) Requiring preservation of specified reasonable legal notices or
357 | author attributions in that material or in the Appropriate Legal
358 | Notices displayed by works containing it; or
359 |
360 | c) Prohibiting misrepresentation of the origin of that material, or
361 | requiring that modified versions of such material be marked in
362 | reasonable ways as different from the original version; or
363 |
364 | d) Limiting the use for publicity purposes of names of licensors or
365 | authors of the material; or
366 |
367 | e) Declining to grant rights under trademark law for use of some
368 | trade names, trademarks, or service marks; or
369 |
370 | f) Requiring indemnification of licensors and authors of that
371 | material by anyone who conveys the material (or modified versions of
372 | it) with contractual assumptions of liability to the recipient, for
373 | any liability that these contractual assumptions directly impose on
374 | those licensors and authors.
375 |
376 | All other non-permissive additional terms are considered "further
377 | restrictions" within the meaning of section 10. If the Program as you
378 | received it, or any part of it, contains a notice stating that it is
379 | governed by this License along with a term that is a further
380 | restriction, you may remove that term. If a license document contains
381 | a further restriction but permits relicensing or conveying under this
382 | License, you may add to a covered work material governed by the terms
383 | of that license document, provided that the further restriction does
384 | not survive such relicensing or conveying.
385 |
386 | If you add terms to a covered work in accord with this section, you
387 | must place, in the relevant source files, a statement of the
388 | additional terms that apply to those files, or a notice indicating
389 | where to find the applicable terms.
390 |
391 | Additional terms, permissive or non-permissive, may be stated in the
392 | form of a separately written license, or stated as exceptions;
393 | the above requirements apply either way.
394 |
395 | 8. Termination.
396 |
397 | You may not propagate or modify a covered work except as expressly
398 | provided under this License. Any attempt otherwise to propagate or
399 | modify it is void, and will automatically terminate your rights under
400 | this License (including any patent licenses granted under the third
401 | paragraph of section 11).
402 |
403 | However, if you cease all violation of this License, then your
404 | license from a particular copyright holder is reinstated (a)
405 | provisionally, unless and until the copyright holder explicitly and
406 | finally terminates your license, and (b) permanently, if the copyright
407 | holder fails to notify you of the violation by some reasonable means
408 | prior to 60 days after the cessation.
409 |
410 | Moreover, your license from a particular copyright holder is
411 | reinstated permanently if the copyright holder notifies you of the
412 | violation by some reasonable means, this is the first time you have
413 | received notice of violation of this License (for any work) from that
414 | copyright holder, and you cure the violation prior to 30 days after
415 | your receipt of the notice.
416 |
417 | Termination of your rights under this section does not terminate the
418 | licenses of parties who have received copies or rights from you under
419 | this License. If your rights have been terminated and not permanently
420 | reinstated, you do not qualify to receive new licenses for the same
421 | material under section 10.
422 |
423 | 9. Acceptance Not Required for Having Copies.
424 |
425 | You are not required to accept this License in order to receive or
426 | run a copy of the Program. Ancillary propagation of a covered work
427 | occurring solely as a consequence of using peer-to-peer transmission
428 | to receive a copy likewise does not require acceptance. However,
429 | nothing other than this License grants you permission to propagate or
430 | modify any covered work. These actions infringe copyright if you do
431 | not accept this License. Therefore, by modifying or propagating a
432 | covered work, you indicate your acceptance of this License to do so.
433 |
434 | 10. Automatic Licensing of Downstream Recipients.
435 |
436 | Each time you convey a covered work, the recipient automatically
437 | receives a license from the original licensors, to run, modify and
438 | propagate that work, subject to this License. You are not responsible
439 | for enforcing compliance by third parties with this License.
440 |
441 | An "entity transaction" is a transaction transferring control of an
442 | organization, or substantially all assets of one, or subdividing an
443 | organization, or merging organizations. If propagation of a covered
444 | work results from an entity transaction, each party to that
445 | transaction who receives a copy of the work also receives whatever
446 | licenses to the work the party's predecessor in interest had or could
447 | give under the previous paragraph, plus a right to possession of the
448 | Corresponding Source of the work from the predecessor in interest, if
449 | the predecessor has it or can get it with reasonable efforts.
450 |
451 | You may not impose any further restrictions on the exercise of the
452 | rights granted or affirmed under this License. For example, you may
453 | not impose a license fee, royalty, or other charge for exercise of
454 | rights granted under this License, and you may not initiate litigation
455 | (including a cross-claim or counterclaim in a lawsuit) alleging that
456 | any patent claim is infringed by making, using, selling, offering for
457 | sale, or importing the Program or any portion of it.
458 |
459 | 11. Patents.
460 |
461 | A "contributor" is a copyright holder who authorizes use under this
462 | License of the Program or a work on which the Program is based. The
463 | work thus licensed is called the contributor's "contributor version".
464 |
465 | A contributor's "essential patent claims" are all patent claims
466 | owned or controlled by the contributor, whether already acquired or
467 | hereafter acquired, that would be infringed by some manner, permitted
468 | by this License, of making, using, or selling its contributor version,
469 | but do not include claims that would be infringed only as a
470 | consequence of further modification of the contributor version. For
471 | purposes of this definition, "control" includes the right to grant
472 | patent sublicenses in a manner consistent with the requirements of
473 | this License.
474 |
475 | Each contributor grants you a non-exclusive, worldwide, royalty-free
476 | patent license under the contributor's essential patent claims, to
477 | make, use, sell, offer for sale, import and otherwise run, modify and
478 | propagate the contents of its contributor version.
479 |
480 | In the following three paragraphs, a "patent license" is any express
481 | agreement or commitment, however denominated, not to enforce a patent
482 | (such as an express permission to practice a patent or covenant not to
483 | sue for patent infringement). To "grant" such a patent license to a
484 | party means to make such an agreement or commitment not to enforce a
485 | patent against the party.
486 |
487 | If you convey a covered work, knowingly relying on a patent license,
488 | and the Corresponding Source of the work is not available for anyone
489 | to copy, free of charge and under the terms of this License, through a
490 | publicly available network server or other readily accessible means,
491 | then you must either (1) cause the Corresponding Source to be so
492 | available, or (2) arrange to deprive yourself of the benefit of the
493 | patent license for this particular work, or (3) arrange, in a manner
494 | consistent with the requirements of this License, to extend the patent
495 | license to downstream recipients. "Knowingly relying" means you have
496 | actual knowledge that, but for the patent license, your conveying the
497 | covered work in a country, or your recipient's use of the covered work
498 | in a country, would infringe one or more identifiable patents in that
499 | country that you have reason to believe are valid.
500 |
501 | If, pursuant to or in connection with a single transaction or
502 | arrangement, you convey, or propagate by procuring conveyance of, a
503 | covered work, and grant a patent license to some of the parties
504 | receiving the covered work authorizing them to use, propagate, modify
505 | or convey a specific copy of the covered work, then the patent license
506 | you grant is automatically extended to all recipients of the covered
507 | work and works based on it.
508 |
509 | A patent license is "discriminatory" if it does not include within
510 | the scope of its coverage, prohibits the exercise of, or is
511 | conditioned on the non-exercise of one or more of the rights that are
512 | specifically granted under this License. You may not convey a covered
513 | work if you are a party to an arrangement with a third party that is
514 | in the business of distributing software, under which you make payment
515 | to the third party based on the extent of your activity of conveying
516 | the work, and under which the third party grants, to any of the
517 | parties who would receive the covered work from you, a discriminatory
518 | patent license (a) in connection with copies of the covered work
519 | conveyed by you (or copies made from those copies), or (b) primarily
520 | for and in connection with specific products or compilations that
521 | contain the covered work, unless you entered into that arrangement,
522 | or that patent license was granted, prior to 28 March 2007.
523 |
524 | Nothing in this License shall be construed as excluding or limiting
525 | any implied license or other defenses to infringement that may
526 | otherwise be available to you under applicable patent law.
527 |
528 | 12. No Surrender of Others' Freedom.
529 |
530 | If conditions are imposed on you (whether by court order, agreement or
531 | otherwise) that contradict the conditions of this License, they do not
532 | excuse you from the conditions of this License. If you cannot convey a
533 | covered work so as to satisfy simultaneously your obligations under this
534 | License and any other pertinent obligations, then as a consequence you may
535 | not convey it at all. For example, if you agree to terms that obligate you
536 | to collect a royalty for further conveying from those to whom you convey
537 | the Program, the only way you could satisfy both those terms and this
538 | License would be to refrain entirely from conveying the Program.
539 |
540 | 13. Remote Network Interaction; Use with the GNU General Public License.
541 |
542 | Notwithstanding any other provision of this License, if you modify the
543 | Program, your modified version must prominently offer all users
544 | interacting with it remotely through a computer network (if your version
545 | supports such interaction) an opportunity to receive the Corresponding
546 | Source of your version by providing access to the Corresponding Source
547 | from a network server at no charge, through some standard or customary
548 | means of facilitating copying of software. This Corresponding Source
549 | shall include the Corresponding Source for any work covered by version 3
550 | of the GNU General Public License that is incorporated pursuant to the
551 | following paragraph.
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 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 work with which it is combined will remain governed by version
559 | 3 of the GNU General Public License.
560 |
561 | 14. Revised Versions of this License.
562 |
563 | The Free Software Foundation may publish revised and/or new versions of
564 | the GNU Affero General Public License from time to time. Such new versions
565 | will be similar in spirit to the present version, but may differ in detail to
566 | address new problems or concerns.
567 |
568 | Each version is given a distinguishing version number. If the
569 | Program specifies that a certain numbered version of the GNU Affero General
570 | Public License "or any later version" applies to it, you have the
571 | option of following the terms and conditions either of that numbered
572 | version or of any later version published by the Free Software
573 | Foundation. If the Program does not specify a version number of the
574 | GNU Affero General Public License, you may choose any version ever published
575 | by the Free Software Foundation.
576 |
577 | If the Program specifies that a proxy can decide which future
578 | versions of the GNU Affero General Public License can be used, that proxy's
579 | public statement of acceptance of a version permanently authorizes you
580 | to choose that version for the Program.
581 |
582 | Later license versions may give you additional or different
583 | permissions. However, no additional obligations are imposed on any
584 | author or copyright holder as a result of your choosing to follow a
585 | later version.
586 |
587 | 15. Disclaimer of Warranty.
588 |
589 | THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
590 | APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
591 | HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
592 | OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
593 | THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
594 | PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
595 | IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
596 | ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
597 |
598 | 16. Limitation of Liability.
599 |
600 | IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
601 | WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
602 | THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
603 | GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
604 | USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
605 | DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
606 | PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
607 | EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
608 | SUCH DAMAGES.
609 |
610 | 17. Interpretation of Sections 15 and 16.
611 |
612 | If the disclaimer of warranty and limitation of liability provided
613 | above cannot be given local legal effect according to their terms,
614 | reviewing courts shall apply local law that most closely approximates
615 | an absolute waiver of all civil liability in connection with the
616 | Program, unless a warranty or assumption of liability accompanies a
617 | copy of the Program in return for a fee.
618 |
619 | END OF TERMS AND CONDITIONS
620 |
621 | How to Apply These Terms to Your New Programs
622 |
623 | If you develop a new program, and you want it to be of the greatest
624 | possible use to the public, the best way to achieve this is to make it
625 | free software which everyone can redistribute and change under these terms.
626 |
627 | To do so, attach the following notices to the program. It is safest
628 | to attach them to the start of each source file to most effectively
629 | state the exclusion of warranty; and each file should have at least
630 | the "copyright" line and a pointer to where the full notice is found.
631 |
632 |
633 | Copyright (C)
634 |
635 | This program is free software: you can redistribute it and/or modify
636 | it under the terms of the GNU Affero General Public License as published by
637 | the Free Software Foundation, either version 3 of the License, or
638 | (at your option) any later version.
639 |
640 | This program is distributed in the hope that it will be useful,
641 | but WITHOUT ANY WARRANTY; without even the implied warranty of
642 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
643 | GNU Affero General Public License for more details.
644 |
645 | You should have received a copy of the GNU Affero General Public License
646 | along with this program. If not, see .
647 |
648 | Also add information on how to contact you by electronic and paper mail.
649 |
650 | If your software can interact with users remotely through a computer
651 | network, you should also make sure that it provides a way for users to
652 | get its source. For example, if your program is a web application, its
653 | interface could display a "Source" link that leads users to an archive
654 | of the code. There are many ways you could offer source, and different
655 | solutions will be better for different programs; see section 13 for the
656 | specific requirements.
657 |
658 | You should also get your employer (if you work as a programmer) or school,
659 | if any, to sign a "copyright disclaimer" for the program, if necessary.
660 | For more information on this, and how to apply and follow the GNU AGPL, see
661 | .
662 |
--------------------------------------------------------------------------------
/INSTALL:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/avati/libevil/0ae9450e42f04a7ac9bc3a1ca0e6956268efbc4d/INSTALL
--------------------------------------------------------------------------------
/Makefile.am:
--------------------------------------------------------------------------------
1 | EXTRA_DIST = autogen.sh COPYING INSTALL build-static-gpg.sh gluster-lic.spec pubring.gpg
2 |
3 | bin_SCRIPTS = gluster-lic-request gluster-lic-setup gluster-lic-install gluster-lic-sign gluster-lic-info gluster-lic-register
4 | bin_PROGRAMS = gpgv gluster-lic-uninstall
5 |
6 | gluster_lic_uninstall_SOURCES = gluster-lic-uninstall.c
7 | gluster_lic_uninstall_CFLAGS = -static
8 | gluster_lic_uninstall_LDFLAGS = -static
9 |
10 | etc_profile_d_SCRIPTS = gluster-lic.sh
11 | etc_profile_ddir = /etc/profile.d
12 |
13 | permit_SCRIPTS = permits-create.sh permits-install.sh
14 | permitdir = $(libdir)
15 |
16 | sysconf_DATA = pubring.gpg
17 |
18 | gpgv_SOURCES =
19 | gpgv: $(srcdir)/build-static-gpg.sh
20 | $(srcdir)/build-static-gpg.sh
21 |
22 | noinst_HEADERS = libevil.h md5.c
23 |
24 | le_PROGRAMS = libevil.so
25 | ledir = $(libdir)
26 | libevil_so_SOURCES = libevil.c
27 | libevil_so_CFLAGS = -D_GNU_SOURCE -fPIC -Wall -pthread -shared
28 | libevil_so_CPPFLAGS = -D_FILE_OFFSET_BITS=64 -D_GNU_SOURCE
29 | libevil_so_LDFLAGS = -module -avoidversion -shared -ldl
30 | # libevil_la_LIBADD =
31 |
32 | CLEANFILES =
33 |
--------------------------------------------------------------------------------
/README:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/avati/libevil/0ae9450e42f04a7ac9bc3a1ca0e6956268efbc4d/README
--------------------------------------------------------------------------------
/autogen.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 |
3 | aclocal
4 | #autoheader
5 | #(libtoolize --automake --copy --force || glibtoolize --automake --copy --force)
6 | autoconf
7 | automake --add-missing --copy --foreign
8 |
--------------------------------------------------------------------------------
/build-static-gpg.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash -e
2 |
3 | gnupg_version="gnupg-1.4.11"
4 | url="ftp://ftp.gnupg.org/gcrypt/gnupg/$gnupg_version.tar.bz2"
5 | url="http://ftp.heanet.ie/disk1/ftp.gnupg.org/gcrypt/gnupg/$gnupg_version.tar.bz2"
6 |
7 | function prepare_source()
8 | {
9 | wget -c $url -O /tmp/$gnupg_version.tar.bz2;
10 | tar -xjf /tmp/$gnupg_version.tar.bz2;
11 | cd $gnupg_version;
12 | }
13 |
14 |
15 | function build_static_gpg()
16 | {
17 | ./configure --quiet CFLAGS="-static";
18 | make --quiet;
19 | }
20 |
21 |
22 | function main()
23 | {
24 | (prepare_source; build_static_gpg;)
25 |
26 | cp -v $gnupg_version/g10/gpgv .;
27 | }
28 |
29 | main "$@"
30 |
--------------------------------------------------------------------------------
/configure.ac:
--------------------------------------------------------------------------------
1 | dnl Copyright (c) 2011 Gluster, Inc.
2 | dnl This file is part of GlusterFS.
3 | dnl
4 | dnl GlusterFS is free software; you can redistribute it and/or modify
5 | dnl it under the terms of the GNU Affero General Public License as published by
6 | dnl the Free Software Foundation; either version 3 of the License, or
7 | dnl (at your option) any later version.
8 | dnl
9 | dnl GlusterFS is distributed in the hope that it will be useful,
10 | dnl but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | dnl GNU Affero General Public License for more details.
13 | dnl
14 | dnl You should have received a copy of the GNU Affero General Public License
15 | dnl along with this program. If not, see .
16 |
17 | AC_INIT([gluster-lic],[0.8],[support@gluster.com])
18 |
19 | AM_INIT_AUTOMAKE
20 |
21 | AC_CONFIG_FILES([Makefile
22 | gluster-lic-setup
23 | gluster-lic-request
24 | gluster-lic-register
25 | gluster-lic-install
26 | gluster-lic-sign
27 | gluster-lic-info
28 | gluster-lic.spec
29 | gluster-lic.sh
30 | permits-create.sh
31 | permits-install.sh])
32 |
33 | AC_CANONICAL_HOST
34 |
35 | AC_PROG_CC
36 | #AC_PROG_LIBTOOL
37 |
38 | AC_CHECK_TOOL([LD],[ld])
39 |
40 | AC_CHECK_LIB([pthread], [pthread_mutex_init], ,AC_MSG_ERROR([Posix threads library is required by libevil]))
41 |
42 | AC_CHECK_FUNC([pthread_spin_init], [have_spinlock=yes])
43 | if test "x${have_spinlock}" = "xyes"; then
44 | AC_DEFINE(HAVE_SPINLOCK, 1, [define if found spinlock])
45 | fi
46 | AC_SUBST(HAVE_SPINLOCK)
47 |
48 |
49 | AC_OUTPUT
50 |
--------------------------------------------------------------------------------
/gluster-lic-info.in:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 |
4 | ME=$(basename $0);
5 |
6 |
7 | function epoch()
8 | {
9 | aT=$(stat -c '%X' /.epoch);
10 | mT=$(stat -c '%Y' /.epoch);
11 | cT=$(stat -c '%Z' /.epoch);
12 |
13 | dE=$((echo $aT; echo $mT; echo $cT) | sort -n | head -n 1);
14 |
15 | echo $dE;
16 | }
17 |
18 |
19 | function food()
20 | {
21 | if [ -f /.default ]; then
22 | delta=$(cat /.default);
23 | else
24 | delta=$((30 * 24 * 3600));
25 | fi
26 |
27 | echo $delta;
28 | }
29 |
30 |
31 | function say_and_die()
32 | {
33 | if [ $now -gt $expire ]; then
34 | status=dead;
35 | else
36 | status=alive;
37 | fi
38 |
39 | case "$mode" in
40 | unlicensed)
41 | if [ -f /.default ]; then
42 | cat </dev/null);
165 |
166 | if [ -z "$macid" ]; then
167 | cat </dev/null 2>&1;
186 | if [ $? -ne 0 ]; then
187 | mode=invalid_license;
188 | expire=$def_expire;
189 | else
190 | count=$(grep '^........-....-....-....-............ ' /lic/license.asc | wc -l);
191 | if grep -q "^$macid " /lic/license.asc; then
192 | expire=$(grep "^$macid " /lic/license.asc | cut -f2 -d' ');
193 | mode=licensed;
194 | else
195 | expire=$def_expire;
196 | mode=mislicensed;
197 | fi
198 | fi
199 | fi
200 |
201 | say_and_die;
202 | }
203 |
204 | main "$@";
205 |
--------------------------------------------------------------------------------
/gluster-lic-install.in:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 |
4 | ME=$(basename $0);
5 |
6 |
7 | function validate_license()
8 | {
9 | echo -n "Validating signature ... "
10 |
11 | /lic/gpgv --keyring /lic/pubring.gpg "$1" >/dev/null 2>&1;
12 |
13 | if [ $? -ne 0 ]; then
14 | echo "FAILED."
15 | exit 1;
16 | fi
17 |
18 | echo "done."
19 |
20 | true
21 | }
22 |
23 |
24 | function show_help()
25 | {
26 | cat </dev/null | grep -i hostname: | cut -f2 -d: );
73 | server_list=$(cat /etc/glusterd/peers/* 2>/dev/null | grep -i hostname1= | cut -f2 -d= );
74 |
75 | validate_license $1;
76 |
77 | for server in $server_list localhost; do
78 | scp "$1" $server:/lic/license.asc;
79 | if [ $? -ne 0 ]; then
80 | echo "Installing license on $server failed";
81 | fi
82 | done
83 |
84 | @prefix@/bin/gluster-lic-info
85 | }
86 |
87 | main "$@";
88 |
--------------------------------------------------------------------------------
/gluster-lic-register.in:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | #
3 | # chkconfig: 35 99 12
4 | # description: Register this instance with Gluster
5 | #
6 |
7 |
8 | ME=$(basename $0);
9 |
10 |
11 | function show_help()
12 | {
13 | cat < /lic/.registered;
53 | }
54 |
55 |
56 | function main()
57 | {
58 | # Parse command line arguments.
59 | while getopts :h OPT; do
60 | case "$OPT" in
61 | h)
62 | show_help
63 | exit 0
64 | ;;
65 | \?)
66 | # getopts issues an error message
67 | echo "Invalid option: -$OPTARG"
68 | show_help
69 | exit 1
70 | ;;
71 | esac
72 | done
73 |
74 | if [ ! -f /.default -o -f /lic/.registered ]; then
75 | exit 0;
76 | fi
77 |
78 | gluster_pingback &
79 | }
80 |
81 | main "$@";
82 |
--------------------------------------------------------------------------------
/gluster-lic-request.in:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 |
4 | ME=$(basename $0);
5 |
6 |
7 | function show_help()
8 | {
9 | cat </dev/null | grep -i hostname: | cut -f2 -d: );
55 | server_list=$(cat /etc/glusterd/peers/* 2>/dev/null | grep -i hostname1= | cut -f2 -d= );
56 | now=$(date '+%s');
57 | environment="Virtual";
58 |
59 | if [ -e @prefix@/etc/ec2-pk.pem ]; then
60 | environment="AWS";
61 | fi
62 |
63 | exec 20>license.req;
64 | count=0;
65 | for server in $server_list localhost; do
66 | echo -n "Querying $server ... ";
67 |
68 | macid=$(ssh $server cat /.epoch);
69 | if [ $? -ne 0 ]; then
70 | echo "failed to get machine identity (skipping)";
71 | continue
72 | fi
73 |
74 | hostname=$(ssh $server hostname --fqdn);
75 | if [ $? -ne 0 ]; then
76 | hostname=$(ssh $server hostname);
77 | if [ $? -ne 0 ]; then
78 | echo "failed to get hostname (skipping)";
79 | continue
80 | fi
81 | fi
82 |
83 | echo "($macid $hostname)"
84 |
85 | echo "$macid $now $hostname $environment" >&20;
86 | count=$(( $count + 1 ));
87 | done
88 | exec 20>&-;
89 |
90 | cat < /etc/ld.32.preload;
29 | fi
30 |
31 | if [ ! -z "$le64so" -a ! -z "$ld64so" ]; then
32 | cp $le64so $ld64dir/libevil64.so;
33 | chown root:root $ld64dir/libevil64.so;
34 | chmod g+s $ld64dir/libevil64.so;
35 | echo $ld64dir/libevil64.so > /etc/ld.so.preload;
36 | fi
37 | }
38 |
39 |
40 | function main()
41 | {
42 | if [ ! -d /lic ]; then
43 | mkdir -p /lic;
44 | cp @bindir@/gpgv /lic;
45 | cp @sysconfdir@/pubring.gpg /lic;
46 | fi
47 |
48 | if [ ! -e /.epoch ]; then
49 | uuidgen -r > /.epoch;
50 | fi
51 |
52 | if [ ! -e /etc/glusterd/glusterd.info ]; then
53 | uuid=$(cat /.epoch);
54 | mkdir -p /etc/glusterd;
55 | echo "UUID=$uuid" > /etc/glusterd/glusterd.info;
56 | fi
57 |
58 | install_libevil;
59 | }
60 |
61 | main "$@";
62 |
--------------------------------------------------------------------------------
/gluster-lic-sign.in:
--------------------------------------------------------------------------------
1 | #!/bin/bash -e
2 |
3 |
4 | ME=$(basename $0);
5 |
6 |
7 | function validate_uuid()
8 | {
9 | left=$(echo $1 | sed -r 's/[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}//g');
10 |
11 | if [ ! -z $left ]; then
12 | echo "FATAL: invalid UUID $1 (line $lineno)";
13 | exit 1
14 | fi
15 | }
16 |
17 |
18 | function validate_secs()
19 | {
20 | if [ ! -z $(echo $1 | sed 's/[0-9]*//g') ]; then
21 | echo "FATAL: invalid number $1 (line $lineno)";
22 | exit 1;
23 | fi
24 | }
25 |
26 |
27 | function validate_license_line()
28 | {
29 | set $@;
30 |
31 | validate_uuid "$1";
32 |
33 | validate_secs "$2";
34 | }
35 |
36 |
37 | function validate_license_request()
38 | {
39 | filename="$1";
40 |
41 | if [ "x$filename" != "x${filename%.lsr}" ]; then
42 | echo "FATAL: invalid filename $filename";
43 | exit 1;
44 | fi
45 |
46 | if [ "x$filename" != "x${filename%.asc}" ]; then
47 | echo "FATAL: invalid filename $filename";
48 | exit 1;
49 | fi
50 |
51 | echo -n "Validating license request $filename ... ";
52 |
53 | if [ ! -f $filename ]; then
54 | echo "FATAL: file does not exist";
55 | exit 1;
56 | fi
57 |
58 | if [ $(wc -l $filename | cut -f1 -d' ') -lt 2 ]; then
59 | echo "FATAL: file has fewer than 2 lines";
60 | exit 1;
61 | fi
62 |
63 | grep -E '^ *[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}' $filename | while read line; do
64 | validate_license_line "$line";
65 | done;
66 |
67 | lineno=$(grep -E '^ *[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}' $filename | wc -l);
68 |
69 | echo "done."
70 | }
71 |
72 |
73 | function validate_num_days()
74 | {
75 | numdays=$1
76 |
77 | while [ -z "$numdays" ]; do
78 | echo -n "Please enter the number days to generate the license for: "
79 | read numdays;
80 | done
81 |
82 | if [ ! -z $(echo "$numdays" | sed 's/[0-9]*//g') ]; then
83 | echo "FATAL: invalid number of days $1";
84 | exit 1;
85 | fi
86 |
87 | if [ $numdays -gt 366 ]; then
88 | cat >&2 < $lsrfile;
105 | sed -i -r -e "s/^([^ ]+[ ]+)[^ ]+(.*)\$/\1$expire\2/g" $lsrfile;
106 |
107 | expirestr=$(date -u --date="1970-01-01 00:00:00 $expire seconds");
108 | }
109 |
110 |
111 | function sign_license()
112 | {
113 | ascfile=${lsrfile%.lsr}.asc;
114 |
115 | cat $lsrfile | gpg --output $ascfile --clearsign;
116 | cat <
3 |
4 | GlusterFS is free software; you can redistribute it and/or modify
5 | it under the terms of the GNU General Public License as published
6 | by the Free Software Foundation; either version 3 of the License,
7 | or (at your option) any later version.
8 |
9 | GlusterFS is distributed in the hope that it will be useful, but
10 | WITHOUT ANY WARRANTY; without even the implied warranty of
11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 | General Public License for more details.
13 |
14 | You should have received a copy of the GNU General Public License
15 | along with this program. If not, see
16 | .
17 | */
18 |
19 | #include
20 | #include
21 | #include
22 |
23 |
24 | int
25 | clean_remove (const char *filename)
26 | {
27 | int ret = 0;
28 |
29 | errno = 0;
30 | ret = remove (filename);
31 | if (errno && errno != ENOENT) {
32 | fprintf (stderr, "remove(%s): %s\n",
33 | filename, strerror (errno));
34 | }
35 |
36 | return ret;
37 | }
38 |
39 |
40 | int
41 | main (int argc, char *argv[])
42 | {
43 | const char *entry = NULL;
44 | int i = 0;
45 | const char *remove_entries[] = {
46 | "/.epoch",
47 | "/.default",
48 | "/lic/gpgv",
49 | "/lic/pubring.gpg",
50 | "/lic/license.req",
51 | "/lic/license.asc",
52 | "/lic",
53 | "/lib/libevil32.so",
54 | "/lib64/libevil64.so",
55 | "/etc/ld.so.preload",
56 | "/etc/ld.32.preload",
57 | "/etc/profile.d/gluster-lic.sh",
58 | NULL,
59 | };
60 |
61 | for (i = 0; (entry = remove_entries[i]); i++) {
62 | clean_remove (entry);
63 | }
64 |
65 | return 0;
66 | }
67 |
--------------------------------------------------------------------------------
/gluster-lic.sh.in:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | @prefix@/bin/gluster-lic-info
4 |
--------------------------------------------------------------------------------
/gluster-lic.spec.in:
--------------------------------------------------------------------------------
1 | %define release 1%{?dist}
2 |
3 | Summary: Gluster Licensing - R. I. P.
4 | Name: @PACKAGE_NAME@
5 | Version: @PACKAGE_VERSION@
6 | Release: %{release}
7 | License: AGPLv3+
8 | Packager: @PACKAGE_BUGREPORT@
9 | Group: Applications/System
10 | URL: http://www.gluster.com
11 | Vendor: Gluster Inc
12 | Source0: %{name}-%{version}.tar.gz
13 | BuildRoot: %{_tmppath}/%{name}-%{version}-root
14 | Requires(post): /sbin/chkconfig
15 | Requires(preun): /sbin/service, /sbin/chkconfig
16 | Requires(postun): /sbin/service
17 |
18 | %define debug_package %{nil}
19 | %define __strip /bin/true
20 |
21 | %description
22 | Gluster Licensing
23 |
24 | %prep
25 | %setup -q
26 |
27 | %build
28 |
29 | %define m32flags %(if [ "%{_target_cpu}" = "i386" ]; then echo CFLAGS=-m32; fi)
30 |
31 | ./configure --prefix=/opt/gvsa --libdir=/opt/gvsa/%{_lib} %{m32flags}
32 | %{__make}
33 |
34 | %install
35 | %{__rm} -rf %{buildroot}
36 | %{__make} install DESTDIR=%{buildroot}
37 | %{__install} -d -m0755 %{buildroot}%{_initrddir}
38 | %{__install} -p -m0755 gluster-lic-setup %{buildroot}%{_initrddir}
39 | %{__install} -p -m0755 gluster-lic-register %{buildroot}%{_initrddir}
40 | %{buildroot}/opt/gvsa/%{_lib}/permits-create.sh %{buildroot}
41 |
42 |
43 | %clean
44 | %{__rm} -rf %{buildroot}
45 |
46 | %files
47 | %defattr(-,root,root,-)
48 | /etc/profile.d/gluster-lic.sh
49 | /opt/gvsa/bin/gluster-lic-install
50 | /opt/gvsa/bin/gluster-lic-uninstall
51 | /opt/gvsa/bin/gluster-lic-setup
52 | /opt/gvsa/bin/gluster-lic-request
53 | /opt/gvsa/bin/gluster-lic-info
54 | /opt/gvsa/bin/gluster-lic-sign
55 | /opt/gvsa/bin/gluster-lic-register
56 | /opt/gvsa/%{_lib}/permits-install.sh
57 | /opt/gvsa/%{_lib}/permits-create.sh
58 | /opt/gvsa/%{_lib}/libevil.so
59 | /opt/gvsa/bin/gpgv
60 | /opt/gvsa/etc/permits*.asc
61 | /opt/gvsa/etc/pubring.gpg
62 | %{_initrddir}/gluster-lic-setup
63 | %{_initrddir}/gluster-lic-register
64 |
65 |
66 | %post
67 | chkconfig --del gluster-lic-setup
68 | chkconfig --del gluster-lic-register
69 | /opt/gvsa/%{_lib}/permits-install.sh
70 | /opt/gvsa/bin/gluster-lic-uninstall
71 | %{__rm} -rf /check4update*;
72 |
73 | %changelog
74 | * Tue Jan 11 2011 - ami-tools
75 | - Initial build.
76 |
77 |
--------------------------------------------------------------------------------
/libevil.c:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright (c) 2011 Gluster, Inc.
3 | This file is part of GlusterFS.
4 |
5 | GlusterFS is free software; you can redistribute it and/or modify
6 | it under the terms of the GNU Affero General Public License as published
7 | by the Free Software Foundation; either version 3 of the License,
8 | or (at your option) any later version.
9 |
10 | GlusterFS is distributed in the hope that it will be useful, but
11 | WITHOUT ANY WARRANTY; without even the implied warranty of
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 | Affero General Public License for more details.
14 |
15 | You should have received a copy of the GNU Affero General Public License
16 | along with this program. If not, see
17 | .
18 | */
19 |
20 | #include
21 | #include
22 | #include
23 | #include
24 | #include
25 | #include
26 | #include
27 | #include
28 | #include
29 | #include
30 | #include
31 | #include
32 | #include
33 | #include
34 | #include
35 |
36 |
37 | #include "libevil.h"
38 | #include "md5.c"
39 |
40 |
41 | static const char *protpatterns[] = {
42 | EPOCH_FILE,
43 | DEFAULT_FILE,
44 | LICDIR,
45 | LICDIR "/gpgv",
46 | LICDIR "/pubring.gpg",
47 | "/etc",
48 | "/etc/ld.*.preload",
49 | "/lib*",
50 | "/lib*/libevil*.so",
51 | NULL,
52 | };
53 |
54 |
55 | static const char *licensed_symbols[] = {
56 | "iobuf_get",
57 | "gf_log_init",
58 | NULL,
59 | };
60 |
61 |
62 | static int le_debug = 0;
63 | static long int default_timeout = 0;
64 |
65 |
66 | static int
67 | dbg (const char *fmt, ...)
68 | {
69 | int ret = 0;
70 | va_list ap;
71 |
72 | if (!le_debug)
73 | return 0;
74 |
75 | va_start (ap, fmt);
76 | ret = vfprintf (stderr, fmt, ap);
77 | va_end (ap);
78 |
79 | return ret;
80 | }
81 |
82 |
83 | static int
84 | err (const char *fmt, ...)
85 | {
86 | int ret = 0;
87 | va_list ap;
88 |
89 | va_start (ap, fmt);
90 | ret = vfprintf (stderr, fmt, ap);
91 | va_end (ap);
92 |
93 | return ret;
94 | }
95 |
96 |
97 | static char *
98 | strip_n (char *str)
99 | {
100 | char *n = NULL;
101 |
102 | n = strchr (str, '\n');
103 | if (n)
104 | *n = '\0';
105 |
106 | return str;
107 | }
108 |
109 |
110 | static void
111 | dbg_init ()
112 | {
113 | if (getenv ("LE_DEBUG"))
114 | le_debug = 1;
115 | }
116 |
117 |
118 | static int
119 | globerr (const char *epath, int eerrno)
120 | {
121 | dbg ("%s: %s\n", epath, strerror (eerrno));
122 |
123 | return 0;
124 | }
125 |
126 |
127 | struct permit_entry {
128 | struct permit_entry *next;
129 | unsigned char md5sum[16];
130 | char *path;
131 | };
132 |
133 |
134 | static struct {
135 | pthread_rwlock_t rwlock;
136 | glob_t protglob;
137 | struct stat *stats;
138 | int permitcnt;
139 | struct permit_entry *permits;
140 | char macid[64];
141 | pthread_t bigbro;
142 | } protect;
143 |
144 |
145 | static int is_signed_file (const char *filename);
146 |
147 | static void
148 | __rehash_glob (void)
149 | {
150 | int ret = 0;
151 | int i = 0;
152 | int globflags = GLOB_BRACE;
153 | const char *pattern = NULL;
154 | char **files = NULL;
155 | struct stat *stats = NULL;
156 |
157 |
158 | if (protect.protglob.gl_pathc) {
159 | globfree (&protect.protglob);
160 | protect.protglob.gl_pathc = 0;
161 | if (protect.stats)
162 | free (protect.stats);
163 | protect.stats = NULL;
164 | }
165 |
166 | for (i = 0; (pattern = protpatterns[i]); i++) {
167 | ret = glob (pattern, globflags, globerr, &protect.protglob);
168 |
169 | if (ret && ret != GLOB_NOMATCH) {
170 | globfree (&protect.protglob);
171 | protect.protglob.gl_pathc = 0;
172 | return;
173 | }
174 |
175 | globflags |= GLOB_APPEND;
176 | }
177 |
178 | files = protect.protglob.gl_pathv;
179 |
180 | stats = calloc (protect.protglob.gl_pathc, sizeof (*stats));
181 | if (!stats) {
182 | globfree (&protect.protglob);
183 | protect.protglob.gl_pathc = 0;
184 | return;
185 | }
186 |
187 | for (i = 0; i < protect.protglob.gl_pathc; i++) {
188 | ret = lstat (files[i], &stats[i]);
189 | if (ret == 0) {
190 | #if 0
191 | dbg ("%s: %lld/%lld\n", files[i],
192 | (long long) (stats[i].st_ino),
193 | (long long) (stats[i].st_dev));
194 | #endif
195 | } else {
196 | dbg ("%s: %s\n", files[i], strerror (errno));
197 | }
198 | }
199 |
200 | protect.stats = stats;
201 |
202 | return;
203 | }
204 |
205 |
206 | static void
207 | rehash_glob (void)
208 | {
209 | pthread_rwlock_wrlock (&protect.rwlock);
210 | {
211 | __rehash_glob ();
212 | }
213 | pthread_rwlock_unlock (&protect.rwlock);
214 | }
215 |
216 |
217 | static void
218 | prepare_glob (void)
219 | {
220 | pthread_rwlock_init (&protect.rwlock, NULL);
221 | rehash_glob ();
222 | }
223 |
224 |
225 | static int
226 | __is_protected_atpath (int dirfd, const char *path, int follow)
227 | {
228 | int i = 0;
229 | int pathc = 0;
230 | struct stat *stats = NULL;
231 | struct stat mystat = {0, };
232 | int ret = 0;
233 | int flags = AT_SYMLINK_NOFOLLOW;
234 |
235 | pathc = protect.protglob.gl_pathc;
236 | stats = protect.stats;
237 |
238 | if (follow)
239 | flags = 0;
240 |
241 | ret = fstatat (dirfd, path, &mystat, flags);
242 | if (ret)
243 | return NO;
244 |
245 | for (i = 0; i < pathc; i++) {
246 | if (stats[i].st_ino == mystat.st_ino
247 | && stats[i].st_dev == mystat.st_dev)
248 | return YES;
249 | }
250 |
251 | return NO;
252 | }
253 |
254 |
255 | static int
256 | __is_protected_atfile (int dirfd, const char *path)
257 | {
258 | return __is_protected_atpath (dirfd, path, 1);
259 | }
260 |
261 |
262 | static int
263 | is_protected_atfile (int dirfd, const char *path)
264 | {
265 | int ret = 0;
266 |
267 | pthread_rwlock_rdlock (&protect.rwlock);
268 | {
269 | ret = __is_protected_atfile (dirfd, path);
270 | }
271 | pthread_rwlock_unlock (&protect.rwlock);
272 |
273 | return ret;
274 | }
275 |
276 |
277 | static int
278 | __is_protected_atentry (int dirfd, const char *path)
279 | {
280 | return __is_protected_atpath (dirfd, path, 0);
281 | }
282 |
283 |
284 | static int
285 | is_protected_atentry (int dirfd, const char *path)
286 | {
287 | int ret = 0;
288 |
289 | pthread_rwlock_rdlock (&protect.rwlock);
290 | {
291 | ret = __is_protected_atentry (dirfd, path);
292 | }
293 | pthread_rwlock_unlock (&protect.rwlock);
294 |
295 | return ret;
296 | }
297 |
298 |
299 | static int
300 | is_protected_file (const char *path)
301 | {
302 | int ret = 0;
303 |
304 | pthread_rwlock_rdlock (&protect.rwlock);
305 | {
306 | ret = __is_protected_atfile (AT_FDCWD, path);
307 | }
308 | pthread_rwlock_unlock (&protect.rwlock);
309 |
310 | return ret;
311 | }
312 |
313 |
314 | static int
315 | is_protected_entry (const char *path)
316 | {
317 | int ret = 0;
318 |
319 | pthread_rwlock_rdlock (&protect.rwlock);
320 | {
321 | ret = __is_protected_atentry (AT_FDCWD, path);
322 | }
323 | pthread_rwlock_unlock (&protect.rwlock);
324 |
325 | return ret;
326 | }
327 |
328 |
329 | static int
330 | __is_protected_fd (int fd)
331 | {
332 | int i = 0;
333 | int pathc = 0;
334 | struct stat *stats = NULL;
335 | struct stat mystat = {0, };
336 | int ret = 0;
337 |
338 | pathc = protect.protglob.gl_pathc;
339 | stats = protect.stats;
340 |
341 | ret = fstat (fd, &mystat);
342 | if (ret)
343 | return NO;
344 |
345 | for (i = 0; i < pathc; i++) {
346 | if (stats[i].st_ino == mystat.st_ino
347 | && stats[i].st_dev == mystat.st_dev)
348 | return YES;
349 | }
350 |
351 | return NO;
352 | }
353 |
354 |
355 | static int
356 | is_protected_fd (int fd)
357 | {
358 | int ret = 0;
359 |
360 | pthread_rwlock_rdlock (&protect.rwlock);
361 | {
362 | ret = __is_protected_fd (fd);
363 | }
364 | pthread_rwlock_unlock (&protect.rwlock);
365 |
366 | return ret;
367 | }
368 |
369 |
370 | static time_t
371 | get_default_deadline (void)
372 | {
373 | struct stat epoch_stat = {0, };
374 | int ret = 0;
375 | time_t epoch = 0;
376 |
377 | ret = lstat (EPOCH_FILE, &epoch_stat);
378 | if (ret != 0)
379 | return 0;
380 |
381 | epoch = epoch_stat.st_ctime;
382 | if (epoch_stat.st_mtime < epoch)
383 | epoch = epoch_stat.st_mtime;
384 | if (epoch_stat.st_atime < epoch)
385 | epoch = epoch_stat.st_atime;
386 |
387 | return (epoch + default_timeout);
388 | }
389 |
390 |
391 | static time_t
392 | license_parse (FILE *fp)
393 | {
394 | char line[1024];
395 | char *l = NULL;
396 | char *saveptr = NULL;;
397 | char *macid = NULL;
398 | char *timestamp = NULL;
399 | char *end = NULL;
400 | time_t final_ts = 0;
401 | time_t ts = 0;
402 | char timebuf[64];
403 |
404 |
405 | while ((l = fgets (line, 1024, fp))) {
406 | macid = strtok_r (line, " \r\n\t", &saveptr);
407 | if (!macid)
408 | continue;
409 |
410 | if (strcmp (macid, protect.macid) != 0) {
411 | macid = NULL;
412 | continue;
413 | }
414 |
415 | dbg ("found entry macid=%s\n", macid);
416 |
417 | timestamp = strtok_r (NULL, " \r\n\t", &saveptr);
418 | if (!timestamp) {
419 | macid = NULL;
420 | continue;
421 | }
422 |
423 | dbg ("found timestamp %s for macid=%s\n", timestamp, macid);
424 | ts = strtoul (timestamp, &end, 10);
425 | if (*end != '\0') {
426 | macid = NULL;
427 | timestamp = NULL;
428 | continue;
429 | }
430 |
431 | if (ts > final_ts)
432 | final_ts = ts;
433 | }
434 |
435 | dbg ("final timestamp = %llu (%s)\n", (unsigned long long) final_ts,
436 | strip_n (ctime_r (&final_ts, timebuf)));
437 |
438 | return final_ts;
439 | }
440 |
441 |
442 | static time_t
443 | get_license_deadline (void)
444 | {
445 | int ret = 0;
446 | struct stat lic_stat = {0, };
447 | static struct stat lic_stat_prev = {0, };
448 | static time_t lic_deadline = 0;
449 | FILE *lfp = NULL;
450 |
451 | /* be symlink friendly */
452 | ret = stat (LICFILE, &lic_stat);
453 | if (ret)
454 | return 0;
455 |
456 | if (lic_stat.st_mtime == lic_stat_prev.st_mtime &&
457 | lic_stat.st_ctime == lic_stat_prev.st_ctime &&
458 | lic_stat.st_ino == lic_stat_prev.st_ino &&
459 | lic_stat.st_dev == lic_stat_prev.st_dev) {
460 | /* nothing changed */
461 | return lic_deadline;
462 | }
463 |
464 | lfp = fopen (LICFILE, "r");
465 | if (!lfp)
466 | return 0;
467 |
468 | ret = is_signed_file (LICFILE);
469 | if (ret != YES) {
470 | fclose (lfp);
471 | return 0;
472 | }
473 |
474 | lic_deadline = license_parse (lfp);
475 | lic_stat_prev = lic_stat;
476 |
477 | fclose (lfp);
478 |
479 | return lic_deadline;
480 | }
481 |
482 |
483 | static time_t
484 | get_latest_deadline (void)
485 | {
486 | time_t def_deadline = 0;
487 | time_t lic_deadline = 0;
488 | time_t deadline = 0;
489 | char timebuf1[64];
490 | char timebuf2[64];
491 |
492 | def_deadline = get_default_deadline ();
493 | lic_deadline = get_license_deadline ();
494 |
495 | dbg ("def_deadline = %s lic_deadline=%s\n",
496 | strip_n (ctime_r (&def_deadline, timebuf1)),
497 | strip_n (ctime_r (&lic_deadline, timebuf2)));
498 |
499 | deadline = MAX (def_deadline, lic_deadline);
500 |
501 | return deadline;
502 | }
503 |
504 |
505 | static void *
506 | bigbro_is_watching (void *data)
507 | {
508 | int can_live = YES;
509 | time_t deadline = -1;
510 | time_t new_deadline = 0;
511 | time_t now = 0;
512 | char timebuf1[64];
513 | char timebuf2[64];
514 |
515 | for (can_live = YES; can_live == YES; sleep (10)) {
516 | new_deadline = get_latest_deadline ();
517 | if (deadline != new_deadline) {
518 | dbg ("updated deadline: %s\n",
519 | strip_n (ctime_r (&new_deadline, timebuf1)));
520 | }
521 | deadline = new_deadline;
522 | now = time (NULL);
523 |
524 | if (deadline < now) {
525 | err ("deadline was: %s, now is: %s\n",
526 | strip_n (ctime_r (&deadline, timebuf1)),
527 | strip_n (ctime_r (&now, timebuf2)));
528 | /* >:) */
529 | break;
530 | }
531 | }
532 |
533 | exit (1);
534 |
535 | return NULL;
536 | }
537 |
538 |
539 | static void
540 | bb_child (void)
541 | {
542 | int ret = 0;
543 |
544 | ret = pthread_create (&protect.bigbro, NULL, bigbro_is_watching, NULL);
545 | if (ret != 0)
546 | protect.bigbro = 0;
547 | }
548 |
549 |
550 | static void
551 | big_brother_kickoff (void)
552 | {
553 | int ret = 0;
554 |
555 | ret = pthread_atfork (NULL, NULL, bb_child);
556 | if (ret != 0) {
557 | dbg ("failed pthread_atfork (%s)\n", strerror (errno));
558 | return;
559 | }
560 |
561 | ret = pthread_create (&protect.bigbro, NULL, bigbro_is_watching, NULL);
562 | if (ret != 0)
563 | protect.bigbro = 0;
564 | }
565 |
566 |
567 | static int is_licensed = -1;
568 |
569 |
570 | static int
571 | is_licensed_prog (void)
572 | {
573 | int i = 0;
574 | const char *symbol = NULL;
575 |
576 |
577 | if (is_licensed == -1) {
578 | for (i = 0; (symbol = licensed_symbols[i]); i++) {
579 | if (dlsym (RTLD_NEXT, symbol) != NULL) {
580 | is_licensed = 1;
581 | break;
582 | }
583 | }
584 |
585 | if (!symbol)
586 | is_licensed = 0;
587 |
588 | if (is_licensed) {
589 | dbg ("found symbol %s -- is a licensed program\n",
590 | symbol);
591 | big_brother_kickoff ();
592 | }
593 | }
594 |
595 | return is_licensed;
596 | }
597 |
598 |
599 | static void
600 | make_licensed_prog (void)
601 | {
602 | if (is_licensed == 1)
603 | return;
604 |
605 | is_licensed = 1;
606 | big_brother_kickoff ();
607 | }
608 |
609 |
610 | static int
611 | is_signed_file (const char *filename)
612 | {
613 | int len = 0;
614 | int ret = 0;
615 | int status = 0;
616 | char cmdbuf[1024];
617 |
618 | len = snprintf (cmdbuf, 1024, "%s/gpgv --keyring %s/pubring.gpg %s >/dev/null 2>&1",
619 | LICDIR, LICDIR, filename);
620 |
621 | if (len >= 1024) {
622 | dbg ("cmd too long (%d)\n", len);
623 | return NO;
624 | }
625 |
626 | status = system (cmdbuf);
627 |
628 | ret = WEXITSTATUS(status);
629 |
630 | dbg ("%s: %d\n", cmdbuf, status);
631 |
632 | if (ret == 0)
633 | return YES;
634 |
635 | return NO;
636 | }
637 |
638 |
639 | static int
640 | __line_has_md5str (const char *line)
641 | {
642 | int i = 0;
643 | int ch = 0;
644 |
645 | for (i = 0; i < 32; i++) {
646 | ch = line[i];
647 | if (!isxdigit (ch))
648 | return NO;
649 | }
650 |
651 | ch = line[i];
652 | if (!isspace (ch))
653 | return NO;
654 |
655 | for (ch = line[i]; (ch = line[i]) && (isspace (ch)); i++);
656 |
657 | for (ch = line[i]; (ch = line[i]); i++)
658 | if (!isascii (ch))
659 | return NO;
660 |
661 | return YES;
662 | }
663 |
664 |
665 | static int
666 | xnum (char ch)
667 | {
668 | int n = 0;
669 |
670 | if (isdigit (ch))
671 | n = (ch - '0');
672 | if (ch >= 'a' && ch <= 'f')
673 | n = (ch - 'a' + 10);
674 | if (ch >= 'A' && ch <= 'F')
675 | n = (ch - 'A' + 10);
676 |
677 | return n;
678 | }
679 |
680 |
681 | static void
682 | md5str_to_md5sum (const char *str, unsigned char *sum)
683 | {
684 | int i = 0;
685 | int j = 0;
686 | int ch = 0;
687 |
688 | for (i = 0; i < 32; i++) {
689 | if (!(i % 2)) {
690 | ch = xnum (str[i]);
691 | continue;
692 | }
693 | ch <<= 4;
694 | ch += xnum (str[i]);
695 |
696 | sum[j] = ch;
697 | j++;
698 | }
699 | }
700 |
701 |
702 |
703 | static int
704 | permits_parse (FILE *fp)
705 | {
706 | struct permit_entry *entry = NULL;
707 | struct permit_entry *next = NULL;
708 | struct permit_entry *head = NULL;
709 | char line[1024];
710 | char *l = NULL;
711 |
712 | while ((l = fgets (line, 1024, fp))) {
713 | if (strlen (l) < 35)
714 | continue;
715 | if (__line_has_md5str (l) != YES)
716 | continue;
717 |
718 | entry = calloc (1, sizeof (*entry));
719 | if (!entry)
720 | goto err;
721 | entry->next = head;
722 | head = entry;
723 |
724 | md5str_to_md5sum (l, entry->md5sum);
725 |
726 | for (l = &line[32]; *l; l++)
727 | if (!isspace (*l))
728 | break;
729 | if (!(*l))
730 | goto err;
731 |
732 | entry->path = strdup (l);
733 | if (!entry->path)
734 | goto err;
735 |
736 | l = strchr (entry->path, '\n');
737 | if (l)
738 | *l = '\0';
739 |
740 | l = strchr (entry->path, '\r');
741 | if (l)
742 | *l = '\0';
743 | }
744 |
745 | protect.permits = head;
746 |
747 | return YES;
748 | err:
749 |
750 | for (entry = head; entry; entry = next) {
751 | next = entry->next;
752 | if (entry->path)
753 | free (entry->path);
754 | free (entry);
755 | }
756 |
757 | return NO;
758 | }
759 |
760 |
761 | static int
762 | permits_load (void)
763 | {
764 | const char *permitfile = NULL;
765 | FILE *permitfp = NULL;
766 | struct stat stbuf;
767 | int ret = 0;
768 |
769 |
770 | if (protect.permits)
771 | return YES;
772 |
773 | permitfile = getenv ("LE_PERMIT");
774 | if (!permitfile)
775 | permitfile = PERMITFILE;
776 |
777 | ret = stat (permitfile, &stbuf);
778 | /* don't care if it is symlink */
779 | if (ret != 0) {
780 | dbg ("%s: %s\n", permitfile, strerror (errno));
781 | return NO;
782 | }
783 |
784 | if (!S_ISREG (stbuf.st_mode)) {
785 | dbg ("%s: Not a regular file\n", permitfile);
786 | return NO;
787 | }
788 |
789 | permitfp = fopen (permitfile, "r");
790 | if (!permitfp) {
791 | dbg ("%s: %s\n", permitfile, strerror (errno));
792 | return NO;
793 | }
794 |
795 | ret = is_signed_file (permitfile);
796 | /* TODO: provide is_signed_fd which uses is_signed_file with
797 | /proc/getpid()/fd/%d as filename
798 | */
799 | if (ret != YES) {
800 | dbg ("%s: signature check failed\n", permitfile);
801 | fclose (permitfp);
802 | return NO;
803 | }
804 |
805 | ret = permits_parse (permitfp);
806 | fclose (permitfp);
807 |
808 | return ret;
809 | }
810 |
811 |
812 | const char *
813 | get_permitted_path (unsigned char md5sum[16])
814 | {
815 | struct permit_entry *entry = NULL;
816 |
817 | for (entry = protect.permits; entry; entry = entry->next) {
818 | if (memcmp (md5sum, entry->md5sum, 16) == 0)
819 | return entry->path;
820 | }
821 |
822 | return NULL;
823 | }
824 |
825 |
826 | static int
827 | is_permitted_renameat (int olddirfd, const char *oldpath,
828 | int newdirfd, const char *newpath)
829 | {
830 | struct stat attempted_dst_stat = {0,};
831 | struct stat permitted_dst_stat = {0,};
832 | struct stat src_stat = {0, };
833 | int ret = 0;
834 | unsigned char md5sum[16];
835 | const char *permitted_path = NULL;
836 |
837 |
838 | ret = fstatat (newdirfd, newpath, &attempted_dst_stat,
839 | AT_SYMLINK_NOFOLLOW);
840 | if (ret != 0)
841 | return NO;
842 |
843 | ret = fstatat (olddirfd, oldpath, &src_stat,
844 | AT_SYMLINK_NOFOLLOW);
845 | if (ret != 0)
846 | return NO;
847 |
848 | if (!S_ISREG (src_stat.st_mode))
849 | return NO;
850 |
851 | ret = libevil_md5sum_file (olddirfd, oldpath, md5sum);
852 | if (ret != 0)
853 | return NO;
854 |
855 | ret = permits_load ();
856 | if (ret != YES)
857 | return NO;
858 |
859 | permitted_path = get_permitted_path (md5sum);
860 | if (!permitted_path)
861 | return NO;
862 |
863 | dbg ("permitted: %s\n", permitted_path);
864 |
865 | ret = lstat (permitted_path, &permitted_dst_stat);
866 | if (ret != 0) {
867 | dbg ("%s: %s\n", permitted_path, strerror (errno));
868 | return NO;
869 | }
870 |
871 | dbg ("cmp p_i=%llu,p_d=%llu a_i=%llu,a_d=%llu\n",
872 | (unsigned long long) (permitted_dst_stat.st_ino),
873 | (unsigned long long) (permitted_dst_stat.st_dev),
874 | (unsigned long long) (attempted_dst_stat.st_ino),
875 | (unsigned long long) (attempted_dst_stat.st_dev));
876 |
877 | if (permitted_dst_stat.st_ino == attempted_dst_stat.st_ino &&
878 | permitted_dst_stat.st_dev == attempted_dst_stat.st_dev)
879 | return YES;
880 |
881 | return NO;
882 | }
883 |
884 |
885 | static int
886 | is_permitted_rename (const char *oldpath, const char *newpath)
887 | {
888 | return is_permitted_renameat (AT_FDCWD, oldpath, AT_FDCWD, newpath);
889 | }
890 |
891 |
892 | int
893 | TRAP (rename, (const char *oldpath, const char *newpath))
894 | {
895 | int ret = 0;
896 |
897 | if (is_licensed_prog ())
898 | goto green;
899 |
900 | if (is_protected_entry (oldpath))
901 | goto red;
902 |
903 | if (!is_protected_entry (newpath))
904 | goto green;
905 |
906 | if (!is_permitted_rename (oldpath, newpath))
907 | goto red;
908 | green:
909 | ret = real_rename (oldpath, newpath);
910 |
911 | return ret;
912 |
913 | red:
914 | errno = EPERM;
915 | return -1;
916 | }
917 |
918 |
919 | int
920 | TRAP (renameat, (int olddirfd, const char *oldpath,
921 | int newdirfd, const char *newpath))
922 | {
923 | int ret = 0;
924 |
925 | if (is_licensed_prog ())
926 | goto green;
927 |
928 | if (is_protected_atentry (olddirfd, oldpath))
929 | goto red;
930 |
931 | if (!is_protected_atentry (newdirfd, newpath))
932 | goto green;
933 |
934 | if (!is_permitted_renameat (olddirfd, oldpath, newdirfd, newpath))
935 | goto red;
936 |
937 | green:
938 | ret = real_renameat (olddirfd, oldpath,
939 | newdirfd, newpath);
940 | return ret;
941 |
942 | red:
943 | errno = EPERM;
944 | return -1;
945 | }
946 |
947 |
948 | int
949 | TRAP (unlink, (const char *pathname))
950 | {
951 | int ret = 0;
952 |
953 | if (is_licensed_prog ())
954 | goto green;
955 |
956 | if (is_protected_entry (pathname))
957 | goto red;
958 |
959 | green:
960 | ret = real_unlink (pathname);
961 |
962 | return ret;
963 |
964 | red:
965 | errno = EPERM;
966 | return -1;
967 | }
968 |
969 |
970 | int
971 | TRAP (unlinkat, (int dirfd, const const char *pathname, int flags))
972 | {
973 | int ret = 0;
974 |
975 | if (is_licensed_prog ())
976 | goto green;
977 |
978 | if (is_protected_atentry (dirfd, pathname))
979 | goto red;
980 |
981 | green:
982 | ret = real_unlinkat (dirfd, pathname, flags);
983 |
984 | return ret;
985 |
986 | red:
987 | errno = EPERM;
988 | return -1;
989 | }
990 |
991 |
992 | int
993 | TRAP (remove, (const char *pathname))
994 | {
995 | int ret = 0;
996 |
997 | if (is_licensed_prog ())
998 | goto green;
999 |
1000 | if (is_protected_entry (pathname))
1001 | goto red;
1002 |
1003 | green:
1004 | ret = real_remove (pathname);
1005 |
1006 | return ret;
1007 |
1008 | red:
1009 | errno = EPERM;
1010 | return -1;
1011 | }
1012 |
1013 |
1014 | int
1015 | TRAP (truncate, (const char *path, off_t length))
1016 | {
1017 | int ret = 0;
1018 |
1019 | if (is_licensed_prog ())
1020 | goto green;
1021 |
1022 | if (is_protected_file (path))
1023 | goto red;
1024 |
1025 | green:
1026 | ret = real_truncate (path, length);
1027 |
1028 | return ret;
1029 |
1030 | red:
1031 | errno = EPERM;
1032 | return -1;
1033 | }
1034 |
1035 |
1036 | int
1037 | TRAP (truncate64, (const char *path, off_t length))
1038 | {
1039 | int ret = 0;
1040 |
1041 | if (is_licensed_prog ())
1042 | goto green;
1043 |
1044 | if (is_protected_file (path))
1045 | goto red;
1046 |
1047 | green:
1048 | ret = real_truncate64 (path, length);
1049 |
1050 | return ret;
1051 |
1052 | red:
1053 | errno = EPERM;
1054 | return -1;
1055 | }
1056 |
1057 |
1058 | int
1059 | TRAP (open, (const char *path, int flags, mode_t mode))
1060 | {
1061 | int ret = 0;
1062 |
1063 | if (is_licensed_prog ())
1064 | goto green;
1065 |
1066 | if (!is_protected_file (path))
1067 | goto green;
1068 |
1069 | if ((flags & O_ACCMODE) != O_RDONLY)
1070 | goto red;
1071 |
1072 | green:
1073 | ret = real_open (path, flags, mode);
1074 |
1075 | return ret;
1076 |
1077 | red:
1078 | errno = EPERM;
1079 | return -1;
1080 | }
1081 |
1082 |
1083 | int
1084 | TRAP (openat, (int dirfd, const char *path, int flags, mode_t mode))
1085 | {
1086 | int ret = 0;
1087 |
1088 | if (is_licensed_prog ())
1089 | goto green;
1090 |
1091 | if (!is_protected_atfile (dirfd, path))
1092 | goto green;
1093 |
1094 | if ((flags & O_ACCMODE) != O_RDONLY)
1095 | goto red;
1096 |
1097 | green:
1098 | ret = real_openat (dirfd, path, flags, mode);
1099 |
1100 | return ret;
1101 |
1102 | red:
1103 | errno = EPERM;
1104 | return -1;
1105 | }
1106 |
1107 |
1108 | int
1109 | TRAP (creat, (const char *path, mode_t mode))
1110 | {
1111 | int ret = 0;
1112 |
1113 | if (is_licensed_prog ())
1114 | goto green;
1115 |
1116 | if (is_protected_file (path))
1117 | goto red;
1118 |
1119 | green:
1120 | ret = real_creat (path, mode);
1121 |
1122 | return ret;
1123 |
1124 | red:
1125 | errno = EPERM;
1126 | return -1;
1127 | }
1128 |
1129 |
1130 | int
1131 | TRAP (chmod, (const char *path, mode_t mode))
1132 | {
1133 | int ret = 0;
1134 |
1135 | if (is_licensed_prog ())
1136 | goto green;
1137 |
1138 | if (is_protected_file (path))
1139 | goto red;
1140 |
1141 | green:
1142 | ret = real_chmod (path, mode);
1143 |
1144 | return ret;
1145 |
1146 | red:
1147 | errno = EPERM;
1148 | return -1;
1149 | }
1150 |
1151 |
1152 | int
1153 | TRAP (fchmod, (int fd, mode_t mode))
1154 | {
1155 | int ret = 0;
1156 |
1157 | if (is_licensed_prog ())
1158 | goto green;
1159 |
1160 | if (is_protected_fd (fd))
1161 | goto red;
1162 |
1163 | green:
1164 | ret = real_fchmod (fd, mode);
1165 |
1166 | return ret;
1167 |
1168 | red:
1169 | errno = EPERM;
1170 | return -1;
1171 | }
1172 |
1173 |
1174 | int
1175 | TRAP (fchmodat, (int dirfd, const char *path, mode_t mode, int flags))
1176 | {
1177 | int ret = 0;
1178 |
1179 | if (is_licensed_prog ())
1180 | goto green;
1181 |
1182 | if (flags & AT_SYMLINK_NOFOLLOW) {
1183 | if (is_protected_atentry (dirfd, path))
1184 | goto red;
1185 | } else {
1186 | if (is_protected_atfile (dirfd, path))
1187 | goto red;
1188 | }
1189 |
1190 | green:
1191 | ret = real_fchmodat (dirfd, path, mode, flags);
1192 |
1193 | return ret;
1194 |
1195 | red:
1196 | errno = EPERM;
1197 | return -1;
1198 | }
1199 |
1200 |
1201 | int
1202 | TRAP (chown, (const char *path, uid_t uid, gid_t gid))
1203 | {
1204 | int ret = 0;
1205 |
1206 | if (is_licensed_prog ())
1207 | goto green;
1208 |
1209 | if (is_protected_file (path))
1210 | goto red;
1211 |
1212 | green:
1213 | ret = real_chown (path, uid, gid);
1214 |
1215 | return ret;
1216 |
1217 | red:
1218 | errno = EPERM;
1219 | return -1;
1220 | }
1221 |
1222 |
1223 | int
1224 | TRAP (lchown, (const char *path, uid_t uid, gid_t gid))
1225 | {
1226 | int ret = 0;
1227 |
1228 | if (is_licensed_prog ())
1229 | goto green;
1230 |
1231 | if (is_protected_entry (path))
1232 | goto red;
1233 |
1234 | green:
1235 | ret = real_lchown (path, uid, gid);
1236 |
1237 | return ret;
1238 |
1239 | red:
1240 | errno = EPERM;
1241 | return -1;
1242 | }
1243 |
1244 |
1245 | int
1246 | TRAP (fchown, (int fd, uid_t uid, gid_t gid))
1247 | {
1248 | int ret = 0;
1249 |
1250 | if (is_licensed_prog ())
1251 | goto green;
1252 |
1253 | if (is_protected_fd (fd))
1254 | goto red;
1255 |
1256 | green:
1257 | ret = real_fchown (fd, uid, gid);
1258 |
1259 | return ret;
1260 |
1261 | red:
1262 | errno = EPERM;
1263 | return -1;
1264 | }
1265 |
1266 |
1267 | int
1268 | TRAP (fchownat, (int dirfd, const char *path, uid_t uid, gid_t gid, int flags))
1269 | {
1270 | int ret = 0;
1271 |
1272 | if (is_licensed_prog ())
1273 | goto green;
1274 |
1275 | if (flags & AT_SYMLINK_NOFOLLOW) {
1276 | if (is_protected_atentry (dirfd, path))
1277 | goto red;
1278 | } else {
1279 | if (is_protected_atfile (dirfd, path))
1280 | goto red;
1281 | }
1282 |
1283 | green:
1284 | ret = real_fchownat (dirfd, path, uid, gid, flags);
1285 |
1286 | return ret;
1287 | red:
1288 | errno = EPERM;
1289 | return -1;
1290 | }
1291 |
1292 |
1293 | int
1294 | TRAP (utime, (const char *filename, const struct utimbuf *times))
1295 | {
1296 | int ret = 0;
1297 |
1298 | if (is_licensed_prog ())
1299 | goto green;
1300 |
1301 | if (is_protected_file (filename))
1302 | goto red;
1303 |
1304 | green:
1305 | ret = real_utime (filename, times);
1306 |
1307 | return ret;
1308 | red:
1309 | errno = EPERM;
1310 | return -1;
1311 | }
1312 |
1313 |
1314 | int
1315 | TRAP (utimes, (const char *filename, const struct timeval times[2]))
1316 | {
1317 | int ret = 0;
1318 |
1319 | if (is_licensed_prog ())
1320 | goto green;
1321 |
1322 | if (is_protected_file (filename))
1323 | goto red;
1324 |
1325 | green:
1326 | ret = real_utimes (filename, times);
1327 |
1328 | return ret;
1329 | red:
1330 | errno = EPERM;
1331 | return -1;
1332 | }
1333 |
1334 |
1335 | int
1336 | TRAP (utimensat, (int dirfd, const char *pathname,
1337 | const struct timespec times[2], int flags))
1338 | {
1339 | int ret = 0;
1340 |
1341 | if (is_licensed_prog ())
1342 | goto green;
1343 |
1344 | if (flags & AT_SYMLINK_NOFOLLOW) {
1345 | if (is_protected_atentry (dirfd, pathname))
1346 | goto red;
1347 | } else {
1348 | if (is_protected_atfile (dirfd, pathname))
1349 | goto red;
1350 | }
1351 | green:
1352 | ret = real_utimensat (dirfd, pathname, times, flags);
1353 |
1354 | return ret;
1355 | red:
1356 | errno = EPERM;
1357 | return -1;
1358 | }
1359 |
1360 |
1361 | int
1362 | TRAP (futimesat, (int dirfd, const char *pathname,
1363 | const struct timeval times[2]))
1364 | {
1365 | int ret = 0;
1366 |
1367 | if (is_licensed_prog ())
1368 | goto green;
1369 |
1370 | if (is_protected_atfile (dirfd, pathname))
1371 | goto red;
1372 |
1373 | green:
1374 | ret = real_futimesat (dirfd, pathname, times);
1375 |
1376 | return ret;
1377 | red:
1378 | errno = EPERM;
1379 | return -1;
1380 | }
1381 |
1382 |
1383 | int
1384 | TRAP (mount, (const char *source, const char *target,
1385 | const char *filesystemtype, unsigned long mountflags,
1386 | const void *data))
1387 | {
1388 | int ret = 0;
1389 |
1390 | if (is_licensed_prog ())
1391 | goto green;
1392 |
1393 | if (is_protected_file (target))
1394 | goto red;
1395 |
1396 | /* no need to check @source for mount --bind since st_ino/st_dev
1397 | are preserved in namespace bind mounts
1398 | */
1399 |
1400 | green:
1401 | ret = real_mount (source, target, filesystemtype, mountflags, data);
1402 |
1403 | return ret;
1404 | red:
1405 | errno = EPERM;
1406 | return -1;
1407 | }
1408 |
1409 |
1410 | int
1411 | TRAP (pivot_root, (const char *new_root, const char *old_put))
1412 | {
1413 | /* blanket disable */
1414 | errno = EPERM;
1415 | return -1;
1416 | #if 0
1417 | int ret = 0;
1418 |
1419 | ret = real_pivot_root (new_root, old_put);
1420 |
1421 | return ret;
1422 | #endif
1423 | }
1424 |
1425 |
1426 | int
1427 | TRAP (chroot, (const char *path))
1428 | {
1429 | int ret = 0;
1430 |
1431 | ret = real_chroot (path);
1432 |
1433 | return ret;
1434 | }
1435 |
1436 |
1437 | int
1438 | TRAP (ptrace, (enum __ptrace_request request, pid_t pid,
1439 | void *addr, void *data))
1440 | {
1441 | int ret = 0;
1442 |
1443 | ret = real_ptrace (request, pid, addr, data);
1444 |
1445 | return ret;
1446 | }
1447 |
1448 |
1449 | int
1450 | TRAP (execve, (const char *filename, const char *argv[], const char *envp[]))
1451 | {
1452 | int ret = 0;
1453 |
1454 | unsetenv ("LD_PRELOAD");
1455 | ret = real_execve (filename, argv, envp);
1456 |
1457 | return ret;
1458 | }
1459 |
1460 |
1461 | int
1462 | TRAP (epoll_create, (int flags))
1463 | {
1464 | int ret = 0;
1465 |
1466 | make_licensed_prog ();
1467 |
1468 | ret = real_epoll_create (flags);
1469 |
1470 | return ret;
1471 | }
1472 |
1473 |
1474 | int
1475 | TRAP (epoll_create1, (int flags))
1476 | {
1477 | int ret = 0;
1478 |
1479 | make_licensed_prog ();
1480 |
1481 | ret = real_epoll_create1 (flags);
1482 |
1483 | return ret;
1484 | }
1485 |
1486 |
1487 | static void
1488 | create_epoch (void)
1489 | {
1490 | FILE *ep = NULL;
1491 | FILE *def = NULL;
1492 | int ret = 0;
1493 | int randfd = -1;
1494 | int i = 0;
1495 | unsigned char randbytes[16];
1496 | struct stat stbuf = {0, };
1497 |
1498 |
1499 | if (lstat (EPOCH_FILE, &stbuf) == 0 && stbuf.st_size != 0)
1500 | goto read;
1501 |
1502 | ep = fopen (EPOCH_FILE, "w+");
1503 | if (!ep)
1504 | return;
1505 |
1506 | randfd = open ("/dev/urandom", O_RDONLY);
1507 | if (randfd == -1)
1508 | randfd = open ("/dev/random", O_RDONLY);
1509 |
1510 | if (randfd == -1) {
1511 | fclose (ep);
1512 | return;
1513 | }
1514 |
1515 | ret = read (randfd, randbytes, sizeof (randbytes));
1516 | if (ret != sizeof (randbytes)) {
1517 | fclose (ep);
1518 | close (randfd);
1519 | return;
1520 | }
1521 |
1522 | for (i = 0; i < 16; i++) {
1523 | fprintf (ep, "%02x", randbytes[i]);
1524 | if (i == 3 || i == 5 || i == 7 || i == 9)
1525 | fprintf (ep, "-");
1526 | }
1527 | fprintf (ep, "\n");
1528 |
1529 | fclose (ep);
1530 | close (randfd);
1531 |
1532 | read:
1533 | ep = fopen (EPOCH_FILE, "r");
1534 | ret = fscanf (ep, "%s", protect.macid);
1535 | fclose (ep);
1536 |
1537 | def = fopen (DEFAULT_FILE, "r");
1538 | if (def) {
1539 | ret = fscanf (def, "%ld", &default_timeout);
1540 | fclose (def);
1541 | }
1542 | if (!default_timeout)
1543 | default_timeout = DAYS(30);
1544 | }
1545 |
1546 |
1547 | static void libevil_init (void) __attribute__((constructor));
1548 |
1549 |
1550 | static void
1551 | libevil_init (void)
1552 | {
1553 | dbg_init ();
1554 |
1555 | create_epoch ();
1556 |
1557 | prepare_glob ();
1558 |
1559 | return;
1560 | }
1561 |
1562 |
--------------------------------------------------------------------------------
/libevil.h:
--------------------------------------------------------------------------------
1 |
2 | #ifndef _LIBEVIL_H
3 | #define _LIBEVIL_H
4 |
5 |
6 | #define __cons __attribute__((constructor))
7 |
8 | #define TRAP(func, params) \
9 | evil_##func params; \
10 | static int (*real_##func) params; \
11 | static void set_real_##func (void) __cons; \
12 | static void set_real_##func (void) \
13 | { real_##func = dlsym (RTLD_NEXT, #func); } \
14 | int __REDIRECT (evil_##func, params, func); \
15 | int evil_##func params
16 |
17 |
18 | enum {
19 | NO = 0,
20 | YES = 1
21 | };
22 |
23 | #define EPOCH_FILE "/.epoch"
24 | #define DEFAULT_FILE "/.default"
25 | #define LICDIR "/lic"
26 | #define PERMITFILE LICDIR "/permit.asc"
27 | #define LICFILE LICDIR "/license.asc"
28 |
29 | #define MAX(a,b) ( (a) > (b) ? (a) : (b) )
30 |
31 | #define SECS(x) (x)
32 | #define MINS(x) (x * SECS(60))
33 | #define HOURS(x) (x * MINS(60))
34 | #define DAYS(x) (x * HOURS(24))
35 |
36 | #endif /* !_LIBEVIL_H */
37 |
--------------------------------------------------------------------------------
/md5.c:
--------------------------------------------------------------------------------
1 | /*
2 | * RFC 1321 compliant MD5 implementation
3 | *
4 | * Copyright (C) 2001-2003 Christophe Devine
5 | *
6 | * This program is free software; you can redistribute it and/or modify
7 | * it under the terms of the GNU General Public License as published by
8 | * the Free Software Foundation; either version 3 of the License, or
9 | * (at your option) any later version.
10 | *
11 | * This program is distributed in the hope that it will be useful,
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | * GNU General Public License for more details.
15 | *
16 | * You should have received a copy of the GNU General Public License along
17 | * with this program; if not, visit the http://fsf.org website.
18 | */
19 |
20 | /* rsync-3.0.6/byteorder.h */
21 |
22 | /*
23 | * Simple byteorder handling.
24 | *
25 | * Copyright (C) 1992-1995 Andrew Tridgell
26 | * Copyright (C) 2007-2008 Wayne Davison
27 | *
28 | * This program is free software; you can redistribute it and/or modify
29 | * it under the terms of the GNU General Public License as published by
30 | * the Free Software Foundation; either version 3 of the License, or
31 | * (at your option) any later version.
32 | *
33 | * This program is distributed in the hope that it will be useful,
34 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
35 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
36 | * GNU General Public License for more details.
37 | *
38 | * You should have received a copy of the GNU General Public License along
39 | * with this program; if not, visit the http://fsf.org website.
40 | */
41 |
42 |
43 | #include
44 | #include
45 | #include
46 | #include
47 | #include
48 |
49 |
50 | #undef CAREFUL_ALIGNMENT
51 |
52 | /* We know that the x86 can handle misalignment and has the same
53 | * byte order (LSB-first) as the 32-bit numbers we transmit. */
54 |
55 | #ifdef __i386__
56 | #define CAREFUL_ALIGNMENT 0
57 | #endif
58 |
59 | #ifndef CAREFUL_ALIGNMENT
60 | #define CAREFUL_ALIGNMENT 1
61 | #endif
62 |
63 | #define CVAL(buf,pos) (((unsigned char *)(buf))[pos])
64 | #define UVAL(buf,pos) ((uint32_t)CVAL(buf,pos))
65 | #define SCVAL(buf,pos,val) (CVAL(buf,pos) = (val))
66 |
67 | #if CAREFUL_ALIGNMENT
68 | #define PVAL(buf,pos) (UVAL(buf,pos)|UVAL(buf,(pos)+1)<<8)
69 | #define IVAL(buf,pos) (PVAL(buf,pos)|PVAL(buf,(pos)+2)<<16)
70 | #define SSVALX(buf,pos,val) (CVAL(buf,pos)=(val)&0xFF,CVAL(buf,pos+1)=(val)>>8)
71 | #define SIVALX(buf,pos,val) (SSVALX(buf,pos,val&0xFFFF),SSVALX(buf,pos+2,val>>16))
72 | #define SIVAL(buf,pos,val) SIVALX((buf),(pos),((uint32_t)(val)))
73 | #else
74 |
75 | /* this handles things for architectures like the 386 that can handle
76 | alignment errors */
77 |
78 | /*
79 | WARNING: This section is dependent on the length of int32
80 | being correct. set CAREFUL_ALIGNMENT if it is not.
81 | */
82 |
83 | #define IVAL(buf,pos) (*(uint32_t *)((char *)(buf) + (pos)))
84 | #define SIVAL(buf,pos,val) IVAL(buf,pos)=((uint32_t)(val))
85 | #endif
86 |
87 | /* The include file for both the MD4 and MD5 routines. */
88 |
89 | #define MD5_DIGEST_LEN 16
90 | #define MAX_DIGEST_LEN MD5_DIGEST_LEN
91 |
92 | #define CSUM_CHUNK 64
93 |
94 |
95 | typedef struct {
96 | uint32_t A, B, C, D;
97 | uint32_t totalN; /* bit count, lower 32 bits */
98 | uint32_t totalN2; /* bit count, upper 32 bits */
99 | uint8_t buffer[CSUM_CHUNK];
100 | } md_context;
101 |
102 | static void md5_begin(md_context *ctx);
103 | static void md5_update(md_context *ctx, const uint8_t *input, uint32_t length);
104 | static void md5_result(md_context *ctx, uint8_t digest[MD5_DIGEST_LEN]);
105 |
106 |
107 | static void md5_begin(md_context *ctx)
108 | {
109 | ctx->A = 0x67452301;
110 | ctx->B = 0xEFCDAB89;
111 | ctx->C = 0x98BADCFE;
112 | ctx->D = 0x10325476;
113 |
114 | ctx->totalN = ctx->totalN2 = 0;
115 | }
116 |
117 | static void md5_process(md_context *ctx, const uint8_t data[CSUM_CHUNK])
118 | {
119 | uint32_t X[16], A, B, C, D;
120 |
121 | A = ctx->A;
122 | B = ctx->B;
123 | C = ctx->C;
124 | D = ctx->D;
125 |
126 | X[0] = IVAL(data, 0);
127 | X[1] = IVAL(data, 4);
128 | X[2] = IVAL(data, 8);
129 | X[3] = IVAL(data, 12);
130 | X[4] = IVAL(data, 16);
131 | X[5] = IVAL(data, 20);
132 | X[6] = IVAL(data, 24);
133 | X[7] = IVAL(data, 28);
134 | X[8] = IVAL(data, 32);
135 | X[9] = IVAL(data, 36);
136 | X[10] = IVAL(data, 40);
137 | X[11] = IVAL(data, 44);
138 | X[12] = IVAL(data, 48);
139 | X[13] = IVAL(data, 52);
140 | X[14] = IVAL(data, 56);
141 | X[15] = IVAL(data, 60);
142 |
143 | #define S(x,n) ((x << n) | ((x & 0xFFFFFFFF) >> (32 - n)))
144 |
145 | #define P(a,b,c,d,k,s,t) a += F(b,c,d) + X[k] + t, a = S(a,s) + b
146 |
147 | #define F(x,y,z) (z ^ (x & (y ^ z)))
148 |
149 | P(A, B, C, D, 0, 7, 0xD76AA478);
150 | P(D, A, B, C, 1, 12, 0xE8C7B756);
151 | P(C, D, A, B, 2, 17, 0x242070DB);
152 | P(B, C, D, A, 3, 22, 0xC1BDCEEE);
153 | P(A, B, C, D, 4, 7, 0xF57C0FAF);
154 | P(D, A, B, C, 5, 12, 0x4787C62A);
155 | P(C, D, A, B, 6, 17, 0xA8304613);
156 | P(B, C, D, A, 7, 22, 0xFD469501);
157 | P(A, B, C, D, 8, 7, 0x698098D8);
158 | P(D, A, B, C, 9, 12, 0x8B44F7AF);
159 | P(C, D, A, B, 10, 17, 0xFFFF5BB1);
160 | P(B, C, D, A, 11, 22, 0x895CD7BE);
161 | P(A, B, C, D, 12, 7, 0x6B901122);
162 | P(D, A, B, C, 13, 12, 0xFD987193);
163 | P(C, D, A, B, 14, 17, 0xA679438E);
164 | P(B, C, D, A, 15, 22, 0x49B40821);
165 |
166 | #undef F
167 | #define F(x,y,z) (y ^ (z & (x ^ y)))
168 |
169 | P(A, B, C, D, 1, 5, 0xF61E2562);
170 | P(D, A, B, C, 6, 9, 0xC040B340);
171 | P(C, D, A, B, 11, 14, 0x265E5A51);
172 | P(B, C, D, A, 0, 20, 0xE9B6C7AA);
173 | P(A, B, C, D, 5, 5, 0xD62F105D);
174 | P(D, A, B, C, 10, 9, 0x02441453);
175 | P(C, D, A, B, 15, 14, 0xD8A1E681);
176 | P(B, C, D, A, 4, 20, 0xE7D3FBC8);
177 | P(A, B, C, D, 9, 5, 0x21E1CDE6);
178 | P(D, A, B, C, 14, 9, 0xC33707D6);
179 | P(C, D, A, B, 3, 14, 0xF4D50D87);
180 | P(B, C, D, A, 8, 20, 0x455A14ED);
181 | P(A, B, C, D, 13, 5, 0xA9E3E905);
182 | P(D, A, B, C, 2, 9, 0xFCEFA3F8);
183 | P(C, D, A, B, 7, 14, 0x676F02D9);
184 | P(B, C, D, A, 12, 20, 0x8D2A4C8A);
185 |
186 | #undef F
187 | #define F(x,y,z) (x ^ y ^ z)
188 |
189 | P(A, B, C, D, 5, 4, 0xFFFA3942);
190 | P(D, A, B, C, 8, 11, 0x8771F681);
191 | P(C, D, A, B, 11, 16, 0x6D9D6122);
192 | P(B, C, D, A, 14, 23, 0xFDE5380C);
193 | P(A, B, C, D, 1, 4, 0xA4BEEA44);
194 | P(D, A, B, C, 4, 11, 0x4BDECFA9);
195 | P(C, D, A, B, 7, 16, 0xF6BB4B60);
196 | P(B, C, D, A, 10, 23, 0xBEBFBC70);
197 | P(A, B, C, D, 13, 4, 0x289B7EC6);
198 | P(D, A, B, C, 0, 11, 0xEAA127FA);
199 | P(C, D, A, B, 3, 16, 0xD4EF3085);
200 | P(B, C, D, A, 6, 23, 0x04881D05);
201 | P(A, B, C, D, 9, 4, 0xD9D4D039);
202 | P(D, A, B, C, 12, 11, 0xE6DB99E5);
203 | P(C, D, A, B, 15, 16, 0x1FA27CF8);
204 | P(B, C, D, A, 2, 23, 0xC4AC5665);
205 |
206 | #undef F
207 | #define F(x,y,z) (y ^ (x | ~z))
208 |
209 | P(A, B, C, D, 0, 6, 0xF4292244);
210 | P(D, A, B, C, 7, 10, 0x432AFF97);
211 | P(C, D, A, B, 14, 15, 0xAB9423A7);
212 | P(B, C, D, A, 5, 21, 0xFC93A039);
213 | P(A, B, C, D, 12, 6, 0x655B59C3);
214 | P(D, A, B, C, 3, 10, 0x8F0CCC92);
215 | P(C, D, A, B, 10, 15, 0xFFEFF47D);
216 | P(B, C, D, A, 1, 21, 0x85845DD1);
217 | P(A, B, C, D, 8, 6, 0x6FA87E4F);
218 | P(D, A, B, C, 15, 10, 0xFE2CE6E0);
219 | P(C, D, A, B, 6, 15, 0xA3014314);
220 | P(B, C, D, A, 13, 21, 0x4E0811A1);
221 | P(A, B, C, D, 4, 6, 0xF7537E82);
222 | P(D, A, B, C, 11, 10, 0xBD3AF235);
223 | P(C, D, A, B, 2, 15, 0x2AD7D2BB);
224 | P(B, C, D, A, 9, 21, 0xEB86D391);
225 |
226 | #undef F
227 |
228 | ctx->A += A;
229 | ctx->B += B;
230 | ctx->C += C;
231 | ctx->D += D;
232 | }
233 |
234 | static void md5_update(md_context *ctx, const uint8_t *input, uint32_t length)
235 | {
236 | uint32_t left, fill;
237 |
238 | if (!length)
239 | return;
240 |
241 | left = ctx->totalN & 0x3F;
242 | fill = CSUM_CHUNK - left;
243 |
244 | ctx->totalN += length;
245 | ctx->totalN &= 0xFFFFFFFF;
246 |
247 | if (ctx->totalN < length)
248 | ctx->totalN2++;
249 |
250 | if (left && length >= fill) {
251 | memcpy(ctx->buffer + left, input, fill);
252 | md5_process(ctx, ctx->buffer);
253 | length -= fill;
254 | input += fill;
255 | left = 0;
256 | }
257 |
258 | while (length >= CSUM_CHUNK) {
259 | md5_process(ctx, input);
260 | length -= CSUM_CHUNK;
261 | input += CSUM_CHUNK;
262 | }
263 |
264 | if (length)
265 | memcpy(ctx->buffer + left, input, length);
266 | }
267 |
268 | static uint8_t md5_padding[CSUM_CHUNK] = { 0x80 };
269 |
270 | static void md5_result(md_context *ctx, uint8_t digest[MD5_DIGEST_LEN])
271 | {
272 | uint32_t last, padn;
273 | uint32_t high, low;
274 | uint8_t msglen[8];
275 |
276 | high = (ctx->totalN >> 29)
277 | | (ctx->totalN2 << 3);
278 | low = (ctx->totalN << 3);
279 |
280 | SIVAL(msglen, 0, low);
281 | SIVAL(msglen, 4, high);
282 |
283 | last = ctx->totalN & 0x3F;
284 | padn = last < 56 ? 56 - last : 120 - last;
285 |
286 | md5_update(ctx, md5_padding, padn);
287 | md5_update(ctx, msglen, 8);
288 |
289 | SIVAL(digest, 0, ctx->A);
290 | SIVAL(digest, 4, ctx->B);
291 | SIVAL(digest, 8, ctx->C);
292 | SIVAL(digest, 12, ctx->D);
293 | }
294 |
295 |
296 | static void libevil_md5sum_fd (int fd, uint8_t *out)
297 | {
298 | int i = 0;
299 | md_context ctx;
300 | uint8_t buf[1024];
301 |
302 | md5_begin(&ctx);
303 |
304 | while ((i = read (fd, buf, sizeof buf)) > 0)
305 | md5_update(&ctx, buf, i);
306 |
307 | md5_result(&ctx, out);
308 | }
309 |
310 |
311 | static int libevil_md5sum_file (int dirfd, const char *path, uint8_t *out)
312 | {
313 | int fd = -1;
314 |
315 | fd = openat (dirfd, path, O_RDONLY, 0);
316 |
317 | if (fd < 0)
318 | return -errno;
319 |
320 | libevil_md5sum_fd (fd, out);
321 |
322 | close (fd);
323 | return 0;
324 | }
325 |
--------------------------------------------------------------------------------
/md5.h:
--------------------------------------------------------------------------------
1 | #ifndef _MD5_H
2 | #define _MD5_H
3 |
4 | #include
5 |
6 | int libevil_md5sum_file (int dirfd, const char *path, uint8_t *out);
7 | void libevil_md5sum_fd (int fd, uint8_t *out);
8 |
9 | #endif /* ! _MD5_H */
10 |
--------------------------------------------------------------------------------
/permits-create.sh.in:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | prefix=@prefix@;
4 | exec_prefix=@exec_prefix@;
5 | sysconfdir=@sysconfdir@;
6 | bindir=@bindir@;
7 | libdir=@libdir@;
8 |
9 |
10 | function md5_entry ()
11 | {
12 | local file="$1";
13 | local name="$2";
14 | local md5="d41d8cd98f00b204e9800998ecf8427e";
15 |
16 | if [ -e "$file" ]; then
17 | md5=$(md5sum "$file" | cut -f1 -d' ');
18 | fi
19 |
20 | echo "$md5 $name";
21 | }
22 |
23 |
24 | function create_permits_lsr ()
25 | {
26 | local buildroot="$1";
27 |
28 | md5_entry "${buildroot}/@bindir@/gpgv" "/lic/gpgv";
29 | md5_entry "${buildroot}/@libdir@/libevil.so" "/$(basename @libdir@)/libevil${bits}.so";
30 | md5_entry "${buildroot}/@sysconfdir@/pubring.gpg" "/lic/pubring.gpg";
31 | }
32 |
33 |
34 | function sign ()
35 | {
36 | local permitfile="$1";
37 |
38 | mkdir -p $(dirname "$permitfile");
39 | gpg --output "$permitfile" --clearsign;
40 | }
41 |
42 |
43 | function main ()
44 | {
45 | local buildroot="$1";
46 |
47 | bits=$(file "${buildroot}/@libdir@/libevil.so" | sed -n 's/.* \([^ ]*\)-bit .*/\1/pg' | head -n 1);
48 |
49 | create_permits_lsr "$buildroot" | sign "${buildroot}/"@sysconfdir@/permits${bits}.asc;
50 | }
51 |
52 |
53 | main "$@";
54 |
--------------------------------------------------------------------------------
/permits-install.sh.in:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 |
4 | prefix=@prefix@;
5 | exec_prefix=@exec_prefix@;
6 | sysconfdir=@sysconfdir@;
7 | bindir=@bindir@;
8 | libdir=@libdir@;
9 |
10 |
11 | function replace_file ()
12 | {
13 | local src="$1";
14 | local dst="$2";
15 |
16 | if [ ! -e "$src" ]; then
17 | return;
18 | fi
19 |
20 | mkdir -p $(dirname "$dst");
21 | cp -a "$src" /tmp/lictmp;
22 | mv /tmp/lictmp "$dst" 2>/dev/null; # magic
23 | }
24 |
25 |
26 | function replace_files ()
27 | {
28 | local bits=$(file "${buildroot}/@libdir@/libevil.so" | sed -n 's/.* \([^ ]*\)-bit .*/\1/pg' | head -n 1);
29 | chown root:root "${buildroot}/@libdir@/libevil.so";
30 | chmod g+s "${buildroot}/@libdir@/libevil.so";
31 |
32 | replace_file "${buildroot}/@bindir@/gpgv" "/lic/gpgv";
33 | replace_file "${buildroot}/@libdir@/libevil.so" "/$(basename @libdir@)/libevil${bits}.so";
34 | replace_file "${buildroot}/@sysconfdir@/pubring.gpg" "/lic/pubring.gpg";
35 | }
36 |
37 |
38 | function main ()
39 | {
40 | bits=$(file "${buildroot}/@libdir@/libevil.so" | sed -n 's/.* \([^ ]*\)-bit .*/\1/pg' | head -n 1);
41 |
42 | export LE_PERMIT=@sysconfdir@/permits${bits}.asc;
43 |
44 | replace_files;
45 | }
46 |
47 | main "$@";
48 |
--------------------------------------------------------------------------------
/pubring.gpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/avati/libevil/0ae9450e42f04a7ac9bc3a1ca0e6956268efbc4d/pubring.gpg
--------------------------------------------------------------------------------