pax_global_header00006660000000000000000000000064137011164250014512gustar00rootroot0000000000000052 comment=cb3bb194cca88211cbfcdde2f10c0f43c3fb8ec3 keyutils-1.6.3/000077500000000000000000000000001370111642500133725ustar00rootroot00000000000000keyutils-1.6.3/.gitignore000066400000000000000000000001261370111642500153610ustar00rootroot00000000000000*~ *.o *.os *.so *.a *.so.* /keyctl /request-key /key.dns_resolver /rpmbuild test.out keyutils-1.6.3/LICENCE.GPL000066400000000000000000000431151370111642500150040ustar00rootroot00000000000000 GNU GENERAL PUBLIC LICENSE Version 2, June 1991 Copyright (C) 1989, 1991 Free Software Foundation, Inc. 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This General Public License applies to most of the Free Software Foundation's software and to any other program whose authors commit to using it. (Some other Free Software Foundation software is covered by the GNU Library General Public License instead.) You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs; and that you know you can do these things. To protect your rights, we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights. These restrictions translate to certain responsibilities for you if you distribute copies of the software, or if you modify it. For example, if you distribute copies of such a program, whether gratis or for a fee, you must give the recipients all the rights that you have. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. We protect your rights with two steps: (1) copyright the software, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the software. Also, for each author's protection and ours, we want to make certain that everyone understands that there is no warranty for this free software. If the software is modified by someone else and passed on, we want its recipients to know that what they have is not the original, so that any problems introduced by others will not reflect on the original authors' reputations. Finally, any free program is threatened constantly by software patents. We wish to avoid the danger that redistributors of a free program will individually obtain patent licenses, in effect making the program proprietary. To prevent this, we have made it clear that any patent must be licensed for everyone's free use or not licensed at all. The precise terms and conditions for copying, distribution and modification follow. GNU GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License applies to any program or other work which contains a notice placed by the copyright holder saying it may be distributed under the terms of this General Public License. The "Program", below, refers to any such program or work, and a "work based on the Program" means either the Program or any derivative work under copyright law: that is to say, a work containing the Program or a portion of it, either verbatim or with modifications and/or translated into another language. (Hereinafter, translation is included without limitation in the term "modification".) Each licensee is addressed as "you". Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running the Program is not restricted, and the output from the Program is covered only if its contents constitute a work based on the Program (independent of having been made by running the Program). Whether that is true depends on what the Program does. 1. You may copy and distribute verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and give any other recipients of the Program a copy of this License along with the Program. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 2. You may modify your copy or copies of the Program or any portion of it, thus forming a work based on the Program, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: a) You must cause the modified files to carry prominent notices stating that you changed the files and the date of any change. b) You must cause any work that you distribute or publish, that in whole or in part contains or is derived from the Program or any part thereof, to be licensed as a whole at no charge to all third parties under the terms of this License. c) If the modified program normally reads commands interactively when run, you must cause it, when started running for such interactive use in the most ordinary way, to print or display an announcement including an appropriate copyright notice and a notice that there is no warranty (or else, saying that you provide a warranty) and that users may redistribute the program under these conditions, and telling the user how to view a copy of this License. (Exception: if the Program itself is interactive but does not normally print such an announcement, your work based on the Program is not required to print an announcement.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Program, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Program, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Program. In addition, mere aggregation of another work not based on the Program with the Program (or with a work based on the Program) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may copy and distribute the Program (or a work based on it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you also do one of the following: a) Accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, b) Accompany it with a written offer, valid for at least three years, to give any third party, for a charge no more than your cost of physically performing source distribution, a complete machine-readable copy of the corresponding source code, to be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, c) Accompany it with the information you received as to the offer to distribute corresponding source code. (This alternative is allowed only for noncommercial distribution and only if you received the program in object code or executable form with such an offer, in accord with Subsection b above.) The source code for a work means the preferred form of the work for making modifications to it. For an executable work, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the executable. However, as a special exception, the source code distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. If distribution of executable or object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place counts as distribution of the source code, even though third parties are not compelled to copy the source along with the object code. 4. You may not copy, modify, sublicense, or distribute the Program except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense or distribute the Program is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 5. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Program or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Program (or any work based on the Program), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Program or works based on it. 6. Each time you redistribute the Program (or any work based on the Program), the recipient automatically receives a license from the original licensor to copy, distribute or modify the Program subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties to this License. 7. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Program at all. For example, if a patent license would not permit royalty-free redistribution of the Program by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Program. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system, which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 8. If the distribution and/or use of the Program is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Program under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 9. The Free Software Foundation may publish revised and/or new versions of the General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of this License, you may choose any version ever published by the Free Software Foundation. 10. If you wish to incorporate parts of the Program into other free programs whose distribution conditions are different, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS Appendix: How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) 19yy This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. Also add information on how to contact you by electronic and paper mail. If the program is interactive, make it output a short notice like this when it starts in an interactive mode: Gnomovision version 69, Copyright (C) 19yy name of author Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, the commands you use may be called something other than `show w' and `show c'; they could even be mouse-clicks or menu items--whatever suits your program. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the program, if necessary. Here is a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the program `Gnomovision' (which makes passes at compilers) written by James Hacker. , 1 April 1989 Ty Coon, President of Vice This General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Library General Public License instead of this License. keyutils-1.6.3/LICENCE.LGPL000066400000000000000000000635221370111642500151240ustar00rootroot00000000000000 GNU LESSER GENERAL PUBLIC LICENSE Version 2.1, February 1999 Copyright (C) 1991, 1999 Free Software Foundation, Inc. 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. [This is the first released version of the Lesser GPL. It also counts as the successor of the GNU Library Public License, version 2, hence the version number 2.1.] Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public Licenses are intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This license, the Lesser General Public License, applies to some specially designated software packages--typically libraries--of the Free Software Foundation and other authors who decide to use it. You can use it too, but we suggest you first think carefully about whether this license or the ordinary General Public License is the better strategy to use in any particular case, based on the explanations below. When we speak of free software, we are referring to freedom of use, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish); that you receive source code or can get it if you want it; that you can change the software and use pieces of it in new free programs; and that you are informed that you can do these things. To protect your rights, we need to make restrictions that forbid distributors to deny you these rights or to ask you to surrender these rights. These restrictions translate to certain responsibilities for you if you distribute copies of the library or if you modify it. For example, if you distribute copies of the library, whether gratis or for a fee, you must give the recipients all the rights that we gave you. You must make sure that they, too, receive or can get the source code. If you link other code with the library, you must provide complete object files to the recipients, so that they can relink them with the library after making changes to the library and recompiling it. And you must show them these terms so they know their rights. We protect your rights with a two-step method: (1) we copyright the library, and (2) we offer you this license, which gives you legal permission to copy, distribute and/or modify the library. To protect each distributor, we want to make it very clear that there is no warranty for the free library. Also, if the library is modified by someone else and passed on, the recipients should know that what they have is not the original version, so that the original author's reputation will not be affected by problems that might be introduced by others. Finally, software patents pose a constant threat to the existence of any free program. We wish to make sure that a company cannot effectively restrict the users of a free program by obtaining a restrictive license from a patent holder. Therefore, we insist that any patent license obtained for a version of the library must be consistent with the full freedom of use specified in this license. Most GNU software, including some libraries, is covered by the ordinary GNU General Public License. This license, the GNU Lesser General Public License, applies to certain designated libraries, and is quite different from the ordinary General Public License. We use this license for certain libraries in order to permit linking those libraries into non-free programs. When a program is linked with a library, whether statically or using a shared library, the combination of the two is legally speaking a combined work, a derivative of the original library. The ordinary General Public License therefore permits such linking only if the entire combination fits its criteria of freedom. The Lesser General Public License permits more lax criteria for linking other code with the library. We call this license the "Lesser" General Public License because it does Less to protect the user's freedom than the ordinary General Public License. It also provides other free software developers Less of an advantage over competing non-free programs. These disadvantages are the reason we use the ordinary General Public License for many libraries. However, the Lesser license provides advantages in certain special circumstances. For example, on rare occasions, there may be a special need to encourage the widest possible use of a certain library, so that it becomes a de-facto standard. To achieve this, non-free programs must be allowed to use the library. A more frequent case is that a free library does the same job as widely used non-free libraries. In this case, there is little to gain by limiting the free library to free software only, so we use the Lesser General Public License. In other cases, permission to use a particular library in non-free programs enables a greater number of people to use a large body of free software. For example, permission to use the GNU C Library in non-free programs enables many more people to use the whole GNU operating system, as well as its variant, the GNU/Linux operating system. Although the Lesser General Public License is Less protective of the users' freedom, it does ensure that the user of a program that is linked with the Library has the freedom and the wherewithal to run that program using a modified version of the Library. The precise terms and conditions for copying, distribution and modification follow. Pay close attention to the difference between a "work based on the library" and a "work that uses the library". The former contains code derived from the library, whereas the latter must be combined with the library in order to run. GNU LESSER GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License Agreement applies to any software library or other program which contains a notice placed by the copyright holder or other authorized party saying it may be distributed under the terms of this Lesser General Public License (also called "this License"). Each licensee is addressed as "you". A "library" means a collection of software functions and/or data prepared so as to be conveniently linked with application programs (which use some of those functions and data) to form executables. The "Library", below, refers to any such software library or work which has been distributed under these terms. A "work based on the Library" means either the Library or any derivative work under copyright law: that is to say, a work containing the Library or a portion of it, either verbatim or with modifications and/or translated straightforwardly into another language. (Hereinafter, translation is included without limitation in the term "modification".) "Source code" for a work means the preferred form of the work for making modifications to it. For a library, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the library. Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running a program using the Library is not restricted, and output from such a program is covered only if its contents constitute a work based on the Library (independent of the use of the Library in a tool for writing it). Whether that is true depends on what the Library does and what the program that uses the Library does. 1. You may copy and distribute verbatim copies of the Library's complete source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and distribute a copy of this License along with the Library. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 2. You may modify your copy or copies of the Library or any portion of it, thus forming a work based on the Library, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: a) The modified work must itself be a software library. b) You must cause the files modified to carry prominent notices stating that you changed the files and the date of any change. c) You must cause the whole of the work to be licensed at no charge to all third parties under the terms of this License. d) If a facility in the modified Library refers to a function or a table of data to be supplied by an application program that uses the facility, other than as an argument passed when the facility is invoked, then you must make a good faith effort to ensure that, in the event an application does not supply such function or table, the facility still operates, and performs whatever part of its purpose remains meaningful. (For example, a function in a library to compute square roots has a purpose that is entirely well-defined independent of the application. Therefore, Subsection 2d requires that any application-supplied function or table used by this function must be optional: if the application does not supply it, the square root function must still compute square roots.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Library, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Library, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Library. In addition, mere aggregation of another work not based on the Library with the Library (or with a work based on the Library) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may opt to apply the terms of the ordinary GNU General Public License instead of this License to a given copy of the Library. To do this, you must alter all the notices that refer to this License, so that they refer to the ordinary GNU General Public License, version 2, instead of to this License. (If a newer version than version 2 of the ordinary GNU General Public License has appeared, then you can specify that version instead if you wish.) Do not make any other change in these notices. Once this change is made in a given copy, it is irreversible for that copy, so the ordinary GNU General Public License applies to all subsequent copies and derivative works made from that copy. This option is useful when you wish to copy part of the code of the Library into a program that is not a library. 4. You may copy and distribute the Library (or a portion or derivative of it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange. If distribution of object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place satisfies the requirement to distribute the source code, even though third parties are not compelled to copy the source along with the object code. 5. A program that contains no derivative of any portion of the Library, but is designed to work with the Library by being compiled or linked with it, is called a "work that uses the Library". Such a work, in isolation, is not a derivative work of the Library, and therefore falls outside the scope of this License. However, linking a "work that uses the Library" with the Library creates an executable that is a derivative of the Library (because it contains portions of the Library), rather than a "work that uses the library". The executable is therefore covered by this License. Section 6 states terms for distribution of such executables. When a "work that uses the Library" uses material from a header file that is part of the Library, the object code for the work may be a derivative work of the Library even though the source code is not. Whether this is true is especially significant if the work can be linked without the Library, or if the work is itself a library. The threshold for this to be true is not precisely defined by law. If such an object file uses only numerical parameters, data structure layouts and accessors, and small macros and small inline functions (ten lines or less in length), then the use of the object file is unrestricted, regardless of whether it is legally a derivative work. (Executables containing this object code plus portions of the Library will still fall under Section 6.) Otherwise, if the work is a derivative of the Library, you may distribute the object code for the work under the terms of Section 6. Any executables containing that work also fall under Section 6, whether or not they are linked directly with the Library itself. 6. As an exception to the Sections above, you may also combine or link a "work that uses the Library" with the Library to produce a work containing portions of the Library, and distribute that work under terms of your choice, provided that the terms permit modification of the work for the customer's own use and reverse engineering for debugging such modifications. You must give prominent notice with each copy of the work that the Library is used in it and that the Library and its use are covered by this License. You must supply a copy of this License. If the work during execution displays copyright notices, you must include the copyright notice for the Library among them, as well as a reference directing the user to the copy of this License. Also, you must do one of these things: a) Accompany the work with the complete corresponding machine-readable source code for the Library including whatever changes were used in the work (which must be distributed under Sections 1 and 2 above); and, if the work is an executable linked with the Library, with the complete machine-readable "work that uses the Library", as object code and/or source code, so that the user can modify the Library and then relink to produce a modified executable containing the modified Library. (It is understood that the user who changes the contents of definitions files in the Library will not necessarily be able to recompile the application to use the modified definitions.) b) Use a suitable shared library mechanism for linking with the Library. A suitable mechanism is one that (1) uses at run time a copy of the library already present on the user's computer system, rather than copying library functions into the executable, and (2) will operate properly with a modified version of the library, if the user installs one, as long as the modified version is interface-compatible with the version that the work was made with. c) Accompany the work with a written offer, valid for at least three years, to give the same user the materials specified in Subsection 6a, above, for a charge no more than the cost of performing this distribution. d) If distribution of the work is made by offering access to copy from a designated place, offer equivalent access to copy the above specified materials from the same place. e) Verify that the user has already received a copy of these materials or that you have already sent this user a copy. For an executable, the required form of the "work that uses the Library" must include any data and utility programs needed for reproducing the executable from it. However, as a special exception, the materials to be distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. It may happen that this requirement contradicts the license restrictions of other proprietary libraries that do not normally accompany the operating system. Such a contradiction means you cannot use both them and the Library together in an executable that you distribute. 7. You may place library facilities that are a work based on the Library side-by-side in a single library together with other library facilities not covered by this License, and distribute such a combined library, provided that the separate distribution of the work based on the Library and of the other library facilities is otherwise permitted, and provided that you do these two things: a) Accompany the combined library with a copy of the same work based on the Library, uncombined with any other library facilities. This must be distributed under the terms of the Sections above. b) Give prominent notice with the combined library of the fact that part of it is a work based on the Library, and explaining where to find the accompanying uncombined form of the same work. 8. You may not copy, modify, sublicense, link with, or distribute the Library except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense, link with, or distribute the Library is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 9. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Library or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Library (or any work based on the Library), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Library or works based on it. 10. Each time you redistribute the Library (or any work based on the Library), the recipient automatically receives a license from the original licensor to copy, distribute, link with or modify the Library subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties with this License. 11. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Library at all. For example, if a patent license would not permit royalty-free redistribution of the Library by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Library. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply, and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 12. If the distribution and/or use of the Library is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Library under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 13. The Free Software Foundation may publish revised and/or new versions of the Lesser General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Library specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Library does not specify a license version number, you may choose any version ever published by the Free Software Foundation. 14. If you wish to incorporate parts of the Library into other free programs whose distribution conditions are incompatible with these, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Libraries If you develop a new library, and you want it to be of the greatest possible use to the public, we recommend making it free software that everyone can redistribute and change. You can do so by permitting redistribution under these terms (or, alternatively, under the terms of the ordinary General Public License). To apply these terms, attach the following notices to the library. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA Also add information on how to contact you by electronic and paper mail. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the library, if necessary. Here is a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the library `Frob' (a library for tweaking knobs) written by James Random Hacker. , 1 April 1990 Ty Coon, President of Vice That's all there is to it! keyutils-1.6.3/Makefile000066400000000000000000000252011370111642500150320ustar00rootroot00000000000000CPPFLAGS := -I. CFLAGS := -g -Wall -Werror CXXFLAGS := -g -Wall -Werror INSTALL := install DESTDIR := SPECFILE := keyutils.spec NO_GLIBC_KEYERR := 0 NO_ARLIB := 0 NO_SOLIB := 0 ETCDIR := /etc BINDIR := /bin SBINDIR := /sbin SHAREDIR := /usr/share/keyutils MANDIR := /usr/share/man MAN1 := $(MANDIR)/man1 MAN3 := $(MANDIR)/man3 MAN5 := $(MANDIR)/man5 MAN7 := $(MANDIR)/man7 MAN8 := $(MANDIR)/man8 INCLUDEDIR := /usr/include LN := ln LNS := $(LN) -sf PREFIX := /usr ############################################################################### # # Determine the current package version from the specfile # ############################################################################### vermajor := $(shell grep "%define vermajor" $(SPECFILE)) verminor := $(shell grep "%define verminor" $(SPECFILE)) MAJOR := $(word 3,$(vermajor)) MINOR := $(word 3,$(verminor)) VERSION := $(MAJOR).$(MINOR) TARBALL := keyutils-$(VERSION).tar ZTARBALL := $(TARBALL).bz2 ############################################################################### # # Determine the current library version from the version script # ############################################################################### libversion := $(filter KEYUTILS_%,$(shell grep ^KEYUTILS_ version.lds)) libversion := $(lastword $(libversion)) libversion := $(lastword $(libversion)) APIVERSION := $(subst KEYUTILS_,,$(libversion)) vernumbers := $(subst ., ,$(APIVERSION)) APIMAJOR := $(firstword $(vernumbers)) ARLIB := libkeyutils.a DEVELLIB := libkeyutils.so SONAME := libkeyutils.so.$(APIMAJOR) LIBNAME := libkeyutils.so.$(APIVERSION) ############################################################################### # # Guess at the appropriate lib directory and word size # ############################################################################### ifeq ($(origin LIBDIR),undefined) LIBDIR := $(shell ldd /usr/bin/make | grep '\(/libc[.]\)' | sed -e 's!.*\(/.*\)/libc[.].*!\1!') endif ifeq ($(origin USRLIBDIR),undefined) USRLIBDIR := $(patsubst /lib/%,/usr/lib/%,$(LIBDIR)) endif BUILDFOR := $(shell file /usr/bin/make | sed -e 's!.*ELF \(32\|64\)-bit.*!\1!')-bit ifeq ($(origin CFLAGS),undefined) ifeq ($(BUILDFOR),32-bit) CFLAGS += -m32 LIBDIR := /lib USRLIBDIR := /usr/lib else ifeq ($(BUILDFOR),64-bit) CFLAGS += -m64 LIBDIR := /lib64 USRLIBDIR := /usr/lib64 endif endif endif PKGCONFIG := libkeyutils.pc PKGCONFIG_DIR := pkgconfig ############################################################################### # # This is necessary if glibc doesn't know about the key management error codes # ############################################################################### ifeq ($(NO_GLIBC_KEYERR),1) CFLAGS += -DNO_GLIBC_KEYERR LIBLIBS := -ldl -lc else LIBLIBS := endif ############################################################################### # # Normal build rule # ############################################################################### all: keyctl request-key key.dns_resolver cxx ############################################################################### # # Build the libraries # ############################################################################### #RPATH = -Wl,-rpath,$(LIBDIR) VCPPFLAGS := -DPKGBUILD="\"$(shell date -u +%F)\"" VCPPFLAGS += -DPKGVERSION="\"keyutils-$(VERSION)\"" VCPPFLAGS += -DAPIVERSION="\"libkeyutils-$(APIVERSION)\"" ifeq ($(NO_ARLIB),0) all: $(ARLIB) $(ARLIB): keyutils.o $(AR) rcs $@ $< keyutils.o: keyutils.c keyutils.h Makefile $(CC) $(CPPFLAGS) $(VCPPFLAGS) $(CFLAGS) -UNO_GLIBC_KEYERR -o $@ -c $< LIB_DEPENDENCY := libkeyutils.a endif ifeq ($(NO_SOLIB),0) all: $(DEVELLIB) $(DEVELLIB): $(SONAME) $(LNS) $< $@ $(SONAME): $(LIBNAME) $(LNS) $< $@ LIBVERS := -shared -Wl,-soname,$(SONAME) -Wl,--version-script,version.lds $(LIBNAME): keyutils.os version.lds Makefile $(CC) $(CFLAGS) -fPIC $(LDFLAGS) $(LIBVERS) -o $@ keyutils.os $(LIBLIBS) keyutils.os: keyutils.c keyutils.h Makefile $(CC) $(CPPFLAGS) $(VCPPFLAGS) $(CFLAGS) -fPIC -o $@ -c $< LIB_DEPENDENCY := $(DEVELLIB) endif ############################################################################### # # Build the programs # ############################################################################### %.o: %.c keyutils.h Makefile $(CC) $(CPPFLAGS) $(CFLAGS) -o $@ -c $< keyctl: keyctl.o keyctl_testing.o keyctl_watch.o $(LIB_DEPENDENCY) $(CC) -L. $(CFLAGS) $(LDFLAGS) $(RPATH) -o $@ \ keyctl.o keyctl_testing.o keyctl_watch.o -lkeyutils keyctl.o keyctl_testing.o keyctl_watch.o: keyctl.h keyctl_watch.o: watch_queue.h request-key: request-key.o $(LIB_DEPENDENCY) $(CC) -L. $(CFLAGS) $(LDFLAGS) $(RPATH) -o $@ $< -lkeyutils key.dns_resolver: key.dns_resolver.o dns.afsdb.o $(LIB_DEPENDENCY) $(CC) -L. $(CFLAGS) $(LDFLAGS) $(RPATH) -o $@ \ key.dns_resolver.o dns.afsdb.o -lkeyutils -lresolv key.dns_resolver.o: key.dns_resolver.c key.dns.h dns.afsdb.o: dns.afsdb.c key.dns.h ############################################################################### # # Check that the header file has valid C++ syntax # ############################################################################### cxx.stamp: keyutils.h Makefile $(CXX) $(CPPFLAGS) $(CXXFLAGS) -x c++-header -fsyntax-only $< touch $@ cxx: cxx.stamp .PHONY: cxx ############################################################################### # # Install everything # ############################################################################### pkgconfig: sed \ -e 's,@VERSION\@,$(VERSION),g' \ -e 's,@prefix\@,$(PREFIX),g' \ -e 's,@exec_prefix\@,$(PREFIX),g' \ -e 's,@libdir\@,$(USRLIBDIR),g' \ -e 's,@includedir\@,$(INCLUDEDIR),g' \ < $(PKGCONFIG).in > $(PKGCONFIG) || rm $(PKGCONFIG) install: all ifeq ($(NO_ARLIB),0) $(INSTALL) -D -m 0644 $(ARLIB) $(DESTDIR)$(USRLIBDIR)/$(ARLIB) endif ifeq ($(NO_SOLIB),0) $(INSTALL) -D $(LIBNAME) $(DESTDIR)$(LIBDIR)/$(LIBNAME) $(LNS) $(LIBNAME) $(DESTDIR)$(LIBDIR)/$(SONAME) mkdir -p $(DESTDIR)$(USRLIBDIR) $(LNS) $(LIBDIR)/$(SONAME) $(DESTDIR)$(USRLIBDIR)/$(DEVELLIB) sed \ -e 's,@VERSION\@,$(VERSION),g' \ -e 's,@prefix\@,$(PREFIX),g' \ -e 's,@exec_prefix\@,$(PREFIX),g' \ -e 's,@libdir\@,$(USRLIBDIR),g' \ -e 's,@includedir\@,$(INCLUDEDIR),g' \ < $(PKGCONFIG).in > $(PKGCONFIG) || rm $(PKGCONFIG) $(INSTALL) -D $(PKGCONFIG) $(DESTDIR)$(LIBDIR)/$(PKGCONFIG_DIR)/$(PKGCONFIG) rm $(PKGCONFIG) endif $(INSTALL) -D keyctl $(DESTDIR)$(BINDIR)/keyctl $(INSTALL) -D request-key $(DESTDIR)$(SBINDIR)/request-key $(INSTALL) -D request-key-debug.sh $(DESTDIR)$(SHAREDIR)/request-key-debug.sh $(INSTALL) -D key.dns_resolver $(DESTDIR)$(SBINDIR)/key.dns_resolver $(INSTALL) -D -m 0644 request-key.conf $(DESTDIR)$(ETCDIR)/request-key.conf mkdir -p $(DESTDIR)$(ETCDIR)/request-key.d mkdir -p $(DESTDIR)$(ETCDIR)/keyutils mkdir -p $(DESTDIR)$(MAN1) $(INSTALL) -m 0644 $(wildcard man/*.1) $(DESTDIR)$(MAN1) mkdir -p $(DESTDIR)$(MAN3) $(INSTALL) -m 0644 $(wildcard man/*.3) $(DESTDIR)$(MAN3) mkdir -p $(DESTDIR)$(MAN5) $(INSTALL) -m 0644 $(wildcard man/*.5) $(DESTDIR)$(MAN5) mkdir -p $(DESTDIR)$(MAN7) $(INSTALL) -m 0644 $(wildcard man/*.7) $(DESTDIR)$(MAN7) mkdir -p $(DESTDIR)$(MAN8) $(INSTALL) -m 0644 $(wildcard man/*.8) $(DESTDIR)$(MAN8) $(LNS) keyctl_describe.3 $(DESTDIR)$(MAN3)/keyctl_describe_alloc.3 $(LNS) keyctl_get_security.3 $(DESTDIR)$(MAN3)/keyctl_get_security_alloc.3 $(LNS) keyctl_instantiate.3 $(DESTDIR)$(MAN3)/keyctl_instantiate_iov.3 $(LNS) keyctl_instantiate.3 $(DESTDIR)$(MAN3)/keyctl_reject.3 $(LNS) keyctl_instantiate.3 $(DESTDIR)$(MAN3)/keyctl_negate.3 $(LNS) keyctl_instantiate.3 $(DESTDIR)$(MAN3)/keyctl_assume_authority.3 $(LNS) keyctl_link.3 $(DESTDIR)$(MAN3)/keyctl_unlink.3 $(LNS) keyctl_read.3 $(DESTDIR)$(MAN3)/keyctl_read_alloc.3 $(LNS) recursive_key_scan.3 $(DESTDIR)$(MAN3)/recursive_session_key_scan.3 $(LNS) keyctl_dh_compute.3 $(DESTDIR)$(MAN3)/keyctl_dh_compute_alloc.3 $(LNS) keyctl_dh_compute.3 $(DESTDIR)$(MAN3)/keyctl_dh_compute_kdf.3 $(INSTALL) -D -m 0644 keyutils.h $(DESTDIR)$(INCLUDEDIR)/keyutils.h ############################################################################### # # Run tests # ############################################################################### test: $(MAKE) -C tests run ############################################################################### # # Clean up # ############################################################################### clean: $(MAKE) -C tests clean $(RM) libkeyutils.so* libkeyutils.a libkeyutils.pc $(RM) keyctl request-key key.dns_resolver $(RM) *.o *.os *~ $(RM) debugfiles.list debugsources.list $(RM) cxx.stamp distclean: clean $(RM) -r rpmbuild $(TARBALL) ############################################################################### # # Generate a tarball # ############################################################################### $(ZTARBALL): git archive --prefix=keyutils-$(VERSION)/ --format tar -o $(TARBALL) HEAD bzip2 -9 <$(TARBALL) >$(ZTARBALL) tarball: $(ZTARBALL) ############################################################################### # # Generate an RPM # ############################################################################### SRCBALL := rpmbuild/SOURCES/$(TARBALL) ZSRCBALL := rpmbuild/SOURCES/$(ZTARBALL) BUILDID := .local rpmver0 := $(shell rpmspec -q ./keyutils.spec --define "buildid $(BUILDID)") rpmver1 := $(word 1,$(rpmver0)) rpmver2 := $(subst ., ,$(rpmver1)) rpmver3 := $(lastword $(rpmver2)) rpmver4 := $(patsubst %.$(rpmver3),%,$(rpmver1)) rpmver := $(patsubst keyutils-%,%,$(rpmver4)) SRPM := rpmbuild/SRPMS/keyutils-$(rpmver).src.rpm RPMBUILDDIRS := \ --define "_srcrpmdir $(CURDIR)/rpmbuild/SRPMS" \ --define "_rpmdir $(CURDIR)/rpmbuild/RPMS" \ --define "_sourcedir $(CURDIR)/rpmbuild/SOURCES" \ --define "_specdir $(CURDIR)/rpmbuild/SPECS" \ --define "_builddir $(CURDIR)/rpmbuild/BUILD" \ --define "_buildrootdir $(CURDIR)/rpmbuild/BUILDROOT" RPMFLAGS := \ --define "buildid $(BUILDID)" srpm: mkdir -p rpmbuild chmod ug-s rpmbuild mkdir -p rpmbuild/{SPECS,SOURCES,BUILD,BUILDROOT,RPMS,SRPMS} git archive --prefix=keyutils-$(VERSION)/ --format tar -o $(SRCBALL) HEAD bzip2 -9 <$(SRCBALL) >$(ZSRCBALL) rpmbuild -ts $(ZSRCBALL) --define "_srcrpmdir rpmbuild/SRPMS" $(RPMFLAGS) rpm: srpm rpmbuild --rebuild $(SRPM) $(RPMBUILDDIRS) $(RPMFLAGS) rpmlint: rpm rpmlint $(SRPM) $(CURDIR)/rpmbuild/RPMS/*/keyutils-{,libs-,libs-devel-,debuginfo-}$(rpmver).*.rpm ############################################################################### # # Build debugging # ############################################################################### show_vars: @echo VERSION=$(VERSION) @echo APIVERSION=$(APIVERSION) @echo LIBDIR=$(LIBDIR) @echo USRLIBDIR=$(USRLIBDIR) @echo BUILDFOR=$(BUILDFOR) @echo SONAME=$(SONAME) @echo LIBNAME=$(LIBNAME) @echo SRPM=$(SRPM) @echo rpmver=$(rpmver) keyutils-1.6.3/README000066400000000000000000000006301370111642500142510ustar00rootroot00000000000000These tools are used to control the key management system built into the Linux kernel. To build and install the tools and manual pages, run: make make install If your glibc does not contain definitions for the new error codes and system calls, then try: make NO_GLIBC_KEYERR=1 The tools are licensed under the GPL and the utility library under the LGPL. Copies of these are included in this tarball. keyutils-1.6.3/SUBMITTING_PATCHES000066400000000000000000000036141370111642500161550ustar00rootroot00000000000000 ================== SUBMITTING PATCHES ================== Patches can be sent to the keyrings@vger.kernel.org mailing list or directly to David Howells , the author, in a private email. When sending patches to be included in keyutils, please certify that your patch meets the criteria below by including include a sign-off line in your email which looks like this: Signed-off-by: Random J Developer This confirms that you are permitted to submit the patch for inclusion in keyutils under the GPLv2 licence (utilities and documentation) or the LGPLv2.1 licence (library). The full text of the certificate is as follows: Developer's Certificate of Origin v1.1 ====================================== By making a contribution to this project, I certify that: (a) The contribution was created in whole or in part by me and I have the right to submit it under the open source licences indicated in the file; or (b) The contribution is based upon previous work that, to the best of my knowledge, is covered under an appropriate open source licence and I have the right under that licence to submit that work with modifications, whether created in whole or in part by me, under the same open source licence (unless I am permitted to submit under a different licence), as indicated in the file; or (c) The contribution was provided directly to me by some other person who certified (a), (b) or (c) and I have not modified it. and also that: (d) I understand and agree that this project and the contribution are public and that a record of the contribution (including all personal information I submit with it, including my sign-off) is maintained indefinitely and may be redistributed consistent with this project or the open source licence(s) involved. keyutils-1.6.3/dns.afsdb.c000066400000000000000000000216171370111642500154070ustar00rootroot00000000000000/* * DNS Resolver Module User-space Helper for AFSDB records * * Copyright (C) Wang Lei (wang840925@gmail.com) 2010 * Authors: Wang Lei (wang840925@gmail.com) * * Copyright (C) David Howells (dhowells@redhat.com) 2018 * * This is a userspace tool for querying AFSDB RR records in the DNS on behalf * of the kernel, and converting the VL server addresses to IPv4 format so that * they can be used by the kAFS filesystem. * * As some function like res_init() should use the static library, which is a * bug of libresolv, that is the reason for cifs.upcall to reimplement. * * To use this program, you must tell /sbin/request-key how to invoke it. You * need to have the keyutils package installed and something like the following * lines added to your /etc/request-key.conf file: * * #OP TYPE DESCRIPTION CALLOUT INFO PROGRAM ARG1 ARG2 ARG3 ... * ====== ============ =========== ============ ========================== * create dns_resolver afsdb:* * /sbin/key.dns_resolver %k * * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "key.dns.h" /* * */ static void afsdb_hosts_to_addrs(ns_msg handle, ns_sect section) { char *vllist[MAX_VLS]; /* list of name servers */ int vlsnum = 0; /* number of name servers in list */ int rrnum; ns_rr rr; int subtype, i, ret; unsigned int ttl = UINT_MAX, rr_ttl; debug("AFSDB RR count is %d", ns_msg_count(handle, section)); /* Look at all the resource records in this section. */ for (rrnum = 0; rrnum < ns_msg_count(handle, section); rrnum++) { /* Expand the resource record number rrnum into rr. */ if (ns_parserr(&handle, section, rrnum, &rr)) { _error("ns_parserr failed : %m"); continue; } /* We're only interested in AFSDB records */ if (ns_rr_type(rr) == ns_t_afsdb) { vllist[vlsnum] = malloc(MAXDNAME); if (!vllist[vlsnum]) error("Out of memory"); subtype = ns_get16(ns_rr_rdata(rr)); /* Expand the name server's domain name */ if (ns_name_uncompress(ns_msg_base(handle), ns_msg_end(handle), ns_rr_rdata(rr) + 2, vllist[vlsnum], MAXDNAME) < 0) error("ns_name_uncompress failed"); rr_ttl = ns_rr_ttl(rr); if (ttl > rr_ttl) ttl = rr_ttl; /* Check the domain name we've just unpacked and add it to * the list of VL servers if it is not a duplicate. * If it is a duplicate, just ignore it. */ for (i = 0; i < vlsnum; i++) if (strcasecmp(vllist[i], vllist[vlsnum]) == 0) goto next_one; /* Turn the hostname into IP addresses */ ret = dns_resolver(vllist[vlsnum], NULL); if (ret) { debug("AFSDB RR can't resolve." "subtype:%d, server name:%s, netmask:%u", subtype, vllist[vlsnum], mask); goto next_one; } info("AFSDB RR subtype:%d, server name:%s, ip:%*.*s, ttl:%u", subtype, vllist[vlsnum], (int)payload[payload_index - 1].iov_len, (int)payload[payload_index - 1].iov_len, (char *)payload[payload_index - 1].iov_base, ttl); /* prepare for the next record */ vlsnum++; continue; next_one: free(vllist[vlsnum]); } } key_expiry = ttl; info("ttl: %u", key_expiry); } /* * */ static void srv_hosts_to_addrs(ns_msg handle, ns_sect section) { char *vllist[MAX_VLS]; /* list of name servers */ int vlsnum = 0; /* number of name servers in list */ int rrnum; ns_rr rr; int subtype, i, ret; unsigned short pref, weight, port; unsigned int ttl = UINT_MAX, rr_ttl; char sport[8]; debug("SRV RR count is %d", ns_msg_count(handle, section)); /* Look at all the resource records in this section. */ for (rrnum = 0; rrnum < ns_msg_count(handle, section); rrnum++) { /* Expand the resource record number rrnum into rr. */ if (ns_parserr(&handle, section, rrnum, &rr)) { _error("ns_parserr failed : %m"); continue; } if (ns_rr_type(rr) == ns_t_srv) { vllist[vlsnum] = malloc(MAXDNAME); if (!vllist[vlsnum]) error("Out of memory"); subtype = ns_get16(ns_rr_rdata(rr)); /* Expand the name server's domain name */ if (ns_name_uncompress(ns_msg_base(handle), ns_msg_end(handle), ns_rr_rdata(rr) + 6, vllist[vlsnum], MAXDNAME) < 0) { _error("ns_name_uncompress failed"); continue; } rr_ttl = ns_rr_ttl(rr); if (ttl > rr_ttl) ttl = rr_ttl; pref = ns_get16(ns_rr_rdata(rr)); weight = ns_get16(ns_rr_rdata(rr) + 2); port = ns_get16(ns_rr_rdata(rr) + 4); info("rdata %u %u %u", pref, weight, port); sprintf(sport, "+%hu", port); /* Check the domain name we've just unpacked and add it to * the list of VL servers if it is not a duplicate. * If it is a duplicate, just ignore it. */ for (i = 0; i < vlsnum; i++) if (strcasecmp(vllist[i], vllist[vlsnum]) == 0) goto next_one; /* Turn the hostname into IP addresses */ ret = dns_resolver(vllist[vlsnum], sport); if (ret) { debug("SRV RR can't resolve." "subtype:%d, server name:%s, netmask:%u", subtype, vllist[vlsnum], mask); goto next_one; } info("SRV RR subtype:%d, server name:%s, ip:%*.*s, ttl:%u", subtype, vllist[vlsnum], (int)payload[payload_index - 1].iov_len, (int)payload[payload_index - 1].iov_len, (char *)payload[payload_index - 1].iov_base, ttl); /* prepare for the next record */ vlsnum++; continue; next_one: free(vllist[vlsnum]); } } key_expiry = ttl; info("ttl: %u", key_expiry); } /* * Look up an AFSDB record to get the VL server addresses. */ static int dns_query_AFSDB(const char *cell) { int response_len; /* buffer length */ ns_msg handle; /* handle for response message */ union { HEADER hdr; u_char buf[NS_PACKETSZ]; } response; /* response buffers */ debug("Get AFSDB RR for cell name:'%s'", cell); /* query the dns for an AFSDB resource record */ response_len = res_query(cell, ns_c_in, ns_t_afsdb, response.buf, sizeof(response)); if (response_len < 0) { /* negative result */ _nsError(h_errno, cell); return -1; } if (ns_initparse(response.buf, response_len, &handle) < 0) error("ns_initparse: %m"); /* look up the hostnames we've obtained to get the actual addresses */ afsdb_hosts_to_addrs(handle, ns_s_an); info("DNS query AFSDB RR results:%u ttl:%u", payload_index, key_expiry); return 0; } /* * Look up an SRV record to get the VL server addresses [RFC 5864]. */ static int dns_query_VL_SRV(const char *cell) { int response_len; /* buffer length */ ns_msg handle; /* handle for response message */ union { HEADER hdr; u_char buf[NS_PACKETSZ]; } response; char name[1024]; snprintf(name, sizeof(name), "_afs3-vlserver._udp.%s", cell); debug("Get VL SRV RR for name:'%s'", name); response_len = res_query(name, ns_c_in, ns_t_srv, response.buf, sizeof(response)); if (response_len < 0) { /* negative result */ _nsError(h_errno, cell); return -1; } if (ns_initparse(response.buf, response_len, &handle) < 0) error("ns_initparse: %m"); /* look up the hostnames we've obtained to get the actual addresses */ srv_hosts_to_addrs(handle, ns_s_an); info("DNS query VL SRV RR results:%u ttl:%u", payload_index, key_expiry); return 0; } /* * Instantiate the key. */ static __attribute__((noreturn)) void afs_instantiate(const char *cell) { int ret; /* set the key's expiry time from the minimum TTL encountered */ if (!debug_mode) { ret = keyctl_set_timeout(key, key_expiry); if (ret == -1) error("%s: keyctl_set_timeout: %m", __func__); } /* handle a lack of results */ if (payload_index == 0) nsError(NO_DATA, cell); /* must include a NUL char at the end of the payload */ payload[payload_index].iov_base = ""; payload[payload_index++].iov_len = 1; dump_payload(); /* load the key with data key */ if (!debug_mode) { ret = keyctl_instantiate_iov(key, payload, payload_index, 0); if (ret == -1) error("%s: keyctl_instantiate: %m", __func__); } exit(0); } /* * Look up VL servers for AFS. */ void afs_look_up_VL_servers(const char *cell, char *options) { /* Is the IP address family limited? */ if (strcmp(options, "ipv4") == 0) mask = INET_IP4_ONLY; else if (strcmp(options, "ipv6") == 0) mask = INET_IP6_ONLY; if (dns_query_VL_SRV(cell) != 0) dns_query_AFSDB(cell); afs_instantiate(cell); } keyutils-1.6.3/key.dns.h000066400000000000000000000041441370111642500151210ustar00rootroot00000000000000/* * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public Licence as published by * the Free Software Foundation; either version 2 of the Licence, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public Licence for more details. */ #define _GNU_SOURCE #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #define MAX_VLS 15 /* Max Volume Location Servers Per-Cell */ #define INET_IP4_ONLY 0x1 #define INET_IP6_ONLY 0x2 #define INET_ALL 0xFF #define ONE_ADDR_ONLY 0x100 /* * key.dns_resolver.c */ extern key_serial_t key; extern int debug_mode; extern unsigned mask; extern unsigned int key_expiry; #define N_PAYLOAD 256 extern struct iovec payload[N_PAYLOAD]; extern int payload_index; extern __attribute__((format(printf, 1, 2), noreturn)) void error(const char *fmt, ...); extern __attribute__((format(printf, 1, 2))) void _error(const char *fmt, ...); extern __attribute__((format(printf, 1, 2))) void warning(const char *fmt, ...); extern __attribute__((format(printf, 1, 2))) void info(const char *fmt, ...); extern __attribute__((noreturn)) void nsError(int err, const char *domain); extern void _nsError(int err, const char *domain); extern __attribute__((format(printf, 1, 2))) void debug(const char *fmt, ...); extern void append_address_to_payload(const char *addr); extern void dump_payload(void); extern int dns_resolver(const char *server_name, const char *port); /* * dns.afsdb.c */ extern __attribute__((noreturn)) void afs_look_up_VL_servers(const char *cell, char *options); keyutils-1.6.3/key.dns_resolver.c000066400000000000000000000403771370111642500170450ustar00rootroot00000000000000/* * DNS Resolver Module User-space Helper for AFSDB records * * Copyright (C) Wang Lei (wang840925@gmail.com) 2010 * Authors: Wang Lei (wang840925@gmail.com) * David Howells (dhowells@redhat.com) * * This is a userspace tool for querying AFSDB RR records in the DNS on behalf * of the kernel, and converting the VL server addresses to IPv4 format so that * they can be used by the kAFS filesystem. * * Compile with: * * cc -o key.dns_resolver key.dns_resolver.c -lresolv -lkeyutils * * As some function like res_init() should use the static library, which is a * bug of libresolv, that is the reason for cifs.upcall to reimplement. * * To use this program, you must tell /sbin/request-key how to invoke it. You * need to have the keyutils package installed and something like the following * lines added to your /etc/request-key.conf file: * * #OP TYPE DESCRIPTION CALLOUT INFO PROGRAM ARG1 ARG2 ARG3 ... * ====== ============ =========== ============ ========================== * create dns_resolver afsdb:* * /sbin/key.dns_resolver %k * * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "key.dns.h" static const char *DNS_PARSE_VERSION = "1.0"; static const char prog[] = "key.dns_resolver"; static const char key_type[] = "dns_resolver"; static const char a_query_type[] = "a"; static const char aaaa_query_type[] = "aaaa"; static const char afsdb_query_type[] = "afsdb"; static const char *config_file = "/etc/keyutils/key.dns_resolver.conf"; static bool config_specified = false; key_serial_t key; static int verbose; int debug_mode; unsigned mask = INET_ALL; unsigned int key_expiry = 5; /* * segmental payload */ struct iovec payload[N_PAYLOAD]; int payload_index; /* * Print an error to stderr or the syslog, negate the key being created and * exit */ void error(const char *fmt, ...) { va_list va; va_start(va, fmt); if (isatty(2)) { vfprintf(stderr, fmt, va); fputc('\n', stderr); } else { vsyslog(LOG_ERR, fmt, va); } va_end(va); /* * on error, negatively instantiate the key ourselves so that we can * make sure the kernel doesn't hang it off of a searchable keyring * and interfere with the next attempt to instantiate the key. */ if (!debug_mode) keyctl_negate(key, 1, KEY_REQKEY_DEFL_DEFAULT); exit(1); } #define error(FMT, ...) error("Error: " FMT, ##__VA_ARGS__); /* * Just print an error to stderr or the syslog */ void _error(const char *fmt, ...) { va_list va; va_start(va, fmt); if (isatty(2)) { vfprintf(stderr, fmt, va); fputc('\n', stderr); } else { vsyslog(LOG_ERR, fmt, va); } va_end(va); } /* * Print a warning to stderr or the syslog */ void warning(const char *fmt, ...) { va_list va; va_start(va, fmt); if (isatty(2)) { vfprintf(stderr, fmt, va); fputc('\n', stderr); } else { vsyslog(LOG_WARNING, fmt, va); } va_end(va); } /* * Print status information */ void info(const char *fmt, ...) { va_list va; if (verbose < 1) return; va_start(va, fmt); if (isatty(1)) { fputs("I: ", stdout); vfprintf(stdout, fmt, va); fputc('\n', stdout); } else { vsyslog(LOG_INFO, fmt, va); } va_end(va); } /* * Print a nameserver error and exit */ static const int ns_errno_map[] = { [0] = ECONNREFUSED, [HOST_NOT_FOUND] = ENODATA, [TRY_AGAIN] = EAGAIN, [NO_RECOVERY] = ECONNREFUSED, [NO_DATA] = ENODATA, }; void _nsError(int err, const char *domain) { if (isatty(2)) fprintf(stderr, "NS:%s: %s.\n", domain, hstrerror(err)); else syslog(LOG_INFO, "%s: %s", domain, hstrerror(err)); if (err >= sizeof(ns_errno_map) / sizeof(ns_errno_map[0])) err = ECONNREFUSED; else err = ns_errno_map[err]; info("Reject the key with error %d", err); } void nsError(int err, const char *domain) { unsigned timeout; int ret; _nsError(err, domain); switch (err) { case TRY_AGAIN: timeout = 1; break; case 0: case NO_RECOVERY: timeout = 10; break; default: timeout = 1 * 60; break; } if (!debug_mode) { ret = keyctl_reject(key, timeout, err, KEY_REQKEY_DEFL_DEFAULT); if (ret == -1) error("%s: keyctl_reject: %m", __func__); } exit(0); } /* * Print debugging information */ void debug(const char *fmt, ...) { va_list va; if (verbose < 2) return; va_start(va, fmt); if (isatty(1)) { fputs("D: ", stdout); vfprintf(stdout, fmt, va); fputc('\n', stdout); } else { vsyslog(LOG_DEBUG, fmt, va); } va_end(va); } /* * Append an address to the payload segment list */ void append_address_to_payload(const char *addr) { size_t sz = strlen(addr); char *copy; int loop; debug("append '%s'", addr); if (payload_index + 2 > N_PAYLOAD - 1) return; /* discard duplicates */ for (loop = 0; loop < payload_index; loop++) if (payload[loop].iov_len == sz && memcmp(payload[loop].iov_base, addr, sz) == 0) return; copy = malloc(sz); if (!copy) error("%s: malloc: %m", __func__); memcpy(copy, addr, sz); if (payload_index != 0) { payload[payload_index ].iov_base = ","; payload[payload_index++].iov_len = 1; } payload[payload_index ].iov_base = copy; payload[payload_index++].iov_len = sz; } /* * Dump the payload when debugging */ void dump_payload(void) { size_t plen, n; char *buf, *p; int loop; if (debug_mode) verbose = 1; if (verbose < 1) return; plen = 0; for (loop = 0; loop < payload_index; loop++) { n = payload[loop].iov_len; debug("seg[%d]: %zu", loop, n); plen += n; } if (plen == 0) { info("The key instantiation data is empty"); return; } debug("total: %zu", plen); buf = malloc(plen + 1); if (!buf) return; p = buf; for (loop = 0; loop < payload_index; loop++) { n = payload[loop].iov_len; memcpy(p, payload[loop].iov_base, n); p += n; } info("The key instantiation data is '%s'", buf); info("The expiry time is %us", key_expiry); free(buf); } /* * Perform address resolution on a hostname and add the resulting address as a * string to the list of payload segments. */ int dns_resolver(const char *server_name, const char *port) { struct addrinfo hints, *addr, *ai; char buf[INET6_ADDRSTRLEN + 8 + 1]; int ret, len; void *sa; debug("Resolve '%s' with %x", server_name, mask); memset(&hints, 0, sizeof(hints)); switch (mask & INET_ALL) { case INET_IP4_ONLY: hints.ai_family = AF_INET; debug("IPv4"); break; case INET_IP6_ONLY: hints.ai_family = AF_INET6; debug("IPv6"); break; default: break; } /* resolve name to ip */ ret = getaddrinfo(server_name, NULL, &hints, &addr); if (ret) { info("unable to resolve hostname: %s [%s]", server_name, gai_strerror(ret)); return -1; } for (ai = addr; ai; ai = ai->ai_next) { debug("RR: %x,%x,%x,%x,%x,%s", ai->ai_flags, ai->ai_family, ai->ai_socktype, ai->ai_protocol, ai->ai_addrlen, ai->ai_canonname); /* convert address to string */ switch (ai->ai_family) { case AF_INET: if (!(mask & INET_IP4_ONLY)) continue; sa = &(((struct sockaddr_in *)ai->ai_addr)->sin_addr); len = INET_ADDRSTRLEN; break; case AF_INET6: if (!(mask & INET_IP6_ONLY)) continue; sa = &(((struct sockaddr_in6 *)ai->ai_addr)->sin6_addr); len = INET6_ADDRSTRLEN; break; default: debug("Address of unknown family %u", addr->ai_family); continue; } if (!inet_ntop(ai->ai_family, sa, buf, len)) error("%s: inet_ntop: %m", __func__); if (port) strcat(buf, port); append_address_to_payload(buf); if (mask & ONE_ADDR_ONLY) break; } freeaddrinfo(addr); return 0; } /* * Look up a A and/or AAAA records to get host addresses * * The callout_info is parsed for request options. For instance, "ipv4" to * request only IPv4 addresses, "ipv6" to request only IPv6 addresses and * "list" to get multiple addresses. */ static __attribute__((noreturn)) int dns_query_a_or_aaaa(const char *hostname, char *options) { int ret; debug("Get A/AAAA RR for hostname:'%s', options:'%s'", hostname, options); if (!options[0]) { /* legacy mode */ mask = INET_IP4_ONLY | ONE_ADDR_ONLY; } else { char *k, *val; mask = INET_ALL | ONE_ADDR_ONLY; do { k = options; options = strchr(options, ' '); if (!options) options = k + strlen(k); else *options++ = '\0'; if (!*k) continue; if (strchr(k, ',')) error("Option name '%s' contains a comma", k); val = strchr(k, '='); if (val) *val++ = '\0'; debug("Opt %s", k); if (strcmp(k, "ipv4") == 0) { mask &= ~INET_ALL; mask |= INET_IP4_ONLY; } else if (strcmp(k, "ipv6") == 0) { mask &= ~INET_ALL; mask |= INET_IP6_ONLY; } else if (strcmp(k, "list") == 0) { mask &= ~ONE_ADDR_ONLY; } } while (*options); } /* Turn the hostname into IP addresses */ ret = dns_resolver(hostname, NULL); if (ret) nsError(NO_DATA, hostname); /* handle a lack of results */ if (payload_index == 0) nsError(NO_DATA, hostname); /* must include a NUL char at the end of the payload */ payload[payload_index].iov_base = ""; payload[payload_index++].iov_len = 1; dump_payload(); /* load the key with data key */ if (!debug_mode) { ret = keyctl_set_timeout(key, key_expiry); if (ret == -1) error("%s: keyctl_set_timeout: %m", __func__); ret = keyctl_instantiate_iov(key, payload, payload_index, 0); if (ret == -1) error("%s: keyctl_instantiate: %m", __func__); } exit(0); } /* * Read the config file. */ static void read_config(void) { FILE *f; char buf[4096], *b, *p, *k, *v; unsigned int line = 0, u; int n; info("READ CONFIG %s", config_file); f = fopen(config_file, "r"); if (!f) { if (errno == ENOENT && !config_specified) { debug("%s: %m", config_file); return; } error("%s: %m", config_file); } while (fgets(buf, sizeof(buf) - 1, f)) { line++; /* Trim off leading and trailing spaces and discard whole-line * comments. */ b = buf; while (isspace(*b)) b++; if (!*b || *b == '#') continue; p = strchr(b, '\n'); if (!p) error("%s:%u: line missing newline or too long", config_file, line); while (p > buf && isspace(p[-1])) p--; *p = 0; /* Split into key[=value] pairs and trim spaces. */ k = b; v = NULL; b = strchr(b, '='); if (b) { char quote = 0; bool esc = false; if (b == k) error("%s:%u: Unspecified key", config_file, line); /* NUL-terminate the key. */ for (p = b - 1; isspace(*p); p--) ; p[1] = 0; /* Strip leading spaces */ b++; while (isspace(*b)) b++; if (!*b) goto missing_value; if (*b == '"' || *b == '\'') { quote = *b; b++; } v = p = b; while (*b) { if (esc) { switch (*b) { case ' ': case '\t': case '"': case '\'': case '\\': break; default: goto invalid_escape_char; } esc = false; *p++ = *b++; continue; } if (*b == '\\') { esc = true; b++; continue; } if (*b == quote) { b++; if (*b) goto post_quote_data; quote = 0; break; } if (!quote && *b == '#') break; /* Terminal comment */ *p++ = *b++; } if (esc) error("%s:%u: Incomplete escape", config_file, line); if (quote) error("%s:%u: Unclosed quotes", config_file, line); *p = 0; } if (strcmp(k, "default_ttl") == 0) { if (!v) goto missing_value; if (sscanf(v, "%u%n", &u, &n) != 1) goto bad_value; if (v[n]) goto extra_data; if (u < 1 || u > INT_MAX) goto out_of_range; key_expiry = u; } else { warning("%s:%u: Unknown option '%s'", config_file, line, k); } } if (ferror(f) || fclose(f) == EOF) error("%s: %m", config_file); return; missing_value: error("%s:%u: %s: Missing value", config_file, line, k); invalid_escape_char: error("%s:%u: %s: Invalid char in escape", config_file, line, k); post_quote_data: error("%s:%u: %s: Data after closing quote", config_file, line, k); bad_value: error("%s:%u: %s: Bad value", config_file, line, k); extra_data: error("%s:%u: %s: Extra data supplied", config_file, line, k); out_of_range: error("%s:%u: %s: Value out of range", config_file, line, k); } /* * Dump the configuration after parsing the config file. */ static __attribute__((noreturn)) void config_dumper(void) { printf("default_ttl = %u\n", key_expiry); exit(0); } /* * Print usage details, */ static __attribute__((noreturn)) void usage(void) { if (isatty(2)) { fprintf(stderr, "Usage: %s [-vv] [-c config] key_serial\n", prog); fprintf(stderr, "Usage: %s -D [-vv] [-c config] \n", prog); } else { info("Usage: %s [-vv] [-c config] key_serial", prog); } exit(2); } static const struct option long_options[] = { { "config", 0, NULL, 'c' }, { "debug", 0, NULL, 'D' }, { "dump-config", 0, NULL, 2 }, { "verbose", 0, NULL, 'v' }, { "version", 0, NULL, 'V' }, { NULL, 0, NULL, 0 } }; /* * */ int main(int argc, char *argv[]) { int ktlen, qtlen, ret; char *keyend, *p; char *callout_info = NULL; char *buf = NULL, *name; bool dump_config = false; openlog(prog, 0, LOG_DAEMON); while ((ret = getopt_long(argc, argv, "c:vDV", long_options, NULL)) != -1) { switch (ret) { case 'c': config_file = optarg; config_specified = true; continue; case 2: dump_config = true; continue; case 'D': debug_mode = 1; continue; case 'V': printf("version: %s from %s (%s)\n", DNS_PARSE_VERSION, keyutils_version_string, keyutils_build_string); exit(0); case 'v': verbose++; continue; default: if (!isatty(2)) syslog(LOG_ERR, "unknown option: %c", ret); usage(); } } argc -= optind; argv += optind; read_config(); if (dump_config) config_dumper(); if (!debug_mode) { if (argc != 1) usage(); /* get the key ID */ if (!**argv) error("Invalid blank key ID"); key = strtol(*argv, &p, 10); if (*p) error("Invalid key ID format"); /* get the key description (of the form "x;x;x;x;:") */ ret = keyctl_describe_alloc(key, &buf); if (ret == -1) error("keyctl_describe_alloc failed: %m"); /* get the callout_info (which can supply options) */ ret = keyctl_read_alloc(KEY_SPEC_REQKEY_AUTH_KEY, (void **)&callout_info); if (ret == -1) error("Invalid key callout_info read: %m"); } else { if (argc != 2) usage(); ret = asprintf(&buf, "%s;-1;-1;0;%s", key_type, argv[0]); if (ret < 0) error("Error %m"); callout_info = argv[1]; } ret = 1; info("Key description: '%s'", buf); info("Callout info: '%s'", callout_info); p = strchr(buf, ';'); if (!p) error("Badly formatted key description '%s'", buf); ktlen = p - buf; /* make sure it's the type we are expecting */ if (ktlen != sizeof(key_type) - 1 || memcmp(buf, key_type, ktlen) != 0) error("Key type is not supported: '%*.*s'", ktlen, ktlen, buf); keyend = buf + ktlen + 1; /* the actual key description follows the last semicolon */ keyend = rindex(keyend, ';'); if (!keyend) error("Invalid key description: %s", buf); keyend++; name = index(keyend, ':'); if (!name) dns_query_a_or_aaaa(keyend, callout_info); qtlen = name - keyend; name++; info("Query type: '%*.*s'", qtlen, qtlen, keyend); if ((qtlen == sizeof(a_query_type) - 1 && memcmp(keyend, a_query_type, sizeof(a_query_type) - 1) == 0) || (qtlen == sizeof(aaaa_query_type) - 1 && memcmp(keyend, aaaa_query_type, sizeof(aaaa_query_type) - 1) == 0) ) { info("Do DNS query of A/AAAA type for:'%s' mask:'%s'", name, callout_info); dns_query_a_or_aaaa(name, callout_info); } if (qtlen == sizeof(afsdb_query_type) - 1 && memcmp(keyend, afsdb_query_type, sizeof(afsdb_query_type) - 1) == 0 ) { info("Do AFS VL server query for:'%s' mask:'%s'", name, callout_info); afs_look_up_VL_servers(name, callout_info); } error("Query type: \"%*.*s\" is not supported", qtlen, qtlen, keyend); } keyutils-1.6.3/keyctl.c000066400000000000000000001545451370111642500150470ustar00rootroot00000000000000/* keyctl.c: key control program * * Copyright (C) 2005, 2011 Red Hat, Inc. All Rights Reserved. * Written by David Howells (dhowells@redhat.com) * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version * 2 of the License, or (at your option) any later version. */ #define _GNU_SOURCE #include #include #include #include #include #include #include #include #include #include #include #include #include "keyutils.h" #include #include "keyctl.h" static void try_wipe_memory(void *s, size_t n) { #if defined(__GLIBC__) && defined(__GLIBC_PREREQ) #if __GLIBC_PREREQ(2,25) explicit_bzero(s, n); #endif #endif } static nr void act_keyctl___version(int argc, char *argv[]); static nr void act_keyctl_id(int argc, char *argv[]); static nr void act_keyctl_show(int argc, char *argv[]); static nr void act_keyctl_add(int argc, char *argv[]); static nr void act_keyctl_padd(int argc, char *argv[]); static nr void act_keyctl_request(int argc, char *argv[]); static nr void act_keyctl_request2(int argc, char *argv[]); static nr void act_keyctl_prequest2(int argc, char *argv[]); static nr void act_keyctl_update(int argc, char *argv[]); static nr void act_keyctl_pupdate(int argc, char *argv[]); static nr void act_keyctl_newring(int argc, char *argv[]); static nr void act_keyctl_revoke(int argc, char *argv[]); static nr void act_keyctl_clear(int argc, char *argv[]); static nr void act_keyctl_link(int argc, char *argv[]); static nr void act_keyctl_unlink(int argc, char *argv[]); static nr void act_keyctl_search(int argc, char *argv[]); static nr void act_keyctl_read(int argc, char *argv[]); static nr void act_keyctl_pipe(int argc, char *argv[]); static nr void act_keyctl_print(int argc, char *argv[]); static nr void act_keyctl_list(int argc, char *argv[]); static nr void act_keyctl_rlist(int argc, char *argv[]); static nr void act_keyctl_describe(int argc, char *argv[]); static nr void act_keyctl_rdescribe(int argc, char *argv[]); static nr void act_keyctl_chown(int argc, char *argv[]); static nr void act_keyctl_chgrp(int argc, char *argv[]); static nr void act_keyctl_setperm(int argc, char *argv[]); static nr void act_keyctl_session(int argc, char *argv[]); static nr void act_keyctl_instantiate(int argc, char *argv[]); static nr void act_keyctl_pinstantiate(int argc, char *argv[]); static nr void act_keyctl_negate(int argc, char *argv[]); static nr void act_keyctl_timeout(int argc, char *argv[]); static nr void act_keyctl_security(int argc, char *argv[]); static nr void act_keyctl_new_session(int argc, char *argv[]); static nr void act_keyctl_reject(int argc, char *argv[]); static nr void act_keyctl_reap(int argc, char *argv[]); static nr void act_keyctl_purge(int argc, char *argv[]); static nr void act_keyctl_invalidate(int argc, char *argv[]); static nr void act_keyctl_get_persistent(int argc, char *argv[]); static nr void act_keyctl_dh_compute(int argc, char *argv[]); static nr void act_keyctl_dh_compute_kdf(int argc, char *argv[]); static nr void act_keyctl_dh_compute_kdf_oi(int argc, char *argv[]); static nr void act_keyctl_restrict_keyring(int argc, char *argv[]); static nr void act_keyctl_pkey_query(int argc, char *argv[]); static nr void act_keyctl_pkey_encrypt(int argc, char *argv[]); static nr void act_keyctl_pkey_decrypt(int argc, char *argv[]); static nr void act_keyctl_pkey_sign(int argc, char *argv[]); static nr void act_keyctl_pkey_verify(int argc, char *argv[]); static nr void act_keyctl_move(int argc, char *argv[]); static nr void act_keyctl_supports(int argc, char *argv[]); static const struct command commands[] = { { act_keyctl___version, "--version", "" }, { act_keyctl_add, "add", "[-x] " }, { act_keyctl_chgrp, "chgrp", " " }, { act_keyctl_chown, "chown", " " }, { act_keyctl_clear, "clear", "" }, { act_keyctl_describe, "describe", "" }, { act_keyctl_dh_compute, "dh_compute", " " }, { act_keyctl_dh_compute_kdf, "dh_compute_kdf", " " }, { act_keyctl_dh_compute_kdf_oi, "dh_compute_kdf_oi", "[-x] " }, { act_keyctl_get_persistent, "get_persistent", " []" }, { act_keyctl_id, "id", "" }, { act_keyctl_instantiate, "instantiate","[-x] " }, { act_keyctl_invalidate,"invalidate", "" }, { act_keyctl_link, "link", " " }, { act_keyctl_list, "list", "" }, { act_keyctl_move, "move", "[-f] " }, { act_keyctl_negate, "negate", " " }, { act_keyctl_new_session, "new_session", "[]" }, { act_keyctl_newring, "newring", " " }, { act_keyctl_padd, "padd", "[-x] " }, { act_keyctl_pinstantiate, "pinstantiate","[-x] " }, { act_keyctl_pipe, "pipe", "" }, { act_keyctl_pkey_query, "pkey_query", " [k=v]*" }, { act_keyctl_pkey_encrypt, "pkey_encrypt", " [k=v]*" }, { act_keyctl_pkey_decrypt, "pkey_decrypt", " [k=v]*" }, { act_keyctl_pkey_sign, "pkey_sign", " [k=v]*" }, { act_keyctl_pkey_verify, "pkey_verify", " [k=v]*" }, { act_keyctl_prequest2, "prequest2", " []" }, { act_keyctl_print, "print", "" }, { act_keyctl_pupdate, "pupdate", "[-x] " }, { act_keyctl_purge, "purge", "" }, { NULL, "purge", "[-p] [-i] " }, { NULL, "purge", "-s " }, { act_keyctl_rdescribe, "rdescribe", " [sep]" }, { act_keyctl_read, "read", "" }, { act_keyctl_reap, "reap", "[-v]" }, { act_keyctl_reject, "reject", " " }, { act_keyctl_request, "request", " []" }, { act_keyctl_request2, "request2", " []" }, { act_keyctl_restrict_keyring, "restrict_keyring", " [ []]" }, { act_keyctl_revoke, "revoke", "" }, { act_keyctl_rlist, "rlist", "" }, { act_keyctl_search, "search", " []" }, { act_keyctl_security, "security", "" }, { act_keyctl_session, "session", "" }, { NULL, "session", "- [ ...]" }, { NULL, "session", " [ ...]" }, { act_keyctl_setperm, "setperm", " " }, { act_keyctl_show, "show", "[-x] []" }, { act_keyctl_supports, "supports", "[ | --raw]" }, { act_keyctl_timeout, "timeout", " " }, { act_keyctl_unlink, "unlink", " []" }, { act_keyctl_update, "update", "[-x] " }, { act_keyctl_watch, "watch", "[-f] " }, { act_keyctl_watch_add, "watch_add", " " }, { act_keyctl_watch_rm, "watch_rm", " " }, { act_keyctl_watch_session, "watch_session", "[-f] [-n ] [ ...]" }, { act_keyctl_watch_sync, "watch_sync", "" }, { act_keyctl_test, "--test", "..." }, { NULL, NULL, NULL } }; static int dump_key_tree(key_serial_t keyring, const char *name, int hex_key_IDs); static void *read_file(const char *name, size_t *_size); static uid_t myuid; static gid_t mygid, *mygroups; static int myngroups; static int verbose; /*****************************************************************************/ /* * handle an error */ void error(const char *msg) { perror(msg); exit(1); } /*****************************************************************************/ /* * */ int main(int argc, char *argv[]) { do_command(argc, argv, commands, ""); } /* * Execute the appropriate subcommand. */ void do_command(int argc, char **argv, const struct command *commands, const char *group) { const struct command *cmd, *best; int n; argv++; argc--; if (argc == 0) format(); /* find the best fit command */ best = NULL; n = strlen(*argv); for (cmd = commands; cmd->name; cmd++) { if (!cmd->action) continue; if (strlen(cmd->name) > n) continue; if (memcmp(cmd->name, *argv, n) != 0) continue; if (cmd->name[n] == 0) { /* exact match */ best = cmd; break; } /* partial match */ if (best) { fprintf(stderr, "Ambiguous %scommand\n", group); exit(2); } best = cmd; } if (!best) { fprintf(stderr, "Unknown %scommand\n", group); exit(2); } best->action(argc, argv); } /*****************************************************************************/ /* * display command format information */ void format(void) { const struct command *cmd; fprintf(stderr, "Format:\n"); for (cmd = commands; cmd->name; cmd++) fprintf(stderr, " keyctl %s %s\n", cmd->name, cmd->format); fprintf(stderr, "\n"); fprintf(stderr, "Key/keyring ID:\n"); fprintf(stderr, " numeric keyring ID\n"); fprintf(stderr, " @t thread keyring\n"); fprintf(stderr, " @p process keyring\n"); fprintf(stderr, " @s session keyring\n"); fprintf(stderr, " @u user keyring\n"); fprintf(stderr, " @us user default session keyring\n"); fprintf(stderr, " @g group keyring\n"); fprintf(stderr, " @a assumed request_key authorisation key\n"); fprintf(stderr, "\n"); fprintf(stderr, " can be \"user\" for a user-defined keyring\n"); fprintf(stderr, "If you do this, prefix the description with \":\"\n"); exit(2); } /* end format() */ /*****************************************************************************/ /* * Display version information */ static void act_keyctl___version(int argc, char *argv[]) { printf("keyctl from %s (Built %s)\n", keyutils_version_string, keyutils_build_string); exit(0); } /*****************************************************************************/ /* * grab data from stdin */ static char *grab_stdin(size_t *_size) { static char input[1024 * 1024 + 1]; int n, tmp; n = 0; do { tmp = read(0, input + n, sizeof(input) - 1 - n); if (tmp < 0) error("stdin"); if (tmp == 0) break; n += tmp; } while (n < sizeof(input)); if (n >= sizeof(input)) { fprintf(stderr, "Too much data read on stdin\n"); exit(1); } input[n] = '\0'; *_size = n; return input; } /* end grab_stdin() */ /* * Convert hex to binary if need be. */ void hex2bin(void **_data, size_t *_datalen, bool as_hex) { unsigned char *buf, *q, h, l; char *p, *end; if (!as_hex || *_datalen == 0) return; q = buf = malloc(*_datalen / 2 + 2); if (!buf) { try_wipe_memory(*_data, *_datalen); error("malloc"); } p = *_data; end = p + *_datalen; while (p < end) { if (isspace(*p)) { p++; continue; } if (end - p < 2) { fprintf(stderr, "Short hex doublet\n"); goto ret_exit; } if (!isxdigit(p[0]) || !isxdigit(p[1])) { fprintf(stderr, "Bad hex doublet\n"); goto ret_exit; } h = isdigit(p[0]) ? p[0] - '0' : tolower(p[0]) - 'a' + 0xa; l = isdigit(p[1]) ? p[1] - '0' : tolower(p[1]) - 'a' + 0xa; p += 2; *q++ = (h << 4) | l; } try_wipe_memory(*_data, *_datalen); *q = 0; *_data = buf; *_datalen = q - buf; return; ret_exit: try_wipe_memory(*_data, *_datalen); try_wipe_memory(buf, q - buf); exit(1); } /* * Load the groups list and grab the process's UID and GID. */ static void grab_creds(void) { static int inited; if (inited) return; inited = 1; /* grab my UID, GID and groups */ myuid = geteuid(); mygid = getegid(); myngroups = getgroups(0, NULL); if (myuid == -1 || mygid == -1 || myngroups == -1) error("Unable to get UID/GID/#Groups\n"); mygroups = calloc(myngroups, sizeof(gid_t)); if (!mygroups) error("calloc"); myngroups = getgroups(myngroups, mygroups); if (myngroups < 0) error("Unable to get Groups\n"); } /*****************************************************************************/ /* * convert the permissions mask to a string representing the permissions we * have actually been granted */ static void calc_perms(char *pretty, key_perm_t perm, uid_t uid, gid_t gid) { unsigned perms; gid_t *pg; int loop; grab_creds(); perms = (perm & KEY_POS_ALL) >> 24; if (uid == myuid) { perms |= (perm & KEY_USR_ALL) >> 16; goto write_mask; } if (gid != -1) { if (gid == mygid) { perms |= (perm & KEY_GRP_ALL) >> 8; goto write_mask; } pg = mygroups; for (loop = myngroups; loop > 0; loop--, pg++) { if (gid == *pg) { perms |= (perm & KEY_GRP_ALL) >> 8; goto write_mask; } } } perms |= (perm & KEY_OTH_ALL); write_mask: sprintf(pretty, "--%c%c%c%c%c%c", perms & KEY_OTH_SETATTR ? 'a' : '-', perms & KEY_OTH_LINK ? 'l' : '-', perms & KEY_OTH_SEARCH ? 's' : '-', perms & KEY_OTH_WRITE ? 'w' : '-', perms & KEY_OTH_READ ? 'r' : '-', perms & KEY_OTH_VIEW ? 'v' : '-'); } /* end calc_perms() */ /*****************************************************************************/ /* * Get a key or keyring ID. */ static void act_keyctl_id(int argc, char *argv[]) { key_serial_t key; if (argc != 2) format(); key = get_key_id(argv[1]); key = keyctl_get_keyring_ID(key, 0); if (key < 0) error("keyctl_get_keyring_ID"); printf("%d\n", key); exit(0); } /*****************************************************************************/ /* * show the parent process's session keyring */ static void act_keyctl_show(int argc, char *argv[]) { key_serial_t keyring = KEY_SPEC_SESSION_KEYRING; int hex_key_IDs = 0; if (argc >= 2 && strcmp(argv[1], "-x") == 0) { hex_key_IDs = 1; argc--; argv++; } if (argc > 2) format(); if (argc == 2) keyring = get_key_id(argv[1]); dump_key_tree(keyring, argc == 2 ? "Keyring" : "Session Keyring", hex_key_IDs); exit(0); } /* end act_keyctl_show() */ /*****************************************************************************/ /* * add a key */ static void act_keyctl_add(int argc, char *argv[]) { key_serial_t dest; size_t datalen; void *data; bool as_hex = false; int ret; if (argc > 1 && strcmp(argv[1], "-x") == 0) { as_hex = true; argc--; argv++; } if (argc != 5) format(); data = argv[3]; datalen = strlen(argv[3]); hex2bin(&data, &datalen, as_hex); dest = get_key_id(argv[4]); ret = add_key(argv[1], argv[2], data, datalen, dest); try_wipe_memory(data, datalen); if (ret < 0) error("add_key"); /* print the resulting key ID */ printf("%d\n", ret); exit(0); } /* end act_keyctl_add() */ /*****************************************************************************/ /* * add a key, reading from a pipe */ static void act_keyctl_padd(int argc, char *argv[]) { key_serial_t dest; size_t datalen; void *data; bool as_hex = false; int ret; if (argc > 1 && strcmp(argv[1], "-x") == 0) { as_hex = true; argc--; argv++; } if (argc != 4) format(); data = grab_stdin(&datalen); hex2bin(&data, &datalen, as_hex); dest = get_key_id(argv[3]); ret = add_key(argv[1], argv[2], data, datalen, dest); try_wipe_memory(data, datalen); if (ret < 0) error("add_key"); /* print the resulting key ID */ printf("%d\n", ret); exit(0); } /* end act_keyctl_padd() */ /*****************************************************************************/ /* * request a key */ static void act_keyctl_request(int argc, char *argv[]) { key_serial_t dest; int ret; if (argc != 3 && argc != 4) format(); dest = 0; if (argc == 4) dest = get_key_id(argv[3]); ret = request_key(argv[1], argv[2], NULL, dest); if (ret < 0) error("request_key"); /* print the resulting key ID */ printf("%d\n", ret); exit(0); } /* end act_keyctl_request() */ /*****************************************************************************/ /* * request a key, with recourse to /sbin/request-key */ static void act_keyctl_request2(int argc, char *argv[]) { key_serial_t dest; int ret; if (argc != 4 && argc != 5) format(); dest = 0; if (argc == 5) dest = get_key_id(argv[4]); ret = request_key(argv[1], argv[2], argv[3], dest); if (ret < 0) error("request_key"); /* print the resulting key ID */ printf("%d\n", ret); exit(0); } /* end act_keyctl_request2() */ /*****************************************************************************/ /* * request a key, with recourse to /sbin/request-key, reading the callout info * from a pipe */ static void act_keyctl_prequest2(int argc, char *argv[]) { char *args[6]; size_t datalen; if (argc != 3 && argc != 4) format(); args[0] = argv[0]; args[1] = argv[1]; args[2] = argv[2]; args[3] = grab_stdin(&datalen); args[4] = argv[3]; args[5] = NULL; act_keyctl_request2(argc + 1, args); } /* end act_keyctl_prequest2() */ /*****************************************************************************/ /* * update a key */ static void act_keyctl_update(int argc, char *argv[]) { key_serial_t key; size_t datalen; void *data; bool as_hex = false; int ret; if (argc > 1 && strcmp(argv[1], "-x") == 0) { as_hex = true; argc--; argv++; } if (argc != 3) format(); data = argv[2]; datalen = strlen(argv[2]); hex2bin(&data, &datalen, as_hex); key = get_key_id(argv[1]); ret = keyctl_update(key, data, datalen); try_wipe_memory(data, datalen); if (ret < 0) error("keyctl_update"); exit(0); } /* end act_keyctl_update() */ /*****************************************************************************/ /* * update a key, reading from a pipe */ static void act_keyctl_pupdate(int argc, char *argv[]) { key_serial_t key; size_t datalen; void *data; bool as_hex = false; int ret; if (argc > 1 && strcmp(argv[1], "-x") == 0) { as_hex = true; argc--; argv++; } if (argc != 2) format(); key = get_key_id(argv[1]); data = grab_stdin(&datalen); hex2bin(&data, &datalen, as_hex); ret = keyctl_update(key, data, datalen); try_wipe_memory(data, datalen); if (ret < 0) error("keyctl_update"); exit(0); } /* end act_keyctl_pupdate() */ /*****************************************************************************/ /* * create a new keyring */ static void act_keyctl_newring(int argc, char *argv[]) { key_serial_t dest; int ret; if (argc != 3) format(); dest = get_key_id(argv[2]); ret = add_key("keyring", argv[1], NULL, 0, dest); if (ret < 0) error("add_key"); printf("%d\n", ret); exit(0); } /* end act_keyctl_newring() */ /*****************************************************************************/ /* * revoke a key */ static void act_keyctl_revoke(int argc, char *argv[]) { key_serial_t key; if (argc != 2) format(); key = get_key_id(argv[1]); if (keyctl_revoke(key) < 0) error("keyctl_revoke"); exit(0); } /* end act_keyctl_revoke() */ /*****************************************************************************/ /* * clear a keyring */ static void act_keyctl_clear(int argc, char *argv[]) { key_serial_t keyring; if (argc != 2) format(); keyring = get_key_id(argv[1]); if (keyctl_clear(keyring) < 0) error("keyctl_clear"); exit(0); } /* end act_keyctl_clear() */ /*****************************************************************************/ /* * link a key to a keyring */ static void act_keyctl_link(int argc, char *argv[]) { key_serial_t keyring, key; if (argc != 3) format(); key = get_key_id(argv[1]); keyring = get_key_id(argv[2]); if (keyctl_link(key, keyring) < 0) error("keyctl_link"); exit(0); } /* end act_keyctl_link() */ /* * Attempt to unlink a key matching the ID */ static int act_keyctl_unlink_func(key_serial_t parent, key_serial_t key, char *desc, int desc_len, void *data) { key_serial_t *target = data; if (key == *target) return keyctl_unlink(key, parent) < 0 ? 0 : 1; return 0; } /* * Unlink a key from a keyring or from the session keyring tree. */ static void act_keyctl_unlink(int argc, char *argv[]) { key_serial_t keyring, key; int n; if (argc != 2 && argc != 3) format(); key = get_key_id(argv[1]); if (argc == 3) { keyring = get_key_id(argv[2]); if (keyctl_unlink(key, keyring) < 0) error("keyctl_unlink"); } else { n = recursive_session_key_scan(act_keyctl_unlink_func, &key); printf("%d links removed\n", n); } exit(0); } /*****************************************************************************/ /* * search a keyring for a key */ static void act_keyctl_search(int argc, char *argv[]) { key_serial_t keyring, dest; int ret; if (argc != 4 && argc != 5) format(); keyring = get_key_id(argv[1]); dest = 0; if (argc == 5) dest = get_key_id(argv[4]); ret = keyctl_search(keyring, argv[2], argv[3], dest); if (ret < 0) error("keyctl_search"); /* print the ID of the key we found */ printf("%d\n", ret); exit(0); } /* end act_keyctl_search() */ /*****************************************************************************/ /* * read a key */ static void act_keyctl_read(int argc, char *argv[]) { key_serial_t key; void *buffer; char *p; int ret, sep, col; if (argc != 2) format(); key = get_key_id(argv[1]); /* read the key payload data */ ret = keyctl_read_alloc(key, &buffer); if (ret < 0) error("keyctl_read_alloc"); if (ret == 0) { printf("No data in key\n"); exit(0); } /* hexdump the contents */ printf("%u bytes of data in key:\n", ret); sep = 0; col = 0; p = buffer; do { if (sep) { putchar(sep); sep = 0; } printf("%02hhx", *p); p++; col++; if (col % 32 == 0) sep = '\n'; else if (col % 4 == 0) sep = ' '; } while (--ret > 0); printf("\n"); exit(0); } /* end act_keyctl_read() */ /*****************************************************************************/ /* * read a key and dump raw to stdout */ static void act_keyctl_pipe(int argc, char *argv[]) { key_serial_t key; void *buffer; int ret; if (argc != 2) format(); key = get_key_id(argv[1]); /* read the key payload data */ ret = keyctl_read_alloc(key, &buffer); if (ret < 0) error("keyctl_read_alloc"); if (ret > 0 && write(1, buffer, ret) < 0) error("write"); exit(0); } /* end act_keyctl_pipe() */ /*****************************************************************************/ /* * read a key and dump to stdout in printable form */ static void act_keyctl_print(int argc, char *argv[]) { key_serial_t key; void *buffer; char *p; int loop, ret; if (argc != 2) format(); key = get_key_id(argv[1]); /* read the key payload data */ ret = keyctl_read_alloc(key, &buffer); if (ret < 0) error("keyctl_read_alloc"); /* see if it's printable */ p = buffer; for (loop = ret; loop > 0; loop--, p++) if (!isprint(*p)) goto not_printable; /* it is */ printf("%s\n", (char *) buffer); exit(0); not_printable: /* it isn't */ printf(":hex:"); p = buffer; for (loop = ret; loop > 0; loop--, p++) printf("%02hhx", *p); printf("\n"); exit(0); } /* end act_keyctl_print() */ /*****************************************************************************/ /* * list a keyring */ static void act_keyctl_list(int argc, char *argv[]) { key_serial_t keyring, key, *pk; key_perm_t perm; void *keylist; char *buffer, pretty_mask[9]; uid_t uid; gid_t gid; int count, tlen, dpos, n, ret; if (argc != 2) format(); keyring = get_key_id(argv[1]); /* read the key payload data */ count = keyctl_read_alloc(keyring, &keylist); if (count < 0) error("keyctl_read_alloc"); count /= sizeof(key_serial_t); if (count == 0) { printf("keyring is empty\n"); exit(0); } /* list the keys in the keyring */ if (count == 1) printf("1 key in keyring:\n"); else printf("%u keys in keyring:\n", count); pk = keylist; do { key = *pk++; ret = keyctl_describe_alloc(key, &buffer); if (ret < 0) { printf("%9d: key inaccessible (%m)\n", key); continue; } uid = 0; gid = 0; perm = 0; tlen = -1; dpos = -1; n = sscanf((char *) buffer, "%*[^;]%n;%d;%d;%x;%n", &tlen, &uid, &gid, &perm, &dpos); if (n != 3) { fprintf(stderr, "Unparsable description obtained for key %d\n", key); exit(3); } calc_perms(pretty_mask, perm, uid, gid); printf("%9d: %s %5d %5d %*.*s: %s\n", key, pretty_mask, uid, gid, tlen, tlen, buffer, buffer + dpos); free(buffer); } while (--count); exit(0); } /* end act_keyctl_list() */ /*****************************************************************************/ /* * produce a raw list of a keyring */ static void act_keyctl_rlist(int argc, char *argv[]) { key_serial_t keyring, key, *pk; void *keylist; int count; if (argc != 2) format(); keyring = get_key_id(argv[1]); /* read the key payload data */ count = keyctl_read_alloc(keyring, &keylist); if (count < 0) error("keyctl_read_alloc"); count /= sizeof(key_serial_t); /* list the keys in the keyring */ if (count <= 0) { printf("\n"); } else { pk = keylist; for (; count > 0; count--) { key = *pk++; printf("%d%c", key, count == 1 ? '\n' : ' '); } } exit(0); } /* end act_keyctl_rlist() */ /*****************************************************************************/ /* * describe a key */ static void act_keyctl_describe(int argc, char *argv[]) { key_serial_t key; key_perm_t perm; char *buffer; uid_t uid; gid_t gid; int tlen, dpos, n, ret; if (argc != 2) format(); key = get_key_id(argv[1]); /* get key description */ ret = keyctl_describe_alloc(key, &buffer); if (ret < 0) error("keyctl_describe_alloc"); /* parse it */ uid = 0; gid = 0; perm = 0; tlen = -1; dpos = -1; n = sscanf(buffer, "%*[^;]%n;%d;%d;%x;%n", &tlen, &uid, &gid, &perm, &dpos); if (n != 3) { fprintf(stderr, "Unparsable description obtained for key %d\n", key); exit(3); } /* display it */ printf("%9d:" " %c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c" " %5d %5d %*.*s: %s\n", key, perm & KEY_POS_SETATTR ? 'a' : '-', perm & KEY_POS_LINK ? 'l' : '-', perm & KEY_POS_SEARCH ? 's' : '-', perm & KEY_POS_WRITE ? 'w' : '-', perm & KEY_POS_READ ? 'r' : '-', perm & KEY_POS_VIEW ? 'v' : '-', perm & KEY_USR_SETATTR ? 'a' : '-', perm & KEY_USR_LINK ? 'l' : '-', perm & KEY_USR_SEARCH ? 's' : '-', perm & KEY_USR_WRITE ? 'w' : '-', perm & KEY_USR_READ ? 'r' : '-', perm & KEY_USR_VIEW ? 'v' : '-', perm & KEY_GRP_SETATTR ? 'a' : '-', perm & KEY_GRP_LINK ? 'l' : '-', perm & KEY_GRP_SEARCH ? 's' : '-', perm & KEY_GRP_WRITE ? 'w' : '-', perm & KEY_GRP_READ ? 'r' : '-', perm & KEY_GRP_VIEW ? 'v' : '-', perm & KEY_OTH_SETATTR ? 'a' : '-', perm & KEY_OTH_LINK ? 'l' : '-', perm & KEY_OTH_SEARCH ? 's' : '-', perm & KEY_OTH_WRITE ? 'w' : '-', perm & KEY_OTH_READ ? 'r' : '-', perm & KEY_OTH_VIEW ? 'v' : '-', uid, gid, tlen, tlen, buffer, buffer + dpos); exit(0); } /* end act_keyctl_describe() */ /*****************************************************************************/ /* * get raw key description */ static void act_keyctl_rdescribe(int argc, char *argv[]) { key_serial_t key; char *buffer, *q; int ret; if (argc != 2 && argc != 3) format(); if (argc == 3 && !argv[2][0]) format(); key = get_key_id(argv[1]); /* get key description */ ret = keyctl_describe_alloc(key, &buffer); if (ret < 0) error("keyctl_describe"); /* replace semicolon separators with requested alternative */ if (argc == 3) { for (q = buffer; *q; q++) if (*q == ';') *q = argv[2][0]; } /* display raw description */ printf("%s\n", buffer); exit(0); } /* end act_keyctl_rdescribe() */ /*****************************************************************************/ /* * change a key's ownership */ static void act_keyctl_chown(int argc, char *argv[]) { key_serial_t key; uid_t uid; char *q; if (argc != 3) format(); key = get_key_id(argv[1]); uid = strtoul(argv[2], &q, 0); if (*q) { fprintf(stderr, "Unparsable uid: '%s'\n", argv[2]); exit(2); } if (keyctl_chown(key, uid, -1) < 0) error("keyctl_chown"); exit(0); } /* end act_keyctl_chown() */ /*****************************************************************************/ /* * change a key's group ownership */ static void act_keyctl_chgrp(int argc, char *argv[]) { key_serial_t key; gid_t gid; char *q; if (argc != 3) format(); key = get_key_id(argv[1]); gid = strtoul(argv[2], &q, 0); if (*q) { fprintf(stderr, "Unparsable gid: '%s'\n", argv[2]); exit(2); } if (keyctl_chown(key, -1, gid) < 0) error("keyctl_chown"); exit(0); } /* end act_keyctl_chgrp() */ /*****************************************************************************/ /* * set the permissions on a key */ static void act_keyctl_setperm(int argc, char *argv[]) { key_serial_t key; key_perm_t perm; char *q; if (argc != 3) format(); key = get_key_id(argv[1]); perm = strtoul(argv[2], &q, 0); if (*q) { fprintf(stderr, "Unparsable permissions: '%s'\n", argv[2]); exit(2); } if (keyctl_setperm(key, perm) < 0) error("keyctl_setperm"); exit(0); } /* end act_keyctl_setperm() */ /*****************************************************************************/ /* * start a process in a new session */ static void act_keyctl_session(int argc, char *argv[]) { char *p, *q; int ret; argv++; argc--; /* no extra arguments signifies a standard shell in an anonymous * session */ p = NULL; if (argc != 0) { /* a dash signifies an anonymous session */ p = *argv; if (strcmp(p, "-") == 0) p = NULL; argv++; argc--; } /* create a new session keyring */ ret = keyctl_join_session_keyring(p); if (ret < 0) error("keyctl_join_session_keyring"); fprintf(stderr, "Joined session keyring: %d\n", ret); /* run the standard shell if no arguments */ if (argc == 0) { q = getenv("SHELL"); if (!q) q = "/bin/sh"; execl(q, q, NULL); error(q); } /* run the command specified */ execvp(argv[0], argv); error(argv[0]); } /* end act_keyctl_session() */ /*****************************************************************************/ /* * instantiate a key that's under construction */ static void act_keyctl_instantiate(int argc, char *argv[]) { key_serial_t key, dest; size_t datalen; void *data; bool as_hex = false; int ret; if (argc > 1 && strcmp(argv[1], "-x") == 0) { as_hex = true; argc--; argv++; } if (argc != 4) format(); key = get_key_id(argv[1]); dest = get_key_id(argv[3]); data = argv[2]; datalen = strlen(argv[2]); hex2bin(&data, &datalen, as_hex); ret = keyctl_instantiate(key, data, datalen, dest); try_wipe_memory(data, datalen); if (ret < 0) error("keyctl_instantiate"); exit(0); } /* end act_keyctl_instantiate() */ /*****************************************************************************/ /* * instantiate a key, reading from a pipe */ static void act_keyctl_pinstantiate(int argc, char *argv[]) { key_serial_t key, dest; size_t datalen; void *data; bool as_hex = false; int ret; if (argc > 1 && strcmp(argv[1], "-x") == 0) { as_hex = true; argc--; argv++; } if (argc != 3) format(); key = get_key_id(argv[1]); dest = get_key_id(argv[2]); data = grab_stdin(&datalen); hex2bin(&data, &datalen, as_hex); ret = keyctl_instantiate(key, data, datalen, dest); try_wipe_memory(data, datalen); if (ret < 0) error("keyctl_instantiate"); exit(0); } /* end act_keyctl_pinstantiate() */ /*****************************************************************************/ /* * negate a key that's under construction */ static void act_keyctl_negate(int argc, char *argv[]) { unsigned long timeout; key_serial_t key, dest; char *q; if (argc != 4) format(); key = get_key_id(argv[1]); timeout = strtoul(argv[2], &q, 10); if (*q) { fprintf(stderr, "Unparsable timeout: '%s'\n", argv[2]); exit(2); } dest = get_key_id(argv[3]); if (keyctl_negate(key, timeout, dest) < 0) error("keyctl_negate"); exit(0); } /* end act_keyctl_negate() */ /*****************************************************************************/ /* * set a key's timeout */ static void act_keyctl_timeout(int argc, char *argv[]) { unsigned long timeout; key_serial_t key; char *q; if (argc != 3) format(); key = get_key_id(argv[1]); timeout = strtoul(argv[2], &q, 10); if (*q) { fprintf(stderr, "Unparsable timeout: '%s'\n", argv[2]); exit(2); } if (keyctl_set_timeout(key, timeout) < 0) error("keyctl_set_timeout"); exit(0); } /* end act_keyctl_timeout() */ /*****************************************************************************/ /* * get a key's security label */ static void act_keyctl_security(int argc, char *argv[]) { key_serial_t key; char *buffer; int ret; if (argc != 2) format(); key = get_key_id(argv[1]); /* get key description */ ret = keyctl_get_security_alloc(key, &buffer); if (ret < 0) error("keyctl_getsecurity"); printf("%s\n", buffer); exit(0); } /*****************************************************************************/ /* * install a new session keyring on the parent process */ static void act_keyctl_new_session(int argc, char *argv[]) { key_serial_t keyring; if (argc != 1 && argc != 2) format(); if (keyctl_join_session_keyring(argv[1]) < 0) error("keyctl_join_session_keyring"); if (keyctl_session_to_parent() < 0) error("keyctl_session_to_parent"); keyring = keyctl_get_keyring_ID(KEY_SPEC_SESSION_KEYRING, 0); if (keyring < 0) error("keyctl_get_keyring_ID"); /* print the resulting key ID */ printf("%d\n", keyring); exit(0); } /*****************************************************************************/ /* * reject a key that's under construction */ static void act_keyctl_reject(int argc, char *argv[]) { unsigned long timeout; key_serial_t key, dest; unsigned long rejerr; char *q; if (argc != 5) format(); key = get_key_id(argv[1]); timeout = strtoul(argv[2], &q, 10); if (*q) { fprintf(stderr, "Unparsable timeout: '%s'\n", argv[2]); exit(2); } if (strcmp(argv[3], "rejected") == 0) { rejerr = EKEYREJECTED; } else if (strcmp(argv[3], "revoked") == 0) { rejerr = EKEYREVOKED; } else if (strcmp(argv[3], "expired") == 0) { rejerr = EKEYEXPIRED; } else { rejerr = strtoul(argv[3], &q, 10); if (*q) { fprintf(stderr, "Unparsable error: '%s'\n", argv[3]); exit(2); } } dest = get_key_id(argv[4]); if (keyctl_reject(key, timeout, rejerr, dest) < 0) error("keyctl_negate"); exit(0); } /* * Attempt to unlink a key if we can't read it for reasons other than we don't * have permission */ static int act_keyctl_reap_func(key_serial_t parent, key_serial_t key, char *desc, int desc_len, void *data) { if (desc_len < 0 && errno != EACCES) { if (verbose) printf("Reap %d", key); if (keyctl_unlink(key, parent) < 0) { if (verbose) printf("... failed %m\n"); return 0; } else { if (verbose) printf("\n"); return 1; }; } return 0; } /* * Reap the dead keys from the session keyring tree */ static void act_keyctl_reap(int argc, char *argv[]) { int n; if (argc > 1 && strcmp(argv[1], "-v") == 0) { verbose = 1; argc--; argv++; } if (argc != 1) format(); n = recursive_session_key_scan(act_keyctl_reap_func, NULL); printf("%d keys reaped\n", n); exit(0); } struct purge_data { const char *type; const char *desc; size_t desc_len; size_t type_len; char prefix_match; char case_indep; }; /* * Attempt to unlink a key matching the type */ static int act_keyctl_purge_type_func(key_serial_t parent, key_serial_t key, char *raw, int raw_len, void *data) { const struct purge_data *purge = data; char *p, *type; if (parent == 0 || !raw) return 0; /* type is everything before the first semicolon */ type = raw; p = memchr(raw, ';', raw_len); if (!p) return 0; *p = 0; if (strcmp(type, purge->type) != 0) return 0; return keyctl_unlink(key, parent) < 0 ? 0 : 1; } /* * Attempt to unlink a key matching the type and description literally */ static int act_keyctl_purge_literal_func(key_serial_t parent, key_serial_t key, char *raw, int raw_len, void *data) { const struct purge_data *purge = data; size_t tlen; char *p, *type, *desc; if (parent == 0 || !raw) return 0; /* type is everything before the first semicolon */ type = raw; p = memchr(type, ';', raw_len); if (!p) return 0; tlen = p - type; if (tlen != purge->type_len) return 0; if (memcmp(type, purge->type, tlen) != 0) return 0; /* description is everything after the last semicolon */ p++; desc = memrchr(p, ';', raw + raw_len - p); if (!desc) return 0; desc++; if (purge->prefix_match) { if (raw_len - (desc - raw) < purge->desc_len) return 0; } else { if (raw_len - (desc - raw) != purge->desc_len) return 0; } if (purge->case_indep) { if (strncasecmp(purge->desc, desc, purge->desc_len) != 0) return 0; } else { if (memcmp(purge->desc, desc, purge->desc_len) != 0) return 0; } printf("%*.*s '%s'\n", (int)tlen, (int)tlen, type, desc); return keyctl_unlink(key, parent) < 0 ? 0 : 1; } /* * Attempt to unlink a key matching the type and description literally */ static int act_keyctl_purge_search_func(key_serial_t parent, key_serial_t keyring, char *raw, int raw_len, void *data) { const struct purge_data *purge = data; key_serial_t key; int kcount = 0; if (!raw || memcmp(raw, "keyring;", 8) != 0) return 0; for (;;) { key = keyctl_search(keyring, purge->type, purge->desc, 0); if (keyctl_unlink(key, keyring) < 0) return kcount; kcount++; } return kcount; } /* * Purge matching keys from a keyring */ static void act_keyctl_purge(int argc, char *argv[]) { recursive_key_scanner_t func; struct purge_data purge = { .prefix_match = 0, .case_indep = 0, }; int n = 0, search_mode = 0; argc--; argv++; while (argc > 0 && argv[0][0] == '-') { if (argv[0][1] == 's') search_mode = 1; else if (argv[0][1] == 'p') purge.prefix_match = 1; else if (argv[0][1] == 'i') purge.case_indep = 1; else format(); argc--; argv++; } if (argc < 1) format(); purge.type = argv[0]; purge.desc = argv[1]; purge.type_len = strlen(purge.type); purge.desc_len = purge.desc ? strlen(purge.desc) : 0; if (search_mode == 1) { if (argc != 2 || purge.prefix_match || purge.case_indep) format(); /* purge all keys of a specific type and description, according * to the kernel's comparator */ func = act_keyctl_purge_search_func; } else if (argc == 1) { if (purge.prefix_match || purge.case_indep) format(); /* purge all keys of a specific type */ func = act_keyctl_purge_type_func; } else if (argc == 2) { /* purge all keys of a specific type with literally matching * description */ func = act_keyctl_purge_literal_func; } else { format(); } n = recursive_session_key_scan(func, &purge); printf("purged %d keys\n", n); exit(0); } /*****************************************************************************/ /* * Invalidate a key */ static void act_keyctl_invalidate(int argc, char *argv[]) { key_serial_t key; if (argc != 2) format(); key = get_key_id(argv[1]); if (keyctl_invalidate(key) < 0) error("keyctl_invalidate"); exit(0); } /*****************************************************************************/ /* * Get the per-UID persistent keyring */ static void act_keyctl_get_persistent(int argc, char *argv[]) { key_serial_t dest, ret; uid_t uid = -1; char *q; if (argc != 2 && argc != 3) format(); dest = get_key_id(argv[1]); if (argc > 2) { uid = strtoul(argv[2], &q, 0); if (*q) { fprintf(stderr, "Unparsable uid: '%s'\n", argv[2]); exit(2); } } ret = keyctl_get_persistent(uid, dest); if (ret < 0) error("keyctl_get_persistent"); /* print the resulting key ID */ printf("%d\n", ret); exit(0); } /*****************************************************************************/ /* * Perform Diffie-Hellman computation */ static void act_keyctl_dh_compute(int argc, char *argv[]) { key_serial_t priv, prime, base; void *buffer; char *p; int ret, sep, col; if (argc != 4) format(); priv = get_key_id(argv[1]); prime = get_key_id(argv[2]); base = get_key_id(argv[3]); ret = keyctl_dh_compute_alloc(priv, prime, base, &buffer); if (ret < 0) error("keyctl_dh_compute_alloc"); /* hexdump the contents */ printf("%u bytes of data in result:\n", ret); sep = 0; col = 0; p = buffer; do { if (sep) { putchar(sep); sep = 0; } printf("%02hhx", *p); *p = 0x00; /* zeroize buffer */ p++; col++; if (col % 32 == 0) sep = '\n'; else if (col % 4 == 0) sep = ' '; } while (--ret > 0); printf("\n"); free(buffer); exit(0); } static void act_keyctl_dh_compute_kdf(int argc, char *argv[]) { key_serial_t private, prime, base; char *buffer; char *p; int ret, sep, col; unsigned long buflen = 0; if (argc != 6) format(); private = get_key_id(argv[1]); prime = get_key_id(argv[2]); base = get_key_id(argv[3]); buflen = strtoul(argv[4], NULL, 10); if (buflen == ULONG_MAX) error("dh_compute: cannot convert generated length value"); buffer = malloc(buflen); if (!buffer) error("dh_compute: cannot allocate memory"); ret = keyctl_dh_compute_kdf(private, prime, base, argv[5], NULL, 0, buffer, buflen); if (ret < 0) error("keyctl_dh_compute_kdf"); /* hexdump the contents */ printf("%u bytes of data in result:\n", ret); sep = 0; col = 0; p = buffer; do { if (sep) { putchar(sep); sep = 0; } printf("%02hhx", *p); *p = 0x00; /* zeroize buffer */ p++; col++; if (col % 32 == 0) sep = '\n'; else if (col % 4 == 0) sep = ' '; } while (--ret > 0); printf("\n"); free(buffer); exit(0); } static void act_keyctl_dh_compute_kdf_oi(int argc, char *argv[]) { key_serial_t private, prime, base; char *buffer; char *p; int ret, sep, col; unsigned long buflen = 0; size_t oilen; void *oi; bool as_hex = false; if (argc > 1 && strcmp(argv[1], "-x") == 0) { as_hex = true; argc--; argv++; } if (argc != 6) format(); private = get_key_id(argv[1]); prime = get_key_id(argv[2]); base = get_key_id(argv[3]); buflen = strtoul(argv[4], NULL, 10); if (buflen == ULONG_MAX) error("dh_compute: cannot convert generated length value"); buffer = malloc(buflen); if (!buffer) error("dh_compute: cannot allocate memory"); oi = grab_stdin(&oilen); hex2bin(&oi, &oilen, as_hex); ret = keyctl_dh_compute_kdf(private, prime, base, argv[5], oi, oilen, buffer, buflen); try_wipe_memory(oi, oilen); if (ret < 0) error("keyctl_dh_compute_kdf"); /* hexdump the contents */ printf("%u bytes of data in result:\n", ret); sep = 0; col = 0; p = buffer; do { if (sep) { putchar(sep); sep = 0; } printf("%02hhx", *p); *p = 0x00; /* zeroize buffer */ p++; col++; if (col % 32 == 0) sep = '\n'; else if (col % 4 == 0) sep = ' '; } while (--ret > 0); printf("\n"); free(buffer); exit(0); } /*****************************************************************************/ /* * Restrict the keys that may be added to a keyring */ static void act_keyctl_restrict_keyring(int argc, char *argv[]) { key_serial_t keyring; char *type = NULL; char *restriction = NULL; long ret; if (argc < 2 || argc > 4) format(); keyring = get_key_id(argv[1]); if (argc > 2) type = argv[2]; if (argc == 4) restriction = argv[3]; ret = keyctl_restrict_keyring(keyring, type, restriction); if (ret < 0) error("keyctl_restrict_keyring"); exit(0); } /* * Parse public key operation info arguments. */ static void pkey_parse_info(char **argv, char info[4096]) { int i_len = 0; /* A number of key=val pairs can be provided after the main arguments * to inform the kernel of things like encoding type and hash function. */ for (; *argv; argv++) { int n = strlen(argv[0]); if (!memchr(argv[0], '=', n)) { fprintf(stderr, "Option not in key=val form\n"); exit(2); } if (n + 1 > 4096 - 1 - i_len) { fprintf(stderr, "Too many info options\n"); exit(2); } if (i_len > 0) info[i_len++] = ' '; memcpy(info + i_len, argv[0], n); i_len += n; } info[i_len] = 0; } /* * Query a public key. */ static void act_keyctl_pkey_query(int argc, char *argv[]) { struct keyctl_pkey_query result; key_serial_t key; char info[4096]; if (argc < 3) format(); pkey_parse_info(argv + 3, info); key = get_key_id(argv[1]); if (strcmp(argv[2], "0") != 0) { fprintf(stderr, "Password passing is not yet supported\n"); exit(2); } if (keyctl_pkey_query(key, info, &result) < 0) error("keyctl_pkey_query"); printf("key_size=%u\n", result.key_size); printf("max_data_size=%u\n", result.max_data_size); printf("max_sig_size=%u\n", result.max_sig_size); printf("max_enc_size=%u\n", result.max_enc_size); printf("max_dec_size=%u\n", result.max_dec_size); printf("encrypt=%c\n", result.supported_ops & KEYCTL_SUPPORTS_ENCRYPT ? 'y' : 'n'); printf("decrypt=%c\n", result.supported_ops & KEYCTL_SUPPORTS_DECRYPT ? 'y' : 'n'); printf("sign=%c\n", result.supported_ops & KEYCTL_SUPPORTS_SIGN ? 'y' : 'n'); printf("verify=%c\n", result.supported_ops & KEYCTL_SUPPORTS_VERIFY ? 'y' : 'n'); exit(0); } /* * Encrypt a blob. */ static void act_keyctl_pkey_encrypt(int argc, char *argv[]) { struct keyctl_pkey_query result; key_serial_t key; size_t in_len; long out_len; void *in, *out; char info[4096]; if (argc < 4) format(); pkey_parse_info(argv + 4, info); key = get_key_id(argv[1]); if (strcmp(argv[2], "0") != 0) { fprintf(stderr, "Password passing is not yet supported\n"); exit(2); } in = read_file(argv[3], &in_len); if (keyctl_pkey_query(key, info, &result) < 0) error("keyctl_pkey_query"); out = malloc(result.max_dec_size); if (!out) error("malloc"); out_len = keyctl_pkey_encrypt(key, info, in, in_len, out, result.max_dec_size); if (out_len < 0) error("keyctl_pkey_encrypt"); if (fwrite(out, out_len, 1, stdout) != 1) error("stdout"); exit(0); } /* * Decrypt a blob. */ static void act_keyctl_pkey_decrypt(int argc, char *argv[]) { struct keyctl_pkey_query result; key_serial_t key; size_t in_len; long out_len; void *in, *out; char info[4096]; if (argc < 4) format(); pkey_parse_info(argv + 4, info); key = get_key_id(argv[1]); if (strcmp(argv[2], "0") != 0) { fprintf(stderr, "Password passing is not yet supported\n"); exit(2); } in = read_file(argv[3], &in_len); if (keyctl_pkey_query(key, info, &result) < 0) error("keyctl_pkey_query"); out = malloc(result.max_enc_size); if (!out) error("malloc"); out_len = keyctl_pkey_decrypt(key, info, in, in_len, out, result.max_enc_size); if (out_len < 0) error("keyctl_pkey_decrypt"); if (fwrite(out, out_len, 1, stdout) != 1) error("stdout"); exit(0); } /* * Create a signature */ static void act_keyctl_pkey_sign(int argc, char *argv[]) { struct keyctl_pkey_query result; key_serial_t key; size_t in_len; long out_len; void *in, *out; char info[4096]; if (argc < 4) format(); pkey_parse_info(argv + 4, info); key = get_key_id(argv[1]); if (strcmp(argv[2], "0") != 0) { fprintf(stderr, "Password passing is not yet supported\n"); exit(2); } in = read_file(argv[3], &in_len); if (keyctl_pkey_query(key, info, &result) < 0) error("keyctl_pkey_query"); out = malloc(result.max_sig_size); if (!out) error("malloc"); out_len = keyctl_pkey_sign(key, info, in, in_len, out, result.max_sig_size); if (out_len < 0) error("keyctl_pkey_sign"); if (fwrite(out, out_len, 1, stdout) != 1) error("stdout"); exit(0); } /* * Verify a signature. */ static void act_keyctl_pkey_verify(int argc, char *argv[]) { key_serial_t key; size_t data_len, sig_len; void *data, *sig; char info[4096]; if (argc < 5) format(); pkey_parse_info(argv + 5, info); key = get_key_id(argv[1]); if (strcmp(argv[2], "0") != 0) { fprintf(stderr, "Password passing is not yet supported\n"); exit(2); } data = read_file(argv[3], &data_len); sig = read_file(argv[4], &sig_len); if (keyctl_pkey_verify(key, info, data, data_len, sig, sig_len) < 0) error("keyctl_pkey_verify"); exit(0); } /* * Move a key between keyrings. */ static void act_keyctl_move(int argc, char *argv[]) { key_serial_t key, from_keyring, to_keyring; unsigned int flags = KEYCTL_MOVE_EXCL; if (argc > 4) { if (strcmp("-f", argv[1]) == 0) { flags &= ~KEYCTL_MOVE_EXCL; argc--; argv++; } } if (argc != 4) format(); key = get_key_id(argv[1]); from_keyring = get_key_id(argv[2]); to_keyring = get_key_id(argv[3]); if (keyctl_move(key, from_keyring, to_keyring, flags) < 0) error("keyctl_move"); exit(0); } struct capability_def { const char *name; /* Textual name of capability */ unsigned int index; /* Index in capabilities array */ unsigned char mask; /* Mask on capabilities array element */ }; static const struct capability_def capabilities[] = { { "capabilities", 0, KEYCTL_CAPS0_CAPABILITIES }, { "persistent_keyrings", 0, KEYCTL_CAPS0_PERSISTENT_KEYRINGS }, { "dh_compute", 0, KEYCTL_CAPS0_DIFFIE_HELLMAN }, { "public_key", 0, KEYCTL_CAPS0_PUBLIC_KEY }, { "big_key_type", 0, KEYCTL_CAPS0_BIG_KEY }, { "key_invalidate", 0, KEYCTL_CAPS0_INVALIDATE }, { "restrict_keyring", 0, KEYCTL_CAPS0_RESTRICT_KEYRING }, { "move_key", 0, KEYCTL_CAPS0_MOVE }, { "ns_keyring_name", 1, KEYCTL_CAPS1_NS_KEYRING_NAME }, { "ns_key_tag", 1, KEYCTL_CAPS1_NS_KEY_TAG }, { "notify", 1, KEYCTL_CAPS1_NOTIFICATIONS }, {} }; /* * Detect/list capabilities. */ static void act_keyctl_supports(int argc, char *argv[]) { const struct capability_def *p; unsigned char caps[256]; size_t len; int i; if (argc < 1 || argc > 2) format(); len = keyctl_capabilities(caps, sizeof(caps)); if (len < 0) error("keyctl_capabilities"); if (argc == 1) { for (p = capabilities; p->name; p++) printf("have_%s=%c\n", p->name, (caps[p->index] & p->mask) ? '1' : '0'); exit(0); } else { if (strcmp(argv[1], "--raw") == 0) { for (i = 0; i < len; i++) printf("%02x", caps[i]); printf("\n"); } for (p = capabilities; p->name; p++) if (strcmp(argv[1], p->name) == 0) exit((caps[p->index] & p->mask) ? 0 : 1); exit(3); } } /*****************************************************************************/ /* * parse a key identifier */ key_serial_t get_key_id(char *arg) { key_serial_t id; char *end; /* handle a special keyring name */ if (arg[0] == '@') { if (strcmp(arg, "@t" ) == 0) return KEY_SPEC_THREAD_KEYRING; if (strcmp(arg, "@p" ) == 0) return KEY_SPEC_PROCESS_KEYRING; if (strcmp(arg, "@s" ) == 0) return KEY_SPEC_SESSION_KEYRING; if (strcmp(arg, "@u" ) == 0) return KEY_SPEC_USER_KEYRING; if (strcmp(arg, "@us") == 0) return KEY_SPEC_USER_SESSION_KEYRING; if (strcmp(arg, "@g" ) == 0) return KEY_SPEC_GROUP_KEYRING; if (strcmp(arg, "@a" ) == 0) return KEY_SPEC_REQKEY_AUTH_KEY; fprintf(stderr, "Unknown special key: '%s'\n", arg); exit(2); } /* handle a lookup-by-name request "%:", eg: "%keyring:_ses" */ if (arg[0] == '%') { char *type; arg++; if (!*arg) goto incorrect_key_by_name_spec; if (*arg == ':') { type = "keyring"; arg++; } else { type = arg; arg = strchr(arg, ':'); if (!arg) goto incorrect_key_by_name_spec; *(arg++) = '\0'; } if (!*arg) goto incorrect_key_by_name_spec; id = find_key_by_type_and_desc(type, arg, 0); if (id == -1) { fprintf(stderr, "Can't find '%s:%s'\n", type, arg); exit(1); } return id; } /* handle a numeric key ID */ id = strtoul(arg, &end, 0); if (*end) { fprintf(stderr, "Unparsable key: '%s'\n", arg); exit(2); } return id; incorrect_key_by_name_spec: fprintf(stderr, "Incorrect key-by-name spec\n"); exit(2); } /* end get_key_id() */ /* * Read the contents of a file into a buffer and return it. */ static void *read_file(const char *name, size_t *_size) { struct stat st; ssize_t r; void *p; int fd; fd = open(name, O_RDONLY); if (fd < 0) error(name); if (fstat(fd, &st) < 0) error(name); p = malloc(st.st_size); if (!p) error("malloc"); r = read(fd, p, st.st_size); if (r == -1) error(name); if (r != st.st_size) { fprintf(stderr, "%s: Short read\n", name); exit(1); } if (close(fd) < 0) error(name); *_size = st.st_size; return p; } /*****************************************************************************/ /* * recursively display a key/keyring tree */ static int dump_key_tree_aux(key_serial_t key, int depth, int more, int hex_key_IDs) { static char dumpindent[64]; key_serial_t *pk; key_perm_t perm; size_t ringlen; void *payload; char *desc, type[255], pretty_mask[9]; int uid, gid, ret, n, dpos, rdepth, kcount = 0; if (depth > 8 * 4) return 0; /* read the description */ ret = keyctl_describe_alloc(key, &desc); if (ret < 0) { printf("%d: key inaccessible (%m)\n", key); return 0; } /* parse */ type[0] = 0; uid = 0; gid = 0; perm = 0; n = sscanf(desc, "%[^;];%d;%d;%x;%n", type, &uid, &gid, &perm, &dpos); if (n != 4) { fprintf(stderr, "Unparsable description obtained for key %d\n", key); exit(3); } /* and print */ calc_perms(pretty_mask, perm, uid, gid); if (hex_key_IDs) printf("0x%08x %s %5d %5d %s%s%s: %s\n", key, pretty_mask, uid, gid, dumpindent, depth > 0 ? "\\_ " : "", type, desc + dpos); else printf("%10d %s %5d %5d %s%s%s: %s\n", key, pretty_mask, uid, gid, dumpindent, depth > 0 ? "\\_ " : "", type, desc + dpos); free(desc); /* if it's a keyring then we're going to want to recursively * display it if we can */ if (strcmp(type, "keyring") == 0) { /* read its contents */ ret = keyctl_read_alloc(key, &payload); if (ret < 0) error("keyctl_read_alloc"); ringlen = ret; kcount = ringlen / sizeof(key_serial_t); /* walk the keyring */ pk = payload; while (ringlen >= sizeof(key_serial_t)) { key = *pk++; /* recurse into next keyrings */ if (strcmp(type, "keyring") == 0) { if (depth == 0) { rdepth = depth; dumpindent[rdepth++] = ' '; dumpindent[rdepth] = 0; } else { rdepth = depth; dumpindent[rdepth++] = ' '; dumpindent[rdepth++] = ' '; dumpindent[rdepth++] = ' '; dumpindent[rdepth++] = ' '; dumpindent[rdepth] = 0; } if (more) dumpindent[depth + 0] = '|'; kcount += dump_key_tree_aux(key, rdepth, ringlen - 4 >= sizeof(key_serial_t), hex_key_IDs); } ringlen -= sizeof(key_serial_t); } free(payload); } return kcount; } /* end dump_key_tree_aux() */ /*****************************************************************************/ /* * recursively list a keyring's contents */ static int dump_key_tree(key_serial_t keyring, const char *name, int hex_key_IDs) { printf("%s\n", name); keyring = keyctl_get_keyring_ID(keyring, 0); if (keyring == -1) error("Unable to dump key"); return dump_key_tree_aux(keyring, 0, 0, hex_key_IDs); } /* end dump_key_tree() */ keyutils-1.6.3/keyctl.h000066400000000000000000000022431370111642500150370ustar00rootroot00000000000000/* keyctl program definitions * * Copyright (C) 2019 Red Hat, Inc. All Rights Reserved. * Written by David Howells (dhowells@redhat.com) * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public Licence * as published by the Free Software Foundation; either version * 2 of the Licence, or (at your option) any later version. */ struct command { void (*action)(int argc, char *argv[]) __attribute__((noreturn)); const char *name; const char *format; }; #define nr __attribute__((noreturn)) /* * keyctl.c */ extern nr void do_command(int, char **, const struct command *, const char *); extern nr void format(void) __attribute__((noreturn)); extern nr void error(const char *) __attribute__((noreturn)); extern key_serial_t get_key_id(char *); /* * keyctl_testing.c */ extern nr void act_keyctl_test(int, char *[]); /* * keyctl_watch.c */ extern nr void act_keyctl_watch(int , char *[]); extern nr void act_keyctl_watch_add(int , char *[]); extern nr void act_keyctl_watch_rm(int , char *[]); extern nr void act_keyctl_watch_session(int , char *[]); extern nr void act_keyctl_watch_sync(int , char *[]); keyutils-1.6.3/keyctl_testing.c000066400000000000000000000122601370111642500165670ustar00rootroot00000000000000/* Tests built into the keyctl program * * Copyright (C) 2019 Red Hat, Inc. All Rights Reserved. * Written by David Howells (dhowells@redhat.com) * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public Licence * as published by the Free Software Foundation; either version * 2 of the Licence, or (at your option) any later version. */ #define _GNU_SOURCE #include #include #include #include #include #include #include #include #include #include #include #include #include "keyutils.h" #include #include "keyctl.h" static nr void act_keyctl_test_limits(int, char *[]); static nr void act_keyctl_test_limits2(int, char *[]); static const struct command test_commands[] = { { act_keyctl_test_limits, "limits", "" }, { act_keyctl_test_limits2, "limits2", "" }, { NULL, NULL, NULL } }; static void test_format(void) __attribute__((noreturn)); static void test_format(void) { const struct command *cmd; fprintf(stderr, "Format:\n"); for (cmd = test_commands; cmd->name; cmd++) fprintf(stderr, " keyctl --test %s %s\n", cmd->name, cmd->format); fprintf(stderr, "\n"); fprintf(stderr, "Key/keyring ID:\n"); fprintf(stderr, " numeric keyring ID\n"); fprintf(stderr, " @t thread keyring\n"); fprintf(stderr, " @p process keyring\n"); fprintf(stderr, " @s session keyring\n"); fprintf(stderr, " @u user keyring\n"); fprintf(stderr, " @us user default session keyring\n"); fprintf(stderr, " @g group keyring\n"); fprintf(stderr, " @a assumed request_key authorisation key\n"); fprintf(stderr, "\n"); fprintf(stderr, " can be \"user\" for a user-defined keyring\n"); fprintf(stderr, "If you do this, prefix the description with \":\"\n"); exit(2); } /* * Provide some testing functions for "keyctl --test" */ void act_keyctl_test(int argc, char *argv[]) { if (argc < 2) test_format(); do_command(argc, argv, test_commands, "test "); } /* * Test the limits of the type and description fields in add_user(). */ static void act_keyctl_test_limits(int argc, char *argv[]) { key_serial_t key; char buf[8192]; int i, nr_fail = 0; if (argc != 1) test_format(); setvbuf(stdout, NULL, _IONBF, 0); for (i = 0; i < sizeof(buf); i++) { if (i % 32 == 0) { if (i != 0) putchar('\n'); printf("TEST SIZE %d", i); } buf[i] = 0; putchar('.'); if (add_key(buf, "wibble", "a", 1, KEY_SPEC_THREAD_KEYRING) == -1) { if (i == 0 || i >= 32) { if (errno != EINVAL) { putchar('\n'); fprintf(stderr, "%d type failed: %m\n", i); nr_fail++; } } else { if (errno != ENODEV) { putchar('\n'); fprintf(stderr, "%d type failed: %m\n", i); nr_fail++; } } } else { putchar('\n'); fprintf(stderr, "%d type unexpectedly succeeded\n", i); nr_fail++; } putchar('_'); key = add_key("user", buf, "a", 1, KEY_SPEC_THREAD_KEYRING); if (key == -1) { if (i == 0 || i >= 4096) { if (errno != EINVAL) { putchar('\n'); fprintf(stderr, "%d desc failed: %m\n", i); nr_fail++; } } else { putchar('\n'); fprintf(stderr, "%d desc wrong error: %m\n", i); nr_fail++; } } else { if (i == 0 || i >= 4096) { putchar('\n'); fprintf(stderr, "%d desc unexpectedly succeeded\n", i); nr_fail++; } if (keyctl_unlink(key, KEY_SPEC_THREAD_KEYRING) == -1) { putchar('\n'); fprintf(stderr, "Unlink failed: %m\n"); nr_fail++; } } buf[i] = 'a'; if (nr_fail > 20) { fprintf(stderr, "Aborting with too many failures\n"); exit(1); } } putchar('\n'); exit(nr_fail ? 1 : 0); } /* * Test the limits of the payload field in add_user(). The user-type will only * accept sizes in the range 1-32767 bytes, though add_key() will accept up to * just shy of 1MiB. */ static void act_keyctl_test_limits2(int argc, char *argv[]) { key_serial_t key; char buf[1030 * 1024]; int i, nr_fail = 0; if (argc != 1) test_format(); setvbuf(stdout, NULL, _IONBF, 0); memset(buf, 'a', sizeof(buf)); for (i = 0; i < sizeof(buf); i++) { if (i % 2048 == 0) { if (i != 0) putchar('\n'); printf("TEST SIZE %7d ", i); } if (i % (2048 / 32) == 0) putchar('.'); key = add_key("user", "a", buf, i, KEY_SPEC_THREAD_KEYRING); if (key == -1) { if (i == 0 || i > 32767) { if (errno != EINVAL) { putchar('\n'); fprintf(stderr, "%d desc failed: %m\n", i); nr_fail++; } } else if (errno == EDQUOT) { /* This might happen due to us creating keys * really fast. */ } else { putchar('\n'); fprintf(stderr, "%d desc wrong error: %m\n", i); nr_fail++; } } else { if (i == 0 || i > 32767) { putchar('\n'); fprintf(stderr, "%d desc unexpectedly succeeded\n", i); nr_fail++; } if (keyctl_unlink(key, KEY_SPEC_THREAD_KEYRING) == -1) { putchar('\n'); fprintf(stderr, "Unlink failed: %m\n"); nr_fail++; } } if (nr_fail > 20) { fprintf(stderr, "Aborting with too many failures\n"); exit(1); } } putchar('\n'); exit(nr_fail ? 1 : 0); } keyutils-1.6.3/keyctl_watch.c000066400000000000000000000267631370111642500162350ustar00rootroot00000000000000/* Key watching facility. * * Copyright (C) 2019 Red Hat, Inc. All Rights Reserved. * Written by David Howells (dhowells@redhat.com) * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public Licence * as published by the Free Software Foundation; either version * 2 of the Licence, or (at your option) any later version. */ #define _GNU_SOURCE #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "keyutils.h" #include #include "keyctl.h" #include "watch_queue.h" #define MAX_MESSAGE_COUNT 256 static int consumer_stop; static pid_t pid_con = -1, pid_cmd = -1; static key_serial_t session; static int watch_fd; static int debug; static struct watch_notification_filter filter = { .nr_filters = 0, .filters = { /* Reserve a slot */ [0] = { .type = WATCH_TYPE_KEY_NOTIFY, }, }, }; static inline bool after_eq(unsigned int a, unsigned int b) { return (signed int)(a - b) >= 0; } static void consumer_term(int sig) { consumer_stop = 1; } static void saw_key_change(FILE *log, struct watch_notification *n, unsigned int len) { struct key_notification *k = (struct key_notification *)n; if (len != sizeof(struct key_notification)) return; switch (n->subtype) { case NOTIFY_KEY_INSTANTIATED: fprintf(log, "%u inst\n", k->key_id); break; case NOTIFY_KEY_UPDATED: fprintf(log, "%u upd\n", k->key_id); break; case NOTIFY_KEY_LINKED: fprintf(log, "%u link %u\n", k->key_id, k->aux); break; case NOTIFY_KEY_UNLINKED: fprintf(log, "%u unlk %u\n", k->key_id, k->aux); break; case NOTIFY_KEY_CLEARED: fprintf(log, "%u clr\n", k->key_id); break; case NOTIFY_KEY_REVOKED: fprintf(log, "%u rev\n", k->key_id); break; case NOTIFY_KEY_INVALIDATED: fprintf(log, "%u inv\n", k->key_id); break; case NOTIFY_KEY_SETATTR: fprintf(log, "%u attr\n", k->key_id); break; } } /* * Handle removal notification. */ static void saw_removal_notification(FILE *gc, struct watch_notification *n, unsigned int len) { key_serial_t key = 0; unsigned int wp; wp = (n->info & WATCH_INFO_ID) >> WATCH_INFO_ID__SHIFT; if (len >= sizeof(struct watch_notification_removal)) { struct watch_notification_removal *r = (void *)n; key = r->id; } fprintf(gc, "%u gc\n", key); if (wp == 1) exit(0); } /* * Consume and display events. */ static __attribute__((noreturn)) int consumer(FILE *log, FILE *gc, int fd) { unsigned char buffer[433], *p, *end; union { struct watch_notification n; unsigned char buf1[128]; } n; ssize_t buf_len; setlinebuf(log); setlinebuf(gc); signal(SIGTERM, consumer_term); do { if (!consumer_stop) { struct pollfd pf[1]; pf[0].fd = fd; pf[0].events = POLLIN; pf[0].revents = 0; if (poll(pf, 1, -1) == -1) { if (errno == EINTR) continue; error("poll"); } } buf_len = read(fd, buffer, sizeof(buffer)); if (buf_len == -1) { perror("read"); exit(1); } if (buf_len == 0) { printf("-- END --\n"); exit(0); } if (buf_len > sizeof(buffer)) { fprintf(stderr, "Read buffer overrun: %zd\n", buf_len); exit(4); } if (debug) fprintf(stderr, "read() = %zd\n", buf_len); p = buffer; end = buffer + buf_len; while (p < end) { size_t largest, len; largest = end - p; if (largest > 128) largest = 128; if (largest < sizeof(struct watch_notification)) { fprintf(stderr, "Short message header: %zu\n", largest); exit(4); } memcpy(&n, p, largest); if (debug) fprintf(stderr, "NOTIFY[%03zx]: ty=%06x sy=%02x i=%08x\n", p - buffer, n.n.type, n.n.subtype, n.n.info); len = n.n.info & WATCH_INFO_LENGTH; if (len < sizeof(n.n) || len > largest) { fprintf(stderr, "Bad message length: %zu/%zu\n", len, largest); exit(1); } switch (n.n.type) { case WATCH_TYPE_META: switch (n.n.subtype) { case WATCH_META_REMOVAL_NOTIFICATION: saw_removal_notification(gc, &n.n, len); break; case WATCH_META_LOSS_NOTIFICATION: fprintf(log, "-- LOSS --\n"); break; default: if (debug) fprintf(stderr, "other meta record\n"); break; } break; case WATCH_TYPE_KEY_NOTIFY: saw_key_change(log, &n.n, len); break; default: if (debug) fprintf(stderr, "other type\n"); break; } p += len; } } while (!consumer_stop); fprintf(log, "Monitoring terminated\n"); if (gc != log) fprintf(gc, "Monitoring terminated\n"); exit(0); } /* * Open the watch device and allocate a buffer. */ static int open_watch(void) { int pipefd[2], fd; if (pipe2(pipefd, O_NOTIFICATION_PIPE | O_NONBLOCK) == -1) error("pipe2"); fd = pipefd[0]; if (ioctl(fd, IOC_WATCH_QUEUE_SET_SIZE, MAX_MESSAGE_COUNT) == -1) error("/dev/watch_queue(size)"); if (filter.nr_filters && ioctl(fd, IOC_WATCH_QUEUE_SET_FILTER, &filter) == -1) error("/dev/watch_queue(filter)"); return fd; } /* * Parse a filter character representation into a subtype number. */ static bool parse_subtype(struct watch_notification_type_filter *t, char filter) { static const char filter_mapping[] = "i" /* 0 NOTIFY_KEY_INSTANTIATED */ "p" /* 1 NOTIFY_KEY_UPDATED */ "l" /* 2 NOTIFY_KEY_LINKED */ "n" /* 3 NOTIFY_KEY_UNLINKED */ "c" /* 4 NOTIFY_KEY_CLEARED */ "r" /* 5 NOTIFY_KEY_REVOKED */ "v" /* 6 NOTIFY_KEY_INVALIDATED */ "s" /* 7 NOTIFY_KEY_SETATTR */ ; const char *p; unsigned int st_bits; unsigned int st_index; unsigned int st_bit; int subtype; p = strchr(filter_mapping, filter); if (!p) return false; subtype = p - filter_mapping; st_bits = sizeof(t->subtype_filter[0]) * 8; st_index = subtype / st_bits; st_bit = 1U << (subtype % st_bits); t->subtype_filter[st_index] |= st_bit; return true; } /* * Parse filters. */ static void parse_watch_filter(char *str) { struct watch_notification_filter *f = &filter; struct watch_notification_type_filter *t0 = &f->filters[0]; f->nr_filters = 1; t0->type = WATCH_TYPE_KEY_NOTIFY; for (; *str; str++) { if (parse_subtype(t0, *str)) continue; fprintf(stderr, "Unknown filter character '%c'\n", *str); exit(2); } } /* * Watch a key or keyring for changes. */ void act_keyctl_watch(int argc, char *argv[]) { key_serial_t key; int wfd, opt; while (opt = getopt(argc, argv, "f:"), opt != -1) { switch (opt) { case 'f': parse_watch_filter(optarg); break; default: fprintf(stderr, "Unknown option\n"); exit(2); } } argv += optind; argc -= optind; if (argc != 1) format(); key = get_key_id(argv[0]); wfd = open_watch(); if (keyctl_watch_key(key, wfd, 0x01) == -1) error("keyctl_watch_key"); consumer(stdout, stdout, wfd); } /* * Add a watch on a key to the monitor created by watch_session. */ void act_keyctl_watch_add(int argc, char *argv[]) { key_serial_t key; int fd; if (argc != 3) format(); fd = atoi(argv[1]); key = get_key_id(argv[2]); if (keyctl_watch_key(key, fd, 0x02) == -1) error("keyctl_watch_key"); exit(0); } /* * Remove a watch on a key from the monitor created by watch_session. */ void act_keyctl_watch_rm(int argc, char *argv[]) { key_serial_t key; int fd; if (argc != 3) format(); fd = atoi(argv[1]); key = get_key_id(argv[2]); if (keyctl_watch_key(key, fd, -1) == -1) error("keyctl_watch_key"); exit(0); } static void exit_cleanup(void) { pid_t me = getpid(); int w; if (me != pid_cmd && me != pid_con) { keyctl_watch_key(session, watch_fd, -1); if (pid_cmd != -1) { kill(pid_cmd, SIGTERM); waitpid(pid_cmd, &w, 0); } if (pid_con != -1) { kill(pid_con, SIGTERM); waitpid(pid_con, &w, 0); } } } static void run_command(int argc, char *argv[], int wfd) { char buf[16]; pid_cmd = fork(); if (pid_cmd == -1) error("fork"); if (pid_cmd != 0) return; pid_cmd = -1; pid_con = -1; sprintf(buf, "%u", wfd); setenv("KEYCTL_WATCH_FD", buf, true); /* run the standard shell if no arguments */ if (argc == 0) { const char *q = getenv("SHELL"); if (!q) q = "/bin/sh"; execl(q, q, NULL); error(q); } /* run the command specified */ execvp(argv[0], argv); error(argv[0]); } /* * Open a logfiles. */ static FILE *open_logfile(const char *logfile) { unsigned int flags; FILE *log; int lfd; log = fopen(logfile, "a"); if (!log) error(logfile); lfd = fileno(log); flags = fcntl(lfd, F_GETFD); if (flags == -1) error("F_GETFD"); if (fcntl(lfd, F_SETFD, flags | FD_CLOEXEC) == -1) error("F_SETFD"); return log; } /* * Set up a new session keyring with a monitor that is exposed on an explicit * file descriptor in the program that it starts. */ void act_keyctl_watch_session(int argc, char *argv[]) { const char *session_name = NULL; const char *logfile, *gcfile, *target_fd; unsigned int flags; pid_t pid; FILE *log, *gc; int wfd, tfd, opt, w, e = 0, e2 = 0; while (opt = getopt(argc, argv, "+df:n:"), opt != -1) { switch (opt) { case 'd': debug = 1; break; case 'f': parse_watch_filter(optarg); break; case 'n': session_name = optarg; break; default: fprintf(stderr, "Unknown option\n"); exit(2); } } argv += optind; argc -= optind; if (argc < 4) format(); logfile = argv[0]; gcfile = argv[1]; target_fd = argv[2]; tfd = atoi(target_fd); if (tfd < 3 || tfd > 9) { fprintf(stderr, "The target fd must be between 3 and 9\n"); exit(2); } wfd = open_watch(); if (wfd != tfd) { if (dup2(wfd, tfd) == -1) error("dup2"); close(wfd); wfd = tfd; } watch_fd = wfd; atexit(exit_cleanup); /* We want the fd to be inherited across a fork. */ flags = fcntl(wfd, F_GETFD); if (flags == -1) error("F_GETFD"); if (fcntl(wfd, F_SETFD, flags & ~FD_CLOEXEC) == -1) error("F_SETFD"); log = open_logfile(logfile); gc = open_logfile(gcfile); pid_con = fork(); if (pid_con == -1) error("fork"); if (pid_con == 0) { pid_cmd = -1; pid_con = -1; consumer(log, gc, wfd); } /* Create a new session keyring and watch it. */ session = keyctl_join_session_keyring(session_name); if (session == -1) error("keyctl_join_session_keyring"); if (keyctl_watch_key(session, wfd, 0x01) == -1) error("keyctl_watch_key/session"); fprintf(stderr, "Joined session keyring: %d\n", session); /* Start the command and then wait for it to finish and the * notification consumer to clean up. */ run_command(argc - 3, argv + 3, wfd); close(wfd); wfd = -1; while (pid = wait(&w), pid != -1) { if (pid == pid_cmd) { if (pid_con != -1) kill(pid_con, SIGTERM); if (WIFEXITED(w)) { e2 = WEXITSTATUS(w); pid_cmd = -1; } else if (WIFSIGNALED(w)) { e2 = WTERMSIG(w) + 128; pid_cmd = -1; } else if (WIFSTOPPED(w)) { raise(WSTOPSIG(w)); } } else if (pid == pid_con) { if (pid_cmd != -1) kill(pid_cmd, SIGTERM); if (WIFEXITED(w)) { e = WEXITSTATUS(w); pid_con = -1; } else if (WIFSIGNALED(w)) { e = WTERMSIG(w) + 128; pid_con = -1; } } } if (e == 0) e = e2; exit(e); } /* * Wait for monitoring to synchronise. */ void act_keyctl_watch_sync(int argc, char *argv[]) { long ret; int wfd, count; if (argc != 2) format(); wfd = atoi(argv[1]); ret = ioctl(wfd, PIPE_IOC_SYNC); if (ret == 0) exit(0); if (ret == -1 && errno != ENOTTY) error("ioctl(PIPE_IOC_SYNC)"); for (;;) { ret = ioctl(wfd, FIONREAD, &count); if (ret == -1) error("ioctl(FIONREAD)"); if (count == 0) break; usleep(200 * 1000); } exit(0); } keyutils-1.6.3/keyutils.c000066400000000000000000000452651370111642500154230ustar00rootroot00000000000000/* keyutils.c: key utility library * * Copyright (C) 2005,2011 Red Hat, Inc. All Rights Reserved. * Written by David Howells (dhowells@redhat.com) * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License * as published by the Free Software Foundation; either version * 2 of the License, or (at your option) any later version. */ #include #include #include #include #include #include #include #include #include #include #include "keyutils.h" const char keyutils_version_string[] = PKGVERSION; const char keyutils_build_string[] = PKGBUILD; #ifdef NO_GLIBC_KEYERR static int error_inited; static void (*libc_perror)(const char *msg); static char *(*libc_strerror_r)(int errnum, char *buf, size_t n); //static int (*libc_xpg_strerror_r)(int errnum, char *buf, size_t n); #define RTLD_NEXT ((void *) -1L) #endif #define __weak __attribute__((weak)) key_serial_t __weak add_key(const char *type, const char *description, const void *payload, size_t plen, key_serial_t ringid) { return syscall(__NR_add_key, type, description, payload, plen, ringid); } key_serial_t __weak request_key(const char *type, const char *description, const char * callout_info, key_serial_t destringid) { return syscall(__NR_request_key, type, description, callout_info, destringid); } static inline long __keyctl(int cmd, unsigned long arg2, unsigned long arg3, unsigned long arg4, unsigned long arg5) { return syscall(__NR_keyctl, cmd, arg2, arg3, arg4, arg5); } long __weak keyctl(int cmd, ...) { va_list va; unsigned long arg2, arg3, arg4, arg5; va_start(va, cmd); arg2 = va_arg(va, unsigned long); arg3 = va_arg(va, unsigned long); arg4 = va_arg(va, unsigned long); arg5 = va_arg(va, unsigned long); va_end(va); return __keyctl(cmd, arg2, arg3, arg4, arg5); } key_serial_t keyctl_get_keyring_ID(key_serial_t id, int create) { return keyctl(KEYCTL_GET_KEYRING_ID, id, create); } key_serial_t keyctl_join_session_keyring(const char *name) { return keyctl(KEYCTL_JOIN_SESSION_KEYRING, name); } long keyctl_update(key_serial_t id, const void *payload, size_t plen) { return keyctl(KEYCTL_UPDATE, id, payload, plen); } long keyctl_revoke(key_serial_t id) { return keyctl(KEYCTL_REVOKE, id); } long keyctl_chown(key_serial_t id, uid_t uid, gid_t gid) { return keyctl(KEYCTL_CHOWN, id, uid, gid); } long keyctl_setperm(key_serial_t id, key_perm_t perm) { return keyctl(KEYCTL_SETPERM, id, perm); } long keyctl_describe(key_serial_t id, char *buffer, size_t buflen) { return keyctl(KEYCTL_DESCRIBE, id, buffer, buflen); } long keyctl_clear(key_serial_t ringid) { return keyctl(KEYCTL_CLEAR, ringid); } long keyctl_link(key_serial_t id, key_serial_t ringid) { return keyctl(KEYCTL_LINK, id, ringid); } long keyctl_unlink(key_serial_t id, key_serial_t ringid) { return keyctl(KEYCTL_UNLINK, id, ringid); } long keyctl_search(key_serial_t ringid, const char *type, const char *description, key_serial_t destringid) { return keyctl(KEYCTL_SEARCH, ringid, type, description, destringid); } long keyctl_read(key_serial_t id, char *buffer, size_t buflen) { return keyctl(KEYCTL_READ, id, buffer, buflen); } long keyctl_instantiate(key_serial_t id, const void *payload, size_t plen, key_serial_t ringid) { return keyctl(KEYCTL_INSTANTIATE, id, payload, plen, ringid); } long keyctl_negate(key_serial_t id, unsigned timeout, key_serial_t ringid) { return keyctl(KEYCTL_NEGATE, id, timeout, ringid); } long keyctl_set_reqkey_keyring(int reqkey_defl) { return keyctl(KEYCTL_SET_REQKEY_KEYRING, reqkey_defl); } long keyctl_set_timeout(key_serial_t id, unsigned timeout) { return keyctl(KEYCTL_SET_TIMEOUT, id, timeout); } long keyctl_assume_authority(key_serial_t id) { return keyctl(KEYCTL_ASSUME_AUTHORITY, id); } long keyctl_get_security(key_serial_t id, char *buffer, size_t buflen) { return keyctl(KEYCTL_GET_SECURITY, id, buffer, buflen); } long keyctl_session_to_parent(void) { return keyctl(KEYCTL_SESSION_TO_PARENT); } long keyctl_reject(key_serial_t id, unsigned timeout, unsigned error, key_serial_t ringid) { long ret = keyctl(KEYCTL_REJECT, id, timeout, error, ringid); /* fall back to keyctl_negate() if this op is not supported by this * kernel version */ if (ret == -1 && errno == EOPNOTSUPP) return keyctl_negate(id, timeout, ringid); return ret; } long keyctl_instantiate_iov(key_serial_t id, const struct iovec *payload_iov, unsigned ioc, key_serial_t ringid) { long ret = keyctl(KEYCTL_INSTANTIATE_IOV, id, payload_iov, ioc, ringid); /* fall back to keyctl_instantiate() if this op is not supported by * this kernel version */ if (ret == -1 && errno == EOPNOTSUPP) { unsigned loop; size_t bsize = 0, seg; void *buf, *p; if (!payload_iov || !ioc) return keyctl_instantiate(id, NULL, 0, ringid); for (loop = 0; loop < ioc; loop++) bsize += payload_iov[loop].iov_len; if (bsize == 0) return keyctl_instantiate(id, NULL, 0, ringid); p = buf = malloc(bsize); if (!buf) return -1; for (loop = 0; loop < ioc; loop++) { seg = payload_iov[loop].iov_len; p = memcpy(p, payload_iov[loop].iov_base, seg) + seg; } ret = keyctl_instantiate(id, buf, bsize, ringid); free(buf); } return ret; } long keyctl_invalidate(key_serial_t id) { return keyctl(KEYCTL_INVALIDATE, id); } long keyctl_get_persistent(uid_t uid, key_serial_t id) { return keyctl(KEYCTL_GET_PERSISTENT, uid, id); } long keyctl_dh_compute(key_serial_t priv, key_serial_t prime, key_serial_t base, char *buffer, size_t buflen) { struct keyctl_dh_params params = { .priv = priv, .prime = prime, .base = base }; return keyctl(KEYCTL_DH_COMPUTE, ¶ms, buffer, buflen, 0); } long keyctl_dh_compute_kdf(key_serial_t priv, key_serial_t prime, key_serial_t base, char *hashname, char *otherinfo, size_t otherinfolen, char *buffer, size_t buflen) { struct keyctl_dh_params params = { .priv = priv, .prime = prime, .base = base }; struct keyctl_kdf_params kdfparams = { .hashname = hashname, .otherinfo = otherinfo, .otherinfolen = otherinfolen }; return keyctl(KEYCTL_DH_COMPUTE, ¶ms, buffer, buflen, &kdfparams); } long keyctl_restrict_keyring(key_serial_t keyring, const char *type, const char *restriction) { return keyctl(KEYCTL_RESTRICT_KEYRING, keyring, type, restriction); } long keyctl_pkey_query(key_serial_t key_id, const char *info, struct keyctl_pkey_query *result) { return keyctl(KEYCTL_PKEY_QUERY, key_id, NULL, info, result); } long keyctl_pkey_encrypt(key_serial_t key_id, const char *info, const void *data, size_t data_len, void *enc, size_t enc_len) { struct keyctl_pkey_params params = { .key_id = key_id, .in_len = data_len, .out_len = enc_len, }; return keyctl(KEYCTL_PKEY_ENCRYPT, ¶ms, info, data, enc); } long keyctl_pkey_decrypt(key_serial_t key_id, const char *info, const void *enc, size_t enc_len, void *data, size_t data_len) { struct keyctl_pkey_params params = { .key_id = key_id, .in_len = enc_len, .out_len = data_len, }; return keyctl(KEYCTL_PKEY_DECRYPT, ¶ms, info, enc, data); } long keyctl_pkey_sign(key_serial_t key_id, const char *info, const void *data, size_t data_len, void *sig, size_t sig_len) { struct keyctl_pkey_params params = { .key_id = key_id, .in_len = data_len, .out_len = sig_len, }; return keyctl(KEYCTL_PKEY_SIGN, ¶ms, info, data, sig); } long keyctl_pkey_verify(key_serial_t key_id, const char *info, const void *data, size_t data_len, const void *sig, size_t sig_len) { struct keyctl_pkey_params params = { .key_id = key_id, .in_len = data_len, .in2_len = sig_len, }; return keyctl(KEYCTL_PKEY_VERIFY, ¶ms, info, data, sig); } long keyctl_move(key_serial_t id, key_serial_t from_ringid, key_serial_t to_ringid, unsigned int flags) { return keyctl(KEYCTL_MOVE, id, from_ringid, to_ringid, flags); } long keyctl_capabilities(unsigned char *buffer, size_t buflen) { long n; n = keyctl(KEYCTL_CAPABILITIES, buffer, buflen); if (n != -1 || errno != EOPNOTSUPP) return n; /* Emulate the operation */ if (buflen > 0) { memset(buffer, 0, buflen); errno = 0; keyctl_get_persistent(-1, 0); if (errno != EOPNOTSUPP) buffer[0] |= KEYCTL_CAPS0_PERSISTENT_KEYRINGS; errno = 0; keyctl_dh_compute(0, 0, 0, NULL, 0); if (errno != EOPNOTSUPP) buffer[0] |= KEYCTL_CAPS0_DIFFIE_HELLMAN; errno = 0; keyctl_pkey_query(0, NULL, NULL); if (errno != EOPNOTSUPP) buffer[0] |= KEYCTL_CAPS0_PUBLIC_KEY; /* Can't emulate KEYCTL_CAPS0_BIG_KEY without a valid * destination keyring. */ errno = 0; keyctl_invalidate(0); if (errno != EOPNOTSUPP) buffer[0] |= KEYCTL_CAPS0_INVALIDATE; errno = 0; keyctl_restrict_keyring(0, NULL, NULL); if (errno != EOPNOTSUPP) buffer[0] |= KEYCTL_CAPS0_RESTRICT_KEYRING; errno = 0; keyctl_move(0, 0, 0, 0); if (errno != EOPNOTSUPP) buffer[0] |= KEYCTL_CAPS0_MOVE; } return sizeof(unsigned char); } long keyctl_watch_key(key_serial_t id, int watch_queue_fd, int watch_id) { return keyctl(KEYCTL_WATCH_KEY, id, watch_queue_fd, watch_id); } /*****************************************************************************/ /* * fetch key description into an allocated buffer * - resulting string is NUL terminated * - returns count not including NUL */ int keyctl_describe_alloc(key_serial_t id, char **_buffer) { char *buf; long buflen, ret; ret = keyctl_describe(id, NULL, 0); if (ret < 0) return -1; for (;;) { buflen = ret; buf = malloc(buflen); if (!buf) return -1; ret = keyctl_describe(id, buf, buflen); if (ret < 0) { free(buf); return -1; } if (buflen >= ret) break; free(buf); } *_buffer = buf; return ret - 1; } /*****************************************************************************/ /* * fetch key contents into an allocated buffer * - resulting buffer has an extra NUL added to the end * - returns count (not including extraneous NUL) */ int keyctl_read_alloc(key_serial_t id, void **_buffer) { char *buf; long buflen, ret; ret = keyctl_read(id, NULL, 0); if (ret < 0) return -1; for (;;) { buflen = ret; buf = malloc(buflen + 1); if (!buf) return -1; ret = keyctl_read(id, buf, buflen); if (ret < 0) { free(buf); return -1; } if (buflen >= ret) break; free(buf); } buf[ret] = 0; *_buffer = buf; return ret; } /*****************************************************************************/ /* * fetch key security label into an allocated buffer * - resulting string is NUL terminated * - returns count not including NUL */ int keyctl_get_security_alloc(key_serial_t id, char **_buffer) { char *buf; long buflen, ret; ret = keyctl_get_security(id, NULL, 0); if (ret < 0) return -1; for (;;) { buflen = ret; buf = malloc(buflen); if (!buf) return -1; ret = keyctl_get_security(id, buf, buflen); if (ret < 0) { free(buf); return -1; } if (buflen >= ret) break; free(buf); } *_buffer = buf; return ret - 1; } /*****************************************************************************/ /* * fetch DH computation results into an allocated buffer * - resulting buffer has an extra NUL added to the end * - returns count (not including extraneous NUL) */ int keyctl_dh_compute_alloc(key_serial_t priv, key_serial_t prime, key_serial_t base, void **_buffer) { char *buf; long buflen, ret; ret = keyctl_dh_compute(priv, prime, base, NULL, 0); if (ret < 0) return -1; buflen = ret; buf = malloc(buflen + 1); if (!buf) return -1; ret = keyctl_dh_compute(priv, prime, base, buf, buflen); if (ret < 0) { free(buf); return -1; } buf[ret] = 0; *_buffer = buf; return ret; } /* * Depth-first recursively apply a function over a keyring tree */ static int recursive_key_scan_aux(key_serial_t parent, key_serial_t key, int depth, recursive_key_scanner_t func, void *data) { key_serial_t *pk; key_perm_t perm; size_t ringlen; void *ring; char *desc, type[255]; int desc_len, uid, gid, ret, n, kcount = 0; if (depth > 800) return 0; /* read the key description */ desc = NULL; desc_len = keyctl_describe_alloc(key, &desc); if (desc_len < 0) goto do_this_key; /* parse */ type[0] = 0; n = sscanf(desc, "%[^;];%d;%d;%x;", type, &uid, &gid, &perm); if (n != 4) { free(desc); desc = NULL; errno = -EINVAL; desc_len = -1; goto do_this_key; } /* if it's a keyring then we're going to want to recursively search it * if we can */ if (strcmp(type, "keyring") == 0) { /* read the keyring's contents */ ret = keyctl_read_alloc(key, &ring); if (ret < 0) goto do_this_key; ringlen = ret; /* walk the keyring */ pk = ring; for (ringlen = ret; ringlen >= sizeof(key_serial_t); ringlen -= sizeof(key_serial_t) ) kcount += recursive_key_scan_aux(key, *pk++, depth + 1, func, data); free(ring); } do_this_key: kcount += func(parent, key, desc, desc_len, data); free(desc); return kcount; } /* * Depth-first apply a function over a keyring tree */ int recursive_key_scan(key_serial_t key, recursive_key_scanner_t func, void *data) { return recursive_key_scan_aux(0, key, 0, func, data); } /* * Depth-first apply a function over session keyring tree */ int recursive_session_key_scan(recursive_key_scanner_t func, void *data) { key_serial_t session = keyctl_get_keyring_ID(KEY_SPEC_SESSION_KEYRING, 0); if (session > 0) return recursive_key_scan(session, func, data); return 0; } /* * Find a key by type and description */ key_serial_t find_key_by_type_and_desc(const char *type, const char *desc, key_serial_t destringid) { key_serial_t id, error; FILE *f; char buf[1024], typebuf[40], rdesc[1024], *kdesc, *cp; int n, ndesc, dlen; error = ENOKEY; id = request_key(type, desc, NULL, destringid); if (id >= 0 || errno == ENOMEM) return id; if (errno != ENOKEY) error = errno; dlen = strlen(desc); f = fopen("/proc/keys", "r"); if (!f) { fprintf(stderr, "libkeyutils: Can't open /proc/keys: %m\n"); return -1; } while (fgets(buf, sizeof(buf), f)) { cp = strchr(buf, '\n'); if (*cp) *cp = '\0'; ndesc = 0; n = sscanf(buf, "%x %*s %*u %*s %*x %*d %*d %s %n", &id, typebuf, &ndesc); if (n == 2 && ndesc > 0 && ndesc <= cp - buf) { if (strcmp(typebuf, type) != 0) continue; kdesc = buf + ndesc; if (memcmp(kdesc, desc, dlen) != 0) continue; if (kdesc[dlen] != ':' && kdesc[dlen] != '\0' && kdesc[dlen] != ' ') continue; kdesc[dlen] = '\0'; /* The key type appends extra stuff to the end of the * description after a colon in /proc/keys. Colons, * however, are allowed in descriptions, so we need to * make a further check. */ n = keyctl_describe(id, rdesc, sizeof(rdesc) - 1); if (n == -1) { if (errno != ENOKEY) error = errno; if (errno == ENOMEM) break; } if (n >= sizeof(rdesc) - 1) continue; rdesc[n] = '\0'; cp = strrchr(rdesc, ';'); if (!cp) continue; cp++; if (strcmp(cp, desc) != 0) continue; fclose(f); if (destringid && keyctl_link(id, destringid) == -1) return -1; return id; } } fclose(f); errno = error; return -1; } #ifdef NO_GLIBC_KEYERR /*****************************************************************************/ /* * initialise error handling */ static void error_init(void) { char *err; error_inited = 1; dlerror(); libc_perror = dlsym(RTLD_NEXT,"perror"); if (!libc_perror) { fprintf(stderr, "Failed to look up next perror\n"); err = dlerror(); if (err) fprintf(stderr, "%s\n", err); abort(); } //fprintf(stderr, "next perror at %p\n", libc_perror); libc_strerror_r = dlsym(RTLD_NEXT,"strerror_r"); if (!libc_strerror_r) { fprintf(stderr, "Failed to look up next strerror_r\n"); err = dlerror(); if (err) fprintf(stderr, "%s\n", err); abort(); } //fprintf(stderr, "next strerror_r at %p\n", libc_strerror_r); #if 0 libc_xpg_strerror_r = dlsym(RTLD_NEXT,"xpg_strerror_r"); if (!libc_xpg_strerror_r) { fprintf(stderr, "Failed to look up next xpg_strerror_r\n"); err = dlerror(); if (err) fprintf(stderr, "%s\n", err); abort(); } //fprintf(stderr, "next xpg_strerror_r at %p\n", libc_xpg_strerror_r); #endif } /* end error_init() */ /*****************************************************************************/ /* * overload glibc's strerror_r() with a version that knows about key errors */ char *strerror_r(int errnum, char *buf, size_t n) { const char *errstr; int len; printf("hello\n"); if (!error_inited) error_init(); switch (errnum) { case ENOKEY: errstr = "Requested key not available"; break; case EKEYEXPIRED: errstr = "Key has expired"; break; case EKEYREVOKED: errstr = "Key has been revoked"; break; case EKEYREJECTED: errstr = "Key was rejected by service"; break; default: return libc_strerror_r(errnum, buf, n); } len = strlen(errstr) + 1; if (n > len) { errno = ERANGE; if (n > 0) { memcpy(buf, errstr, n - 1); buf[n - 1] = 0; } return NULL; } else { memcpy(buf, errstr, len); return buf; } } /* end strerror_r() */ #if 0 /*****************************************************************************/ /* * overload glibc's strerror_r() with a version that knows about key errors */ int xpg_strerror_r(int errnum, char *buf, size_t n) { const char *errstr; int len; if (!error_inited) error_init(); switch (errnum) { case ENOKEY: errstr = "Requested key not available"; break; case EKEYEXPIRED: errstr = "Key has expired"; break; case EKEYREVOKED: errstr = "Key has been revoked"; break; case EKEYREJECTED: errstr = "Key was rejected by service"; break; default: return libc_xpg_strerror_r(errnum, buf, n); } len = strlen(errstr) + 1; if (n > len) { errno = ERANGE; if (n > 0) { memcpy(buf, errstr, n - 1); buf[n - 1] = 0; } return -1; } else { memcpy(buf, errstr, len); return 0; } } /* end xpg_strerror_r() */ #endif /*****************************************************************************/ /* * */ void perror(const char *msg) { if (!error_inited) error_init(); switch (errno) { case ENOKEY: fprintf(stderr, "%s: Requested key not available\n", msg); return; case EKEYEXPIRED: fprintf(stderr, "%s: Key has expired\n", msg); return; case EKEYREVOKED: fprintf(stderr, "%s: Key has been revoked\n", msg); return; case EKEYREJECTED: fprintf(stderr, "%s: Key was rejected by service\n", msg); return; default: libc_perror(msg); return; } } /* end perror() */ #endif keyutils-1.6.3/keyutils.h000066400000000000000000000270241370111642500154210ustar00rootroot00000000000000/* keyutils.h: key utility library interface * * Copyright (C) 2005,2011 Red Hat, Inc. All Rights Reserved. * Written by David Howells (dhowells@redhat.com) * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License * as published by the Free Software Foundation; either version * 2 of the License, or (at your option) any later version. */ #ifndef KEYUTILS_H #define KEYUTILS_H #include #include #ifdef __cplusplus extern "C" { #endif extern const char keyutils_version_string[]; extern const char keyutils_build_string[]; /* key serial number */ typedef int32_t key_serial_t; /* special process keyring shortcut IDs */ #define KEY_SPEC_THREAD_KEYRING -1 /* - key ID for thread-specific keyring */ #define KEY_SPEC_PROCESS_KEYRING -2 /* - key ID for process-specific keyring */ #define KEY_SPEC_SESSION_KEYRING -3 /* - key ID for session-specific keyring */ #define KEY_SPEC_USER_KEYRING -4 /* - key ID for UID-specific keyring */ #define KEY_SPEC_USER_SESSION_KEYRING -5 /* - key ID for UID-session keyring */ #define KEY_SPEC_GROUP_KEYRING -6 /* - key ID for GID-specific keyring */ #define KEY_SPEC_REQKEY_AUTH_KEY -7 /* - key ID for assumed request_key auth key */ /* request-key default keyrings */ #define KEY_REQKEY_DEFL_NO_CHANGE -1 #define KEY_REQKEY_DEFL_DEFAULT 0 #define KEY_REQKEY_DEFL_THREAD_KEYRING 1 #define KEY_REQKEY_DEFL_PROCESS_KEYRING 2 #define KEY_REQKEY_DEFL_SESSION_KEYRING 3 #define KEY_REQKEY_DEFL_USER_KEYRING 4 #define KEY_REQKEY_DEFL_USER_SESSION_KEYRING 5 #define KEY_REQKEY_DEFL_GROUP_KEYRING 6 /* key handle permissions mask */ typedef uint32_t key_perm_t; #define KEY_POS_VIEW 0x01000000 /* possessor can view a key's attributes */ #define KEY_POS_READ 0x02000000 /* possessor can read key payload / view keyring */ #define KEY_POS_WRITE 0x04000000 /* possessor can update key payload / add link to keyring */ #define KEY_POS_SEARCH 0x08000000 /* possessor can find a key in search / search a keyring */ #define KEY_POS_LINK 0x10000000 /* possessor can create a link to a key/keyring */ #define KEY_POS_SETATTR 0x20000000 /* possessor can set key attributes */ #define KEY_POS_ALL 0x3f000000 #define KEY_USR_VIEW 0x00010000 /* user permissions... */ #define KEY_USR_READ 0x00020000 #define KEY_USR_WRITE 0x00040000 #define KEY_USR_SEARCH 0x00080000 #define KEY_USR_LINK 0x00100000 #define KEY_USR_SETATTR 0x00200000 #define KEY_USR_ALL 0x003f0000 #define KEY_GRP_VIEW 0x00000100 /* group permissions... */ #define KEY_GRP_READ 0x00000200 #define KEY_GRP_WRITE 0x00000400 #define KEY_GRP_SEARCH 0x00000800 #define KEY_GRP_LINK 0x00001000 #define KEY_GRP_SETATTR 0x00002000 #define KEY_GRP_ALL 0x00003f00 #define KEY_OTH_VIEW 0x00000001 /* third party permissions... */ #define KEY_OTH_READ 0x00000002 #define KEY_OTH_WRITE 0x00000004 #define KEY_OTH_SEARCH 0x00000008 #define KEY_OTH_LINK 0x00000010 #define KEY_OTH_SETATTR 0x00000020 #define KEY_OTH_ALL 0x0000003f /* keyctl commands */ #define KEYCTL_GET_KEYRING_ID 0 /* ask for a keyring's ID */ #define KEYCTL_JOIN_SESSION_KEYRING 1 /* join or start named session keyring */ #define KEYCTL_UPDATE 2 /* update a key */ #define KEYCTL_REVOKE 3 /* revoke a key */ #define KEYCTL_CHOWN 4 /* set ownership of a key */ #define KEYCTL_SETPERM 5 /* set perms on a key */ #define KEYCTL_DESCRIBE 6 /* describe a key */ #define KEYCTL_CLEAR 7 /* clear contents of a keyring */ #define KEYCTL_LINK 8 /* link a key into a keyring */ #define KEYCTL_UNLINK 9 /* unlink a key from a keyring */ #define KEYCTL_SEARCH 10 /* search for a key in a keyring */ #define KEYCTL_READ 11 /* read a key or keyring's contents */ #define KEYCTL_INSTANTIATE 12 /* instantiate a partially constructed key */ #define KEYCTL_NEGATE 13 /* negate a partially constructed key */ #define KEYCTL_SET_REQKEY_KEYRING 14 /* set default request-key keyring */ #define KEYCTL_SET_TIMEOUT 15 /* set timeout on a key */ #define KEYCTL_ASSUME_AUTHORITY 16 /* assume authority to instantiate key */ #define KEYCTL_GET_SECURITY 17 /* get key security label */ #define KEYCTL_SESSION_TO_PARENT 18 /* set my session keyring on my parent process */ #define KEYCTL_REJECT 19 /* reject a partially constructed key */ #define KEYCTL_INSTANTIATE_IOV 20 /* instantiate a partially constructed key */ #define KEYCTL_INVALIDATE 21 /* invalidate a key */ #define KEYCTL_GET_PERSISTENT 22 /* get a user's persistent keyring */ #define KEYCTL_DH_COMPUTE 23 /* Compute Diffie-Hellman values */ #define KEYCTL_PKEY_QUERY 24 /* Query public key parameters */ #define KEYCTL_PKEY_ENCRYPT 25 /* Encrypt a blob using a public key */ #define KEYCTL_PKEY_DECRYPT 26 /* Decrypt a blob using a public key */ #define KEYCTL_PKEY_SIGN 27 /* Create a public key signature */ #define KEYCTL_PKEY_VERIFY 28 /* Verify a public key signature */ #define KEYCTL_RESTRICT_KEYRING 29 /* Restrict keys allowed to link to a keyring */ #define KEYCTL_MOVE 30 /* Move keys between keyrings */ #define KEYCTL_CAPABILITIES 31 /* Find capabilities of keyrings subsystem */ #define KEYCTL_WATCH_KEY 32 /* Watch a key or ring of keys for changes */ /* keyctl structures */ struct keyctl_dh_params { key_serial_t priv; key_serial_t prime; key_serial_t base; }; struct keyctl_kdf_params { char *hashname; char *otherinfo; uint32_t otherinfolen; uint32_t __spare[8]; }; #define KEYCTL_SUPPORTS_ENCRYPT 0x01 #define KEYCTL_SUPPORTS_DECRYPT 0x02 #define KEYCTL_SUPPORTS_SIGN 0x04 #define KEYCTL_SUPPORTS_VERIFY 0x08 struct keyctl_pkey_query { unsigned int supported_ops; /* Which ops are supported */ unsigned int key_size; /* Size of the key in bits */ unsigned short max_data_size; /* Maximum size of raw data to sign in bytes */ unsigned short max_sig_size; /* Maximum size of signature in bytes */ unsigned short max_enc_size; /* Maximum size of encrypted blob in bytes */ unsigned short max_dec_size; /* Maximum size of decrypted blob in bytes */ unsigned int __spare[10]; }; struct keyctl_pkey_params { key_serial_t key_id; /* Serial no. of public key to use */ unsigned int in_len; /* Input data size */ union { unsigned int out_len; /* Output buffer size (encrypt/decrypt/sign) */ unsigned int in2_len; /* Second input data size (verify) */ }; unsigned int __spare[7]; }; #define KEYCTL_MOVE_EXCL 0x00000001 /* Do not displace from the to-keyring */ /* * Capabilities flags. The capabilities list is an array of 8-bit integers; * each integer can carry up to 8 flags. */ #define KEYCTL_CAPS0_CAPABILITIES 0x01 /* KEYCTL_CAPABILITIES supported */ #define KEYCTL_CAPS0_PERSISTENT_KEYRINGS 0x02 /* Persistent keyrings enabled */ #define KEYCTL_CAPS0_DIFFIE_HELLMAN 0x04 /* Diffie-Hellman ops enabled */ #define KEYCTL_CAPS0_PUBLIC_KEY 0x08 /* Public key ops enabled */ #define KEYCTL_CAPS0_BIG_KEY 0x10 /* big_key-type enabled */ #define KEYCTL_CAPS0_INVALIDATE 0x20 /* KEYCTL_INVALIDATE supported */ #define KEYCTL_CAPS0_RESTRICT_KEYRING 0x40 /* KEYCTL_RESTRICT_KEYRING supported */ #define KEYCTL_CAPS0_MOVE 0x80 /* KEYCTL_MOVE supported */ #define KEYCTL_CAPS1_NS_KEYRING_NAME 0x01 /* Keyring names are per-user_namespace */ #define KEYCTL_CAPS1_NS_KEY_TAG 0x02 /* Key indexing can include a namespace tag */ #define KEYCTL_CAPS1_NOTIFICATIONS 0x04 /* Keys generate watchable notifications */ /* * syscall wrappers */ extern key_serial_t add_key(const char *type, const char *description, const void *payload, size_t plen, key_serial_t ringid); extern key_serial_t request_key(const char *type, const char *description, const char *callout_info, key_serial_t destringid); extern long keyctl(int cmd, ...); /* * keyctl function wrappers */ extern key_serial_t keyctl_get_keyring_ID(key_serial_t id, int create); extern key_serial_t keyctl_join_session_keyring(const char *name); extern long keyctl_update(key_serial_t id, const void *payload, size_t plen); extern long keyctl_revoke(key_serial_t id); extern long keyctl_chown(key_serial_t id, uid_t uid, gid_t gid); extern long keyctl_setperm(key_serial_t id, key_perm_t perm); extern long keyctl_describe(key_serial_t id, char *buffer, size_t buflen); extern long keyctl_clear(key_serial_t ringid); extern long keyctl_link(key_serial_t id, key_serial_t ringid); extern long keyctl_unlink(key_serial_t id, key_serial_t ringid); extern long keyctl_search(key_serial_t ringid, const char *type, const char *description, key_serial_t destringid); extern long keyctl_read(key_serial_t id, char *buffer, size_t buflen); extern long keyctl_instantiate(key_serial_t id, const void *payload, size_t plen, key_serial_t ringid); extern long keyctl_negate(key_serial_t id, unsigned timeout, key_serial_t ringid); extern long keyctl_set_reqkey_keyring(int reqkey_defl); extern long keyctl_set_timeout(key_serial_t key, unsigned timeout); extern long keyctl_assume_authority(key_serial_t key); extern long keyctl_get_security(key_serial_t key, char *buffer, size_t buflen); extern long keyctl_session_to_parent(void); extern long keyctl_reject(key_serial_t id, unsigned timeout, unsigned error, key_serial_t ringid); struct iovec; extern long keyctl_instantiate_iov(key_serial_t id, const struct iovec *payload_iov, unsigned ioc, key_serial_t ringid); extern long keyctl_invalidate(key_serial_t id); extern long keyctl_get_persistent(uid_t uid, key_serial_t id); extern long keyctl_dh_compute(key_serial_t priv, key_serial_t prime, key_serial_t base, char *buffer, size_t buflen); extern long keyctl_dh_compute_kdf(key_serial_t priv, key_serial_t prime, key_serial_t base, char *hashname, char *otherinfo, size_t otherinfolen, char *buffer, size_t buflen); extern long keyctl_restrict_keyring(key_serial_t keyring, const char *type, const char *restriction); extern long keyctl_pkey_query(key_serial_t key_id, const char *info, struct keyctl_pkey_query *result); extern long keyctl_pkey_encrypt(key_serial_t key_id, const char *info, const void *data, size_t data_len, void *enc, size_t enc_len); extern long keyctl_pkey_decrypt(key_serial_t key_id, const char *info, const void *enc, size_t enc_len, void *data, size_t data_len); extern long keyctl_pkey_sign(key_serial_t key_id, const char *info, const void *data, size_t data_len, void *sig, size_t sig_len); extern long keyctl_pkey_verify(key_serial_t key_id, const char *info, const void *data, size_t data_len, const void *sig, size_t sig_len); extern long keyctl_move(key_serial_t id, key_serial_t from_ringid, key_serial_t to_ringid, unsigned int flags); extern long keyctl_capabilities(unsigned char *buffer, size_t buflen); extern long keyctl_watch_key(key_serial_t id, int watch_queue_fd, int watch_id); /* * utilities */ extern int keyctl_describe_alloc(key_serial_t id, char **_buffer); extern int keyctl_read_alloc(key_serial_t id, void **_buffer); extern int keyctl_get_security_alloc(key_serial_t id, char **_buffer); extern int keyctl_dh_compute_alloc(key_serial_t priv, key_serial_t prime, key_serial_t base, void **_buffer); typedef int (*recursive_key_scanner_t)(key_serial_t parent, key_serial_t key, char *desc, int desc_len, void *data); extern int recursive_key_scan(key_serial_t key, recursive_key_scanner_t func, void *data); extern int recursive_session_key_scan(recursive_key_scanner_t func, void *data); extern key_serial_t find_key_by_type_and_desc(const char *type, const char *desc, key_serial_t destringid); #ifdef __cplusplus } #endif #endif /* KEYUTILS_H */ keyutils-1.6.3/keyutils.spec000066400000000000000000000265331370111642500161300ustar00rootroot00000000000000%define vermajor 1 %define verminor 6.3 %define version %{vermajor}.%{verminor} %define libapivermajor 1 %define libapiversion %{libapivermajor}.10 # % define buildid .local Name: keyutils Version: %{version} Release: 1%{?buildid}%{?dist} Summary: Linux Key Management Utilities License: GPLv2+ and LGPLv2+ Url: http://people.redhat.com/~dhowells/keyutils/ Source0: http://people.redhat.com/~dhowells/keyutils/keyutils-%{version}.tar.bz2 BuildRequires: gcc BuildRequires: glibc-kernheaders >= 2.4-9.1.92 Requires: %{name}-libs%{?_isa} = %{version}-%{release} %description Utilities to control the kernel key management facility and to provide a mechanism by which the kernel call back to user space to get a key instantiated. %package libs Summary: Key utilities library %description libs This package provides a wrapper library for the key management facility system calls. %package libs-devel Summary: Development package for building Linux key management utilities Requires: %{name}-libs%{?_isa} = %{version}-%{release} %description libs-devel This package provides headers and libraries for building key utilities. %prep %setup -q %define datadir %{_datarootdir}/keyutils %build make \ NO_ARLIB=1 \ ETCDIR=%{_sysconfdir} \ LIBDIR=%{_libdir} \ USRLIBDIR=%{_libdir} \ BINDIR=%{_bindir} \ SBINDIR=%{_sbindir} \ MANDIR=%{_mandir} \ INCLUDEDIR=%{_includedir} \ SHAREDIR=%{datadir} \ RELEASE=.%{release} \ NO_GLIBC_KEYERR=1 \ CFLAGS="-Wall $RPM_OPT_FLAGS -Werror" \ LDFLAGS="%{?__global_ldflags}" %install make \ NO_ARLIB=1 \ DESTDIR=$RPM_BUILD_ROOT \ ETCDIR=%{_sysconfdir} \ LIBDIR=%{_libdir} \ USRLIBDIR=%{_libdir} \ BINDIR=%{_bindir} \ SBINDIR=%{_sbindir} \ MANDIR=%{_mandir} \ INCLUDEDIR=%{_includedir} \ SHAREDIR=%{datadir} \ install %ldconfig_scriptlets libs %files %doc README %license LICENCE.GPL %{_sbindir}/* %{_bindir}/* %{datadir} %{_mandir}/man1/* %{_mandir}/man5/* %{_mandir}/man8/* %config(noreplace) %{_sysconfdir}/* %files libs %license LICENCE.LGPL %{_mandir}/man7/* %{_libdir}/libkeyutils.so.%{libapiversion} %{_libdir}/libkeyutils.so.%{libapivermajor} %files libs-devel %{_libdir}/libkeyutils.so %{_includedir}/* %{_mandir}/man3/* %{_libdir}/pkgconfig/libkeyutils.pc %changelog * Tue Jul 7 2020 David Howells - 1.6.3-1 - Revert the change notifications that were using /dev/watch_queue. - Apply the change notifications that use pipe2(O_NOTIFICATION_PIPE). * Mon Jul 6 2020 David Howells - 1.6.2-1 - Allow "keyctl supports" to retrieve raw capability data. - Allow "keyctl id" to turn a symbolic key ID into a numeric ID. - Allow "keyctl new_session" to name the keyring. - Allow "keyctl add/padd/etc." to take hex-encoded data. - Add "keyctl watch*" to expose kernel change notifications on keys. - Add caps for namespacing and notifications. - Set a default TTL on keys that upcall for name resolution. - Explicitly clear memory after it's held sensitive information. - Various manual page fixes. - Fix C++-related errors. * Fri Aug 2 2019 David Howells - 1.6.1-1 - Add support for keyctl_move(). - Add support for keyctl_capabilities(). - Make key=val list optional for various public-key ops. - Fix system call signature for KEYCTL_PKEY_QUERY. - Fix 'keyctl pkey_query' argument passing. - Use keyctl_read_alloc() in dump_key_tree_aux(). - Various manual page fixes. * Tue Nov 13 2018 David Howells - 1.6-1 - Apply various specfile cleanups from Fedora. - request-key: Provide a command line option to suppress helper execution. - request-key: Find least-wildcard match rather than first match. - Remove the dependency on MIT Kerberos. - Fix some error messages - keyctl_dh_compute.3: Suggest /proc/crypto for list of available hashes. - Fix doc and comment typos. - Add public key ops for encrypt, decrypt, sign and verify (needs linux-4.20). - Add pkg-config support for finding libkeyutils. * Wed May 9 2018 David Howells - 1.5.11-1 - Add keyring restriction support. - Add KDF support to the Diffie-Helman function. - DNS: Add support for AFS config files and SRV records * Wed Mar 15 2017 David Howells - 1.5.10-1 - Include sys/types.h in keyutils.h. - The dns resolver needs limits.h. - Overhaul of all manual pages. - Some manual pages moved to Linux man-pages project. - Add Diffie-Helman keyctl function. * Fri Feb 21 2014 David Howells - 1.5.9-1 - Add manpages for get_persistent. - Fix memory leaks in keyctl_describe/read/get_security_alloc(). - Use keyctl_describe_alloc in dump_key_tree_aux rather than open coding it. - Exit rather than returning from act_xxx() functions. - Fix memory leak in dump_key_tree_aux. - Only get the groups list if we need it. - Don't trust sscanf's %%n argument. - Use the correct path macros in the specfile. - Avoid use realloc when the memory has no content. - Fix a bunch of issues in key.dns_resolver. - Fix command table searching in keyctl utility. - Fix a typo in the permissions mask constants. - Improve the keyctl_read manpage. - Add man7 pages describing various keyrings concepts. * Fri Oct 4 2013 David Howells - 1.5.8-1 - New lib symbols should go in a new library minor version. * Wed Oct 2 2013 David Howells - 1.5.7-1 - Provide a utility function to find a key by type and name. - Allow keyctl commands to take a type+name arg instead of a key-id arg. - Add per-UID get_persistent keyring function. * Thu Aug 29 2013 David Howells - 1.5.6-1 - Fix the request-key.conf.5 manpage. - Fix the max depth of key tree dump (keyctl show). - The input buffer size for keyctl padd and pinstantiate should be larger. - Add keyctl_invalidate.3 manpage. * Wed Nov 30 2011 David Howells - 1.5.5-1 - Fix a Makefile error. * Wed Nov 30 2011 David Howells - 1.5.4-1 - Fix the keyctl padd command and similar to handle binary input. - Make keyctl show able to take a keyring to dump. - Make keyctl show able to take a flag to request hex key IDs. - Make keyctl show print the real ID of the root keyring. * Tue Nov 15 2011 David Howells - Allow /sbin/request-key to have multiple config files. * Wed Aug 31 2011 David Howells - Adjust the manual page for 'keyctl unlink' to show keyring is optional. - Add --version support for the keyutils version and build date. * Thu Aug 11 2011 David Howells - 1.5.3-1 - Make the keyutils rpm depend on the same keyutils-libs rpm version. * Tue Jul 26 2011 David Howells - 1.5.2-1 - Use correct format spec for printing pointer subtraction results. * Tue Jul 19 2011 David Howells - 1.5.1-1 - Fix unread variables. - Licence file update. * Thu Mar 10 2011 David Howells - 1.5-1 - Disable RPATH setting in Makefile. - Add -I. to build to get this keyutils.h. - Make CFLAGS override on make command line work right. - Make specfile UTF-8. - Support KEYCTL_REJECT. - Support KEYCTL_INSTANTIATE_IOV. - Add AFSDB DNS lookup program from Wang Lei. - Generalise DNS lookup program. - Add recursive scan utility function. - Add bad key reap command to keyctl. - Add multi-unlink variant to keyctl unlink command. - Add multi key purge command to keyctl. - Handle multi-line commands in keyctl command table. - Move the package to version to 1.5. * Tue Mar 1 2011 David Howells - 1.4-4 - Make build guess at default libdirs and word size. - Make program build depend on library in Makefile. - Don't include $(DESTDIR) in MAN* macros. - Remove NO_GLIBC_KEYSYS as it is obsolete. - Have Makefile extract version info from specfile and version script. - Provide RPM build rule in Makefile. - Provide distclean rule in Makefile. * Fri Dec 17 2010 Diego Elio Pettenò - 1.4-3 - Fix local linking and RPATH. * Thu Jun 10 2010 David Howells - 1.4-2 - Fix prototypes in manual pages (some char* should be void*). - Rename the keyctl_security.3 manpage to keyctl_get_security.3. * Fri Mar 19 2010 David Howells - 1.4-1 - Fix the library naming wrt the version. - Move the package to version to 1.4. * Fri Mar 19 2010 David Howells - 1.3-3 - Fix spelling mistakes in manpages. - Add an index manpage for all the keyctl functions. * Thu Mar 11 2010 David Howells - 1.3-2 - Fix rpmlint warnings. * Fri Feb 26 2010 David Howells - 1.3-1 - Fix compiler warnings in request-key. - Expose the kernel function to get a key's security context. - Expose the kernel function to set a processes keyring onto its parent. - Move libkeyutils library version to 1.3. * Tue Aug 22 2006 David Howells - 1.2-1 - Remove syscall manual pages (section 2) to man-pages package [BZ 203582] - Don't write to serial port in debugging script * Mon Jun 5 2006 David Howells - 1.1-4 - Call ldconfig during (un)installation. * Fri May 5 2006 David Howells - 1.1-3 - Don't include the release number in the shared library filename - Don't build static library * Fri May 5 2006 David Howells - 1.1-2 - More bug fixes from Fedora reviewer. * Thu May 4 2006 David Howells - 1.1-1 - Fix rpmlint errors * Mon Dec 5 2005 David Howells - 1.0-2 - Add build dependency on glibc-kernheaders with key management syscall numbers * Tue Nov 29 2005 David Howells - 1.0-1 - Add data pipe-in facility for keyctl request2 * Mon Nov 28 2005 David Howells - 1.0-1 - Rename library and header file "keyutil" -> "keyutils" for consistency - Fix shared library version naming to same way as glibc. - Add versioning for shared library symbols - Create new keyutils-libs package and install library and main symlink there - Install base library symlink in /usr/lib and place in devel package - Added a keyutils archive library - Shorten displayed key permissions list to just those we actually have * Thu Nov 24 2005 David Howells - 0.3-4 - Add data pipe-in facilities for keyctl add, update and instantiate * Fri Nov 18 2005 David Howells - 0.3-3 - Added stdint.h inclusion in keyutils.h - Made request-key.c use request_key() rather than keyctl_search() - Added piping facility to request-key * Thu Nov 17 2005 David Howells - 0.3-2 - Added timeout keyctl option - request_key auth keys must now be assumed - Fix keyctl argument ordering for debug negate line in request-key.conf * Thu Jul 28 2005 David Howells - 0.3-1 - Must invoke initialisation from perror() override in libkeyutils - Minor UI changes * Wed Jul 20 2005 David Howells - 0.2-2 - Bump version to permit building in main repositories. * Tue Jul 12 2005 David Howells - 0.2-1 - Don't attempt to define the error codes in the header file. - Pass the release ID through to the makefile to affect the shared library name. * Tue Jul 12 2005 David Howells - 0.1-3 - Build in the perror() override to get the key error strings displayed. * Tue Jul 12 2005 David Howells - 0.1-2 - Need a defattr directive after each files directive. * Tue Jul 12 2005 David Howells - 0.1-1 - Package creation. keyutils-1.6.3/libkeyutils.pc.in000066400000000000000000000002411370111642500166600ustar00rootroot00000000000000libdir=@libdir@ includedir=@includedir@ Name: libkeyutils Description: keyutils library Version: @VERSION@ Cflags: -I${includedir} Libs: -L${libdir} -lkeyutils keyutils-1.6.3/man/000077500000000000000000000000001370111642500141455ustar00rootroot00000000000000keyutils-1.6.3/man/asymmetric-key.7000066400000000000000000000223101370111642500171760ustar00rootroot00000000000000.\" .\" Copyright (C) 2018 Red Hat, Inc. All Rights Reserved. .\" Written by David Howells (dhowells@redhat.com) .\" .\" This program is free software; you can redistribute it and/or .\" modify it under the terms of the GNU General Public Licence .\" as published by the Free Software Foundation; either version .\" 2 of the Licence, or (at your option) any later version. .\" .TH ASYMMETRIC-KEY 7 "8 Nov 2018" Linux "Asymmetric Kernel Key Type" .\""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" .SH NAME asymmetric \- Kernel key type for holding asymmetric keys .\""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" .SH OVERVIEW .PP A kernel key of .B asymmetric type acts as a handle to an asymmetric key as used for public-key cryptography. The key material itself may be held inside the kernel or it may be held in hardware with operations being offloaded. This prevents direct user access to the cryptographic material. .PP Keys may be any asymmetric type (RSA, ECDSA, ...) and may have both private and public components present or just the public component. .PP Asymmetric keys can be made use of by both the kernel and userspace. The kernel can make use of them for module signature verification and kexec image verification for example. Userspace is provided with a set of .BR keyctl ( KEYCTL_PKEY_* ) calls for querying and using the key. These are wrapped by .B libkeyutils as functions named .BR keyctl_pkey_*() . .PP An asymmetric-type key can be loaded by the keyctl utility using a command line like: .PP .in +4n .EX openssl x509 -in key.x509 -outform DER | keyctl padd asymmetric foo @s .EE .in .\""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" .SH DESCRIPTION .PP The asymmetric-type key can be viewed as a container that comprises of a number of components: .TP Parsers The asymmetric key parsers attempt to identify the content of the payload blob and extract useful data from it with which to instantiate the key. The parser is only used when adding, instantiating or updating a key and isn't thereafter associated with the key. .IP Available parsers include ones that can deal with .RB "DER-encoded " X.509 ", DER-encoded " PKCS#8 " and DER-encoded " TPM "-wrapped blobs." .TP Public and private keys These are the cryptographic components of the key pair. The public half should always be available, but the private half might not be. What operations are available can be queried, as can the size of the key. The key material may or may not actually reside in the kernel. .TP Identifiers In addition to the normal key description (which can be generated by the parser), a number of supplementary identifiers may be available that can be searched for. These may be obtained, for example, by hashing the public key material or from the subjectKeyIdentifier in an X.509 certificate. .IP Identifier-based searches are selected by passing as the description to .BR keyctl_search () a string constructed of hex characters prefixed with either "id:" or "ex:". The "id:" prefix indicates that a partial tail match is permissible whereas "ex:" requires an exact match on the full string. The hex characters indicate the data to match. .TP Subtype This is the driver inside the kernel that accesses the key material and performs operations on it. It might be entirely software-based or it may offload the operations to a hardware key store, such as a .BR TPM . .PP Note that expiry times from the payload are ignored as these patches may be used during boot before the system clock is set. .\""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" .SH PARSERS .PP The asymmetric key parsers can handle keys in a number of forms: .TP \fBX.509\fP DER-encoded X.509 certificates can be accepted. Two identifiers are constructed: one from from the certificate issuer and serial number and the other from the subjectKeyIdentifier, if present. If left blank, the key description will be filled in from the subject field plus either the subjectKeyIdentifier or the serialNumber. Only the public key is filled in and only the encrypt and verify operations are supported. .IP The signature on the X.509 certificate may be checked by the keyring it is being added to and it may also be rejected if the key is blacklisted. .TP \fBPKCS#8\fP Unencrypted DER-encoded PKCS#8 key data containers can be accepted. Currently no identifiers are constructed. The private key and the public key are loaded from the PKCS#8 blobs. Encrypted PKCS#8 is not currently supported. .TP \fBTPM-Wrapped keys\fP DER-encoded TPM-wrapped TSS key blobs can be accepted. Currently no identifiers are constructed. The public key is extracted from the blob but the private key is expected to be resident in the TPM. Encryption and signature verification is done in software, but decryption and signing are offloaded to the TPM so as not to expose the private key. .IP This parser only supports TPM-1.2 wrappings and enc=pkcs1 encoding type. It also uses a hard-coded null SRK password; password-protected SRKs are not yet supported. .\""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" .SH USERSPACE API .PP In addition to the standard keyutils library functions, such as .IR keyctl_update (), there are five calls specific to the asymmetric key type (though they are open to being used by other key types also): .PP .RS \fIkeyctl_pkey_query\fP() .br \fIkeyctl_pkey_encrypt\fP() .br \fIkeyctl_pkey_decrypt\fP() .br \fIkeyctl_pkey_sign\fP() .br \fIkeyctl_pkey_verify\fP() .RE .PP The query function can be used to retrieve information about an asymmetric key, such as the key size, the amount of space required by buffers for the other operations and which operations are actually supported. .PP The other operations form two pairs: encrypt/decrypt and create/verify signature. Not all of these operations will necessarily be available; typically, encrypt and verify only require the public key to be available whereas decrypt and sign require the private key as well. .PP All of these operations take an information string parameter that supplies additional information such as encoding type/form and the password(s) needed to unlock/unwrap the key. This takes the form of a comma-separated list of "key[=value]" pairs, the exact set of which depends on the subtype driver used by a particular key. .PP Available parameters include: .TP enc= The encoding type for use in an encrypted blob or a signature. An example might be "enc=pkcs1". .TP hash= The name of the hash algorithm that was used to digest the data to be signed. Note that this is only used to construct any encoding that is used in a signature. The data to be signed or verified must have been parsed by the caller and the hash passed to \fIkeyctl_pkey_sign\fP() or \fIkeyctl_pkey_verify\fP() beforehand. An example might be "hash=sha256". .PP Note that not all parameters are used by all subtypes. .\""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" .SH RESTRICTED KEYRINGS .PP An additional keyutils function, .IR keyctl_restrict_keyring (), can be used to gate a keyring so that a new key can only be added to the affected keyring if (a) it's an asymmetric key, (b) it's validly signed by a key in some appropriate keyring and (c) it's not blacklisted. .PP .in +4n .EX keyctl_restrict_keyring(keyring, "asymmetric", "key_or_keyring:[:chain]"); .EE .in .PP Where \fI\fP is the ID of a key or a ring of keys that act as the authority to permit a new key to be added to the keyring. The \fIchain\fP flag indicates that keys that have been added to the keyring may also be used to verify new keys. Authorising keys must themselves be asymmetric-type keys that can be used to do a signature verification on the key being added. .PP Note that there are various system keyrings visible to the root user that may permit additional keys to be added. These are typically gated by keys that already exist, preventing unauthorised keys from being used for such things as module verification. .\""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" .SH BLACKLISTING .PP When the attempt is made to add a key to the kernel, a hash of the public key is checked against the .BR blacklist. This is a system keyring named .B .blacklist and contains keys of type .BR blacklist . If the blacklist contains a key whose description matches the hash of the new key, that new key will be rejected with error .BR EKEYREJECTED . .PP The blacklist keyring may be loaded from multiple sources, including a list compiled into the kernel and the UEFI .B dbx variable. Further hashes may also be blacklisted by the administrator. Note that blacklisting is not retroactive, so an asymmetric key that is already on the system cannot be blacklisted by adding a matching blacklist entry later. .\""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" .SH VERSIONS The .B asymmetric key type first appeared in v3.7 of the Linux kernel, the .B restriction function in v4.11 and the .B public key operations in v4.20. .SH SEE ALSO .ad l .nh .BR keyctl (1), .BR add_key (2), .BR keyctl (3), .BR keyctl_pkey_encrypt (3), .BR keyctl_pkey_query (3), .BR keyctl_pkey_sign (3), .BR keyrings (7), .BR keyutils (7) keyutils-1.6.3/man/find_key_by_type_and_name.3000066400000000000000000000041531370111642500214010ustar00rootroot00000000000000.\" .\" Copyright (C) 2013 Red Hat, Inc. All Rights Reserved. .\" Written by David Howells (dhowells@redhat.com) .\" .\" This program is free software; you can redistribute it and/or .\" modify it under the terms of the GNU General Public Licence .\" as published by the Free Software Foundation; either version .\" 2 of the Licence, or (at your option) any later version. .\" .TH FIND_KEY_BY_TYPE_AND_NAME 3 "10 Sep 2013" Linux "Linux Key Utility Calls" .\""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" .SH NAME find_key_by_type_and_name \- find a key by type and name .\""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" .SH SYNOPSIS .nf .B #include .sp .BI "key_serial_t find_key_by_type_and_name(const char *" type , .BI " const char *" description ", key_serial_t " destringid ");" .\""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" .SH DESCRIPTION .BR find_key_by_type_and_name () searches for a key with the given .I type and exact .IR description , firstly in the thread, process and session keyrings to which a process is subscribed and secondly in .IR /proc/keys . .P If a key is found, and .I destringid is not 0 and specifies a keyring, then the found key will be linked into it. .\""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" .SH RETURN VALUE The function returns the ID of the key if a key was found or \-1 otherwise. .\""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" .SH ERRORS .TP .B ENOKEY No key was found or the keyring specified is invalid. .TP .B EKEYEXPIRED The key or keyring have expired. .TP .B EKEYREVOKED The key or keyring have been revoked. .TP .B EACCES The key is not accessible or keyring exists, but is not .B writable by the calling process. .\""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" .SH LINKING When linking, .B \-lkeyutils should be specified to the linker. .\""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" .SH SEE ALSO .ad l .nh .BR request_key (2), .BR keyctl (3), .BR keyrings (7) keyutils-1.6.3/man/key.dns_resolver.8000066400000000000000000000034741370111642500175420ustar00rootroot00000000000000.\" .\" Copyright (C) 2011 Red Hat, Inc. All Rights Reserved. .\" Written by David Howells (dhowells@redhat.com) .\" .\" This program is free software; you can redistribute it and/or .\" modify it under the terms of the GNU General Public License .\" as published by the Free Software Foundation; either version .\" 2 of the License, or (at your option) any later version. .\" .TH KEY.DNS_RESOLVER 8 "18 May 2020" Linux "Linux Key Management Utilities" .SH NAME key.dns_resolver \- upcall for request\-key to handle dns_resolver keys .SH SYNOPSIS \fB/sbin/key.dns_resolver \fR .br \fB/sbin/key.dns_resolver \fR--dump-config [\-c ] .br \fB/sbin/key.dns_resolver \fR\-D [\-v] [\-v] [\-c ] .br .SH DESCRIPTION This program is invoked by request\-key on behalf of the kernel when kernel services (such as NFS, CIFS and AFS) want to perform a hostname lookup and the kernel does not have the key cached. It is not ordinarily intended to be called directly. .P There program has internal parameters that can be changed with a configuration file (see key.dns_resolver.conf(5) for more information). The default configuration file is in /etc, but this can be overridden with the \fB-c\fR flag. .P The program can be called in debugging mode to test its functionality by passing a \fB\-D\fR or \fB\--debug\fR flag on the command line. For this to work, the key description and the callout information must be supplied. Verbosity can be increased by supplying one or more \fB\-v\fR flags. .P The program may also be called with \fB--dump-config\fR to show the values that configurable parameters will have after parsing the config file. .SH ERRORS All errors will be logged to the syslog. .SH SEE ALSO .ad l .nh .BR key.dns_resolver.conf (5), .BR request\-key.conf (5), .BR keyrings (7), .BR request\-key (8) keyutils-1.6.3/man/key.dns_resolver.conf.5000066400000000000000000000036101370111642500204530ustar00rootroot00000000000000.\" -*- nroff -*- .\" Copyright (C) 2020 Red Hat, Inc. All Rights Reserved. .\" Written by David Howells (dhowells@redhat.com) .\" .\" This program is free software; you can redistribute it and/or .\" modify it under the terms of the GNU General Public License .\" as published by the Free Software Foundation; either version .\" 2 of the License, or (at your option) any later version. .\" .TH KEY.DNS_RESOLVER.CONF 5 "18 May 2020" Linux "Linux Key Management Utilities" .SH NAME key.dns_resolver.conf \- Kernel DNS resolver config .SH DESCRIPTION This file is used by the key.dns_resolver(5) program to set parameters. Unless otherwise overridden with the \fB\-c\fR flag, the program reads: .IP /etc/key.dns_resolver.conf .P Configuration options are given in \fBkey[=value]\fR form, where \fBvalue\fR is optional. If present, the value may be surrounded by a pair of single ('') or double quotes ("") which will be stripped off. The special characters in the value may be escaped with a backslash to turn them into ordinary characters. .P Lines beginning with a '#' are considered comments and ignored. A '#' symbol anywhere after the '=' makes the rest of the line into a comment unless the '#' is inside a quoted section or is escaped. .P Leading and trailing spaces and spaces around the '=' symbol will be stripped off. .P Available options include: .TP .B default_ttl= The number of seconds to set as the expiration on a cached record. This will be overridden if the program manages to retrieve TTL information along with the addresses (if, for example, it accesses the DNS directly). The default is 5 seconds. The value must be in the range 1 to INT_MAX. .P The file can also include comments beginning with a '#' character unless otherwise suppressed by being inside a quoted value or being escaped with a backslash. .SH FILES .ul /etc/key.dns_resolver.conf .ul 0 .SH SEE ALSO \fBkey.dns_resolver\fR(8) keyutils-1.6.3/man/keyctl.1000066400000000000000000000766211370111642500155360ustar00rootroot00000000000000.\" .\" Copyright (C) 2004 Red Hat, Inc. All Rights Reserved. .\" Written by David Howells (dhowells@redhat.com) .\" .\" This program is free software; you can redistribute it and/or .\" modify it under the terms of the GNU General Public License .\" as published by the Free Software Foundation; either version .\" 2 of the License, or (at your option) any later version. .\" .TH KEYCTL 1 "20 Feb 2014" Linux "Linux Key Management Utilities" .SH NAME keyctl \- key management facility control .SH SYNOPSIS \fBkeyctl\fR \-\-version .br \fBkeyctl\fR supports [ | --raw] .br \fBkeyctl\fR id [] .br \fBkeyctl\fR show [\-x] [] .br \fBkeyctl\fR add [\-x] .br \fBkeyctl\fR padd [\-x] .br \fBkeyctl\fR request [] .br \fBkeyctl\fR request2 [] .br \fBkeyctl\fR prequest2 [] .br \fBkeyctl\fR update [\-x] .br \fBkeyctl\fR pupdate [\-x] .br \fBkeyctl\fR newring .br \fBkeyctl\fR revoke .br \fBkeyctl\fR clear .br \fBkeyctl\fR link .br \fBkeyctl\fR unlink [] .br \fBkeyctl\fR move [-f] .br \fBkeyctl\fR search [] .br \fBkeyctl\fR restrict_keyring [ []] .br \fBkeyctl\fR read .br \fBkeyctl\fR pipe .br \fBkeyctl\fR print .br \fBkeyctl\fR list .br \fBkeyctl\fR rlist .br \fBkeyctl\fR describe .br \fBkeyctl\fR rdescribe [sep] .br \fBkeyctl\fR chown .br \fBkeyctl\fR chgrp .br \fBkeyctl\fR setperm .br \fBkeyctl\fR new_session [] .br \fBkeyctl\fR session .br \fBkeyctl\fR session \- [ ...] .br \fBkeyctl\fR session [ ...] .br \fBkeyctl\fR instantiate [\-x] .br \fBkeyctl\fR pinstantiate [\-x] .br \fBkeyctl\fR negate .br \fBkeyctl\fR reject .br \fBkeyctl\fR timeout .br \fBkeyctl\fR security .br \fBkeyctl\fR reap [\-v] .br \fBkeyctl\fR purge .br \fBkeyctl\fR purge [\-i] [\-p] .br \fBkeyctl\fR purge \-s .br \fBkeyctl\fR get_persistent [] .br \fBkeyctl\fR dh_compute .br \fBkeyctl\fR dh_compute_kdf .br \fBkeyctl\fR dh_compute_kdf_oi [\-x] .br \fBkeyctl\fR pkey_query [k=v]* .br \fBkeyctl\fR pkey_encrypt [k=v]* > .br \fBkeyctl\fR pkey_decrypt [k=v]* > .br \fBkeyctl\fR pkey_sign [k=v]* > .br \fBkeyctl\fR pkey_decrypt [k=v]* .br \fBkeyctl\fR watch [\-f] .br \fBkeyctl\fR watch_add .br \fBkeyctl\fR watch_rm .br \fBkeyctl\fR watch_session [\-f ] [-n ] \\ [ ...] .SH DESCRIPTION This program is used to control the key management facility in various ways using a variety of subcommands. .SH KEY IDENTIFIERS The key identifiers passed to or returned from keyctl are, in general, positive integers. There are, however, some special values with special meanings that can be passed as arguments: .TP No key: \fB0\fR .TP Thread keyring: \fB@t\fR or \fB\-1\fR Each thread may have its own keyring. This is searched first, before all others. The thread keyring is replaced by (v)fork, exec and clone. .TP Process keyring: \fB@p\fR or \fB\-2\fR Each process (thread group) may have its own keyring. This is shared between all members of a group and will be searched after the thread keyring. The process keyring is replaced by (v)fork and exec. .TP Session keyring: \fB@s\fR or \fB\-3\fR Each process subscribes to a session keyring that is inherited across (v)fork, exec and clone. This is searched after the process keyring. Session keyrings can be named and an extant keyring can be joined in place of a process's current session keyring. .TP User specific keyring: \fB@u\fR or \fB\-4\fR This keyring is shared between all the processes owned by a particular user. It isn't searched directly, but is normally linked to from the session keyring. .TP User default session keyring: \fB@us\fR or \fB\-5\fR This is the default session keyring for a particular user. Login processes that change to a particular user will bind to this session until another session is set. .TP Group specific keyring: \fB@g\fR or \fB\-6\fR This is a place holder for a group specific keyring, but is not actually implemented yet in the kernel. .TP Assumed request_key authorisation key: \fB@a\fR or \fB\-7\fR This selects the authorisation key provided to the .BR request_key () helper to permit it to access the callers keyrings and instantiate the target key. .TP Keyring by name: \fB%:\fR A named keyring. This will be searched for in the process's keyrings and in .IR /proc/keys . .TP Key by name: \fB%:\fR A named key of the given type. This will be searched for in the process's keyrings and in .IR /proc/keys . .SH COMMAND SYNTAX Any non-ambiguous shortening of a command name may be used in lieu of the full command name. This facility should not be used in scripting as new commands may be added in future that then cause ambiguity. .SS Display the package version number \fBkeyctl \-\-version\fR This command prints the package version number and build date and exits: .RS .nf $ keyctl \-\-version keyctl from keyutils\-1.5.3 (Built 2011\-08\-24) .fi .RE .SS Query subsystem capabilities .nf \fBkeyctl\fR supports \fBkeyctl\fR supports --raw \fBkeyctl\fR supports .fi .P This command can list the available capabilities: .P .RS .nf $ keyctl supports have_capabilities=0 have_persistent_keyrings=1 have_dh_compute=1 have_public_key=1 ... .fi .RE .P produce a raw hex dump of the capabilities list: .P .RS .nf $ keyctl supports --raw ff0f .fi .RE .P or query a specific capability: .RS .nf $ keyctl supports pkey echo $? 0 .fi .RE which exits 0 if the capability is supported, 1 if it isn't and 3 if the name is not recognised. The capabilities supported are: .TP .B capabilities The kernel supports capability querying. If not, the other capabilities will be queried as best libkeyutils can manage. .TP .B persistent_keyrings The kernel supports persistent keyrings. .TP .B dh_compute The kernel supports Diffie-Hellman computation operations. .TP .B public_key The kernel supports public key operations. .TP .B big_key_type The kernel supports the big_key key type. .TP .B key_invalidate The kernel supports the invalidate key operaiton. .TP .B restrict_keyring The kernel supports the restrict_keyring operation. .TP .B move_key The kernel supports the move key operation. .TP .B ns_keyring_name Keyring names are segregated according to the user-namespace in which the keyrings are created. .TP .B ns_key_tag Keys can get tagged with namespace tags, allowing keys with the same type and description, but different namespaces to coexist in the same keyring. Tagging is done automatically according to the key type. .SS Show actual key or keyring ID \fBkeyctl id []\fR This command looks up the real ID of a key or keyring from the identifier given, which is typically a symbolic ID such as "@s" indicating the session keyring, but can also be a numeric ID or "%type:desc" notation. If a special keyring is specified that isn't created yet, an error will be given rather than causing that keyring to be created. .SS Show process keyrings \fBkeyctl show [\-x] []\fR By default this command recursively shows what keyrings a process is subscribed to and what keys and keyrings they contain. If a keyring is specified then that keyring will be dumped instead. If \fB\-x\fR is specified then the keyring IDs will be dumped in hex instead of decimal. .SS Add a key to a keyring \fBkeyctl add\fR [\-x] .br \fBkeyctl padd\fR [\-x] This command creates a key of the specified type and description; instantiates it with the given data and attaches it to the specified keyring. It then prints the new key's ID on stdout: .RS .nf $ keyctl add user mykey stuff @u 26 .fi .RE The \fBpadd\fR variant of the command reads the data from stdin rather than taking it from the command line: .RS .fi $ echo \-n stuff | keyctl padd user mykey @u 26 .fi .RE If \fB\-x\fR is given, then the data is hex-decoded with whitespace being discarded. .SS Request a key \fBkeyctl request\fR [] .br \fBkeyctl request2\fR [] .br \fBkeyctl prequest2\fR [] These three commands request the lookup of a key of the given type and description. The process's keyrings will be searched, and if a match is found the matching key's ID will be printed to stdout; and if a destination keyring is given, the key will be added to that keyring also. If there is no key, the first command will simply return the error ENOKEY and fail. The second and third commands will create a partial key with the type and description, and call out to .IR /sbin/request\-key with that key and the extra information supplied. This will then attempt to instantiate the key in some manner, such that a valid key is obtained. The third command is like the second, except that the callout information is read from stdin rather than being passed on the command line. If a valid key is obtained, the ID will be printed and the key attached as if the original search had succeeded. If there wasn't a valid key obtained, a temporary negative key will be attached to the destination keyring if given and the error "Requested key not available" will be given. .RS .nf $ keyctl request2 user debug:hello wibble 23 $ echo \-n wibble | keyctl prequest2 user debug:hello 23 $ keyctl request user debug:hello 23 .fi .RE .SS Update a key \fBkeyctl update\fR [\-x] .br \fBkeyctl pupdate\fR [\-x] This command replaces the data attached to a key with a new set of data. If the type of the key doesn't support update then error "Operation not supported" will be returned. .RS .nf $ keyctl update 23 zebra .fi .RE The \fBpupdate\fR variant of the command reads the data from stdin rather than taking it from the command line: .RS .nf $ echo \-n zebra | keyctl pupdate 23 $ echo 616263313233 | keyctl pupdate -x 23 .fi .RE If \fB\-x\fR is given, then the data is hex-decoded with whitespace being discarded. .SS Create a keyring \fBkeyctl newring\fR This command creates a new keyring of the specified name and attaches it to the specified keyring. The ID of the new keyring will be printed to stdout if successful. .RS .nf $ keyctl newring squelch @us 27 .fi .RE .SS Revoke a key \fBkeyctl revoke\fR This command marks a key as being revoked. Any further operations on that key (apart from unlinking it) will return error "Key has been revoked". .RS .nf $ keyctl revoke 26 $ keyctl describe 26 keyctl_describe: Key has been revoked .fi .RE .SS Clear a keyring \fBkeyctl clear\fR This command unlinks all the keys attached to the specified keyring. Error "Not a directory" will be returned if the key specified is not a keyring. .RS .nf $ keyctl clear 27 .fi .RE .SS Link a key to a keyring \fBkeyctl link\fR This command makes a link from the key to the keyring if there's enough capacity to do so. Error "Not a directory" will be returned if the destination is not a keyring. Error "Permission denied" will be returned if the key doesn't have link permission or the keyring doesn't have write permission. Error "File table overflow" will be returned if the keyring is full. Error "Resource deadlock avoided" will be returned if an attempt was made to introduce a recursive link. .RS .nf $ keyctl link 23 27 $ keyctl link 27 27 keyctl_link: Resource deadlock avoided .fi .RE .SS Unlink a key from a keyring or the session keyring tree \fBkeyctl unlink\fR [] If the keyring is specified, this command removes a link to the key from the keyring. Error "Not a directory" will be returned if the destination is not a keyring. Error "Permission denied" will be returned if the keyring doesn't have write permission. Error "No such file or directory" will be returned if the key is not linked to by the keyring. If the keyring is not specified, this command performs a depth-first search of the session keyring tree and removes all the links to the nominated key that it finds (and that it is permitted to remove). It prints the number of successful unlinks before exiting. .RS .nf $ keyctl unlink 23 27 .fi .RE .SS Move a key between keyrings. \fBkeyctl move\fR [-f] This command moves a key from one keyring to another, atomically combining "keyctl unlink " and "keyctl link ". If the "-f" flag is present, any matching key will be displaced from "to_keyring"; if not present, the command will fail with the error message "File exists" if the key would otherwise displace another key from "to_keyring". .RS .nf $ keyctl move 23 27 29 $ keyctl move -f 71 @u @s .fi .RE .SS Search a keyring \fBkeyctl search\fR [] This command non-recursively searches a keyring for a key of a particular type and description. If found, the ID of the key will be printed on stdout and the key will be attached to the destination keyring if present. Error "Requested key not available" will be returned if the key is not found. .RS .nf $ keyctl search @us user debug:hello 23 $ keyctl search @us user debug:bye keyctl_search: Requested key not available .fi .RE .SS Restrict a keyring \fBkeyctl restrict_keyring\fR [ []] This command limits the linkage of keys to the given keyring using a provided restriction scheme. The scheme is associated with a given key type, with further details provided in the restriction option string. Options typically contain a restriction name possibly followed by key ids or other data relevant to the restriction. If no restriction scheme is provided, the keyring will reject all links. .RS .nf $ keyctl restrict_keyring $1 asymmetric builtin_trusted .RE .SS Read a key \fBkeyctl read\fR .br \fBkeyctl pipe\fR .br \fBkeyctl print\fR These commands read the payload of a key. "read" prints it on stdout as a hex dump, "pipe" dumps the raw data to stdout and "print" dumps it to stdout directly if it's entirely printable or as a hexdump preceded by ":hex:" if not. If the key type does not support reading of the payload, then error "Operation not supported" will be returned. .RS .nf $ keyctl read 26 1 bytes of data in key: 62 $ keyctl print 26 b $ keyctl pipe 26 $ .fi .RE .SS List a keyring \fBkeyctl list\fR .br \fBkeyctl rlist\fR These commands list the contents of a key as a keyring. "list" pretty prints the contents and "rlist" just produces a space-separated list of key IDs. No attempt is made to check that the specified keyring is a keyring. .RS .nf $ keyctl list @us 2 keys in keyring: 22: vrwsl\-\-\-\-\-\-\-\-\-\- 4043 \-1 keyring: _uid.4043 23: vrwsl\-\-\-\-\-\-\-\-\-\- 4043 4043 user: debug:hello $ keyctl rlist @us 22 23 .fi .RE .SS Describe a key \fBkeyctl describe\fR .br \fBkeyctl rdescribe\fR [sep] These commands fetch a description of a keyring. "describe" pretty prints the description in the same fashion as the "list" command; "rdescribe" prints the raw data returned from the kernel. .RS .nf $ keyctl describe @us \-5: vrwsl\-\-\-\-\-\-\-\-\-\- 4043 \-1 keyring: _uid_ses.4043 $ keyctl rdescribe @us keyring;4043;\-1;3f1f0000;_uid_ses.4043 .fi .RE The raw string is ";;;;", where \fIuid\fR and \fIgid\fR are the decimal user and group IDs, \fIperms\fR is the permissions mask in hex, \fItype\fR and \fIdescription\fR are the type name and description strings (neither of which will contain semicolons). .SS Change the access controls on a key \fBkeyctl chown\fR .br \fBkeyctl chgrp\fR These two commands change the UID and GID associated with evaluating a key's permissions mask. The UID also governs which quota a key is taken out of. The chown command is not currently supported; attempting it will earn the error "Operation not supported" at best. For non-superuser users, the GID may only be set to the process's GID or a GID in the process's groups list. The superuser may set any GID it likes. .RS .nf $ sudo keyctl chown 27 0 keyctl_chown: Operation not supported $ sudo keyctl chgrp 27 0 .fi .RE .SS Set the permissions mask on a key \fBkeyctl setperm\fR This command changes the permission control mask on a key. The mask may be specified as a hex number if it begins "0x", an octal number if it begins "0" or a decimal number otherwise. The hex numbers are a combination of: .RS .nf Possessor UID GID Other Permission Granted ======== ======== ======== ======== ================== 01000000 00010000 00000100 00000001 View 02000000 00020000 00000200 00000002 Read 04000000 00040000 00000400 00000004 Write 08000000 00080000 00000800 00000008 Search 10000000 00100000 00001000 00000010 Link 20000000 00200000 00002000 00000020 Set Attribute 3f000000 003f0000 00003f00 0000003f All .fi .RE \fIView\fR permits the type, description and other parameters of a key to be viewed. \fIRead\fR permits the payload (or keyring list) to be read if supported by the type. \fIWrite\fR permits the payload (or keyring list) to be modified or updated. \fISearch\fR on a key permits it to be found when a keyring to which it is linked is searched. \fILink\fR permits a key to be linked to a keyring. \fISet Attribute\fR permits a key to have its owner, group membership, permissions mask and timeout changed. .RS .nf $ keyctl setperm 27 0x1f1f1f00 .fi .RE .SS Start a new session with fresh keyrings \fBkeyctl session\fR .br \fBkeyctl session\fR \- [ ...] .br \fBkeyctl session\fR [ ...] These commands join or create a new keyring and then run a shell or other program with that keyring as the session key. The variation with no arguments just creates an anonymous session keyring and attaches that as the session keyring; it then exec's $SHELL. The variation with a dash in place of a name creates an anonymous session keyring and attaches that as the session keyring; it then exec's the supplied command, or $SHELL if one isn't supplied. The variation with a name supplied creates or joins the named keyring and attaches that as the session keyring; it then exec's the supplied command, or $SHELL if one isn't supplied. .RS .nf $ keyctl rdescribe @s keyring;4043;\-1;3f1f0000;_uid_ses.4043 $ keyctl session Joined session keyring: 28 $ keyctl rdescribe @s keyring;4043;4043;3f1f0000;_ses.24082 $ keyctl session \- Joined session keyring: 29 $ keyctl rdescribe @s keyring;4043;4043;3f1f0000;_ses.24139 $ keyctl session \- keyctl rdescribe @s Joined session keyring: 30 keyring;4043;4043;3f1f0000;_ses.24185 $ keyctl session fish Joined session keyring: 34 $ keyctl rdescribe @s keyring;4043;4043;3f1f0000;fish $ keyctl session fish keyctl rdesc @s Joined session keyring: 35 keyring;4043;4043;3f1f0000;fish .fi .RE .SS Instantiate a key \fBkeyctl instantiate\fR [\-x] .br \fBkeyctl pinstantiate\fR [\-x] .br \fBkeyctl negate\fR .br \fBkeyctl reject\fR These commands are used to attach data to a partially set up key (as created by the kernel and passed to .IR /sbin/request\-key ). "instantiate" marks a key as being valid and attaches the data as the payload. "negate" and "reject" mark a key as invalid and sets a timeout on it so that it'll go away after a while. This prevents a lot of quickly sequential requests from slowing the system down overmuch when they all fail, as all subsequent requests will then fail with error "Requested key not found" (if negated) or the specified error (if rejected) until the negative key has expired. Reject's error argument can either be a UNIX error number or one of .BR "" "'" rejected "', '" expired "' or '" revoked "'." The newly instantiated key will be attached to the specified keyring. These commands may only be run from the program run by request\-key - a special authorisation key is set up by the kernel and attached to the request\-key's session keyring. This special key is revoked once the key to which it refers has been instantiated one way or another. .RS .nf $ keyctl instantiate $1 "Debug $3" $4 $ keyctl negate $1 30 $4 $ keyctl reject $1 30 64 $4 .fi .RE The \fBpinstantiate\fR variant of the command reads the data from stdin rather than taking it from the command line: .RS .nf $ echo \-n "Debug $3" | keyctl pinstantiate $1 $4 .fi .RE If \fB\-x\fR is given, then the data is hex-decoded with whitespace being discarded: .RS .nf $ echo 01 02 03 04 | keyctl pinstantiate -x $1 $4 .fi .RE .SS Set the expiry time on a key \fBkeyctl timeout\fR This command is used to set the timeout on a key, or clear an existing timeout if the value specified is zero. The timeout is given as a number of seconds into the future. .RS .nf $ keyctl timeout $1 45 .fi .RE .SS Retrieve a key's security context \fBkeyctl security\fR This command is used to retrieve a key's LSM security context. The label is printed on stdout. .RS .nf $ keyctl security @s unconfined_u:unconfined_r:unconfined_t:s0\-s0:c0.c1023 .fi .RE .SS Give the parent process a new session keyring \fBkeyctl new_session []\fR This command is used to give the invoking process (typically a shell) a new session keyring, discarding its old session keyring. If a name is given, the keyring is given that name, otherwise it will be given a name of "_ses" and will not be manually joinable. .RS .nf $ keyctl session foo Joined session keyring: 723488146 $ keyctl show Session Keyring \-3 \-\-alswrv 0 0 keyring: foo $ keyctl new_session 490511412 $ keyctl show Session Keyring \-3 \-\-alswrv 0 0 keyring: _ses .fi .RE Note that this affects the \fIparent\fP of the process that invokes the system call, and so may only affect processes with matching credentials. Furthermore, the change does not take effect till the parent process next transitions from kernel space to user space - typically when the \fBwait\fP() system call returns. .SS Remove dead keys from the session keyring tree \fBkeyctl reap\fR This command performs a depth-first search of the caller's session keyring tree and attempts to unlink any key that it finds that is inaccessible due to expiry, revocation, rejection or negation. It does not attempt to remove live keys that are unavailable simply due to a lack of granted permission. A key that is designated reapable will only be removed from a keyring if the caller has Write permission on that keyring, and only keyrings that grant Search permission to the caller will be searched. The command prints the number of keys reaped before it exits. If the \fB\-v\fR flag is passed then the reaped keys are listed as they're being reaped, together with the success or failure of the unlink. .SS Remove matching keys from the session keyring tree \fBkeyctl\fR purge .br \fBkeyctl\fR purge [\-i] [\-p] .br \fBkeyctl\fR purge \-s These commands perform a depth-first search to find matching keys in the caller's session keyring tree and attempts to unlink them. The number of keys successfully unlinked is printed at the end. The keyrings must grant Read and View permission to the caller to be searched, and the keys to be removed must also grant View permission. Keys can only be removed from keyrings that grant Write permission. The first variant purges all keys of the specified type. The second variant purges all keys of the specified type that also match the given description literally. The \-i flag allows a case-independent match and the \-p flag allows a prefix match. The third variant purges all keys of the specified type and matching description using the key type's comparator in the kernel to match the description. This permits the key type to match a key with a variety of descriptions. .SS Get persistent keyring \fBkeyctl\fR get_persistent [] This command gets the persistent keyring for either the current UID or the specified UID and attaches it to the nominated keyring. The persistent keyring's ID will be printed on stdout. The kernel will create the keyring if it doesn't exist and every time this command is called, will reset the expiration timeout on the keyring to the value in: .IP /proc/sys/kernel/keys/persistent_keyring_expiry .P (by default three days). Should the timeout be reached, the persistent keyring will be removed and everything it pins can then be garbage collected. If a UID other than the process's real or effective UIDs is specified, then an error will be given if the process does not have the CAP_SETUID capability. .SS Compute a Diffie-Hellman shared secret or public key \fBkeyctl\fR dh_compute This command computes either a Diffie-Hellman shared secret or the public key corresponding to the provided private key using the payloads of three keys. The computation is: .IP base ^ private (mod prime) .P The three inputs must be user keys with read permission. If the provided base key contains the shared generator value, the public key will be computed. If the provided base key contains the remote public key value, the shared secret will be computed. The result is printed to stdout as a hex dump. .RS .nf $ keyctl dh_compute $1 $2 $3 8 bytes of data in result: 00010203 04050607 .fi .RE .SS Compute a Diffie-Hellman shared secret and derive key material \fBkeyctl\fR dh_compute_kdf This command computes a Diffie-Hellman shared secret and derives key material from the shared secret using a key derivation function (KDF). The shared secret is derived as outlined above and is input to the KDF using the specified hash type. The hash type must point to a hash name known to the kernel crypto API. The operation derives key material of the length specified by the caller. The operation is compliant to the specification of SP800-56A. The result is printed to stdout as hex dump. .SS Compute a Diffie-Hellman shared secret and apply KDF with other input \fBkeyctl\fR dh_compute_kdf_oi [\-x] This command is identical to the command .IR dh_compute_kdf to generate a Diffie-Hellman shared secret followed by a key derivation operation. This command allows the caller to provide the other input data (OI data) compliant to SP800-56A via stdin. If \fB\-x\fR is given, then the data passed to stdin is hex-decoded with whitespace being discarded. .SS Perform public-key operations with an asymmetric key \fBkeyctl\fR pkey_query [k=v]* .br \fBkeyctl\fR pkey_encrypt [k=v]* > .br \fBkeyctl\fR pkey_decrypt [k=v]* > .br \fBkeyctl\fR pkey_sign [k=v]* > .br \fBkeyctl\fR pkey_verify [k=v]* .PP These commands query an asymmetric key, encrypt data with it, decrypt the encrypted data, generate a signature over some data and verify that signature. For encrypt, decrypt and sign, the resulting data is written to stdout; verify reads the data and the signature files and compares them. .PP [\fB!\fP] NOTE that the data is of very limited capacity, with no more bits than the size of the key. For signatures, the caller is expected to digest the actual data and pass in the result of the digest as the datafile. The name of the digest should be specified on the end of the command line as "hash=". .PP The .I key ID indicates the key to use; .I pass is a placeholder for future password provision and should be "0" for the moment; .I datafile is the unencrypted data to be encrypted, signed or to have its signature checked; .I encfile is a file containing encrypted data; and .I sigfile is a file containing a signature. .PP A list of parameters in "key[=val]" form can be included on the end of the command line. These specify things like the digest algorithm used ("hash=") or the encoding form ("enc="). .PP .RS .nf k=`keyctl padd asymmetric "" @s foo.enc keyctl pkey_decrypt $k 0 foo.enc enc=pkcs1 >foo.hash keyctl pkey_sign $k 0 foo.hash enc=pkcs1 hash=sha256 >foo.sig keyctl pkey_verify $k 0 foo.hash foo.sig enc=pkcs1 hash=sha256 .fi .RE .PP See asymmetric-key(7) for more information. .SS Change notifications \fBkeyctl\fR watch [\-f] .br \fBkeyctl\fR watch_session [\-f ] [-n ] \\ [ ...] \fBkeyctl\fR watch_add .br \fBkeyctl\fR watch_rm .br .PP The .B watch command watches a single key, printing notifications to stdout until the key is destroyed. Filters can be employed to cut down the events that will be delivered. The .I filter string is a series of letters, each one of which enables a particular event subtype: .PP .RS .nf .BR i " - The key has been instantiated" .BR p " - The key has been updated" .BR l " - A link has been added to a keyring" .BR n " - A link has been removed from a keyring" .BR c " - A keyring has been cleared" .BR r " - A key has been revoked" .BR v " - A key has been invalidated" .BR s " - A key has had its attributes changed" .fi .RE .PP The output of the command looks like: .PP .RS .nf .RI < keyid "> <" event "> [<" aux ">]" .fi .RE .PP Where .I keyid is the primary subject of the notification, .I op is the event and .I aux is the secondary key if there is one (such as link where the primary key is the keyring secondary key is the key being linked in to it). For example: .PP .RS .nf 255913279 link 340681059 255913279 clr .fi .RE .PP An additional notication is generated when a key being watched is garbage collected, e.g.: .PP .RS .nf 255913279 gc .fi .RE .PP The .B watch_session command creates a new session keyring, with name .I name if given, watches it for notifications and runs program .I prog with it. The program is given the specified arguments. .PP A second process is forked off to monitor the notifications. The output from that is directed to the files .I notifylog for most notifications and .I gclog for key removal notifications (which are asynchronous and may be deferred). .PP The .BR watch_queue (7) device is exported to the program attached to fd number .IR fd . This can be passed by the other two commands. .PP The .B watch_add command adds a watch on .I key to the .B watch_queue attached to .I fd as exported by watch_session and the .B watch_rm caommand removes it. A watch_queue can handle multiple keys and even non-keys sources as well. .SH ERRORS There are a number of common errors returned by this program: "Not a directory" - a key wasn't a keyring. "Requested key not found" - the looked for key isn't available. "Key has been revoked" - a revoked key was accessed. "Key has expired" - an expired key was accessed. "Permission denied" - permission was denied by a UID/GID/mask combination. .SH SEE ALSO .ad l .nh .BR keyctl (1), .BR keyctl (2), .BR request_key (2), .BR keyctl (3), .BR request\-key.conf (5), .BR keyrings (7), .BR request\-key (8) keyutils-1.6.3/man/keyctl.3000066400000000000000000000051751370111642500155340ustar00rootroot00000000000000.\" .\" Copyright (C) 2010 Red Hat, Inc. All Rights Reserved. .\" Written by David Howells (dhowells@redhat.com) .\" .\" This program is free software; you can redistribute it and/or .\" modify it under the terms of the GNU General Public Licence .\" as published by the Free Software Foundation; either version .\" 2 of the Licence, or (at your option) any later version. .\" .TH KEYCTL 3 "21 Feb 2014" Linux "Linux Key Management Calls" .\""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" .SH NAME keyctl_*() \- key management function wrappers .\""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" .SH DESCRIPTION The .BR keyctl () system call is a multiplexor for a number of key management functions. These should be called via the wrappers in the libkeyutils library. .P The functions can be compiled in by including the \fBkeyutils\fR header file: .sp .RS .nf .B #include .RE .P and then telling the linker it should link in the library: .sp .RS .nf .B \-lkeyutils .RE .\""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" .SH KEYCTL FUNCTIONS .BR keyctl_assume_authority (3) .br .BR keyctl_chown (3) .br .BR keyctl_capabilities (3) .br .BR keyctl_clear (3) .br .BR keyctl_describe (3) .br .BR keyctl_describe_alloc (3) .br .BR keyctl_dh_compute (3) .br .BR keyctl_dh_compute_alloc (3) .br .BR keyctl_get_keyring_ID (3) .br .BR keyctl_get_persistent (3) .br .BR keyctl_get_security (3) .br .BR keyctl_get_security_alloc (3) .br .BR keyctl_instantiate (3) .br .BR keyctl_instantiate_iov (3) .br .BR keyctl_invalidate (3) .br .BR keyctl_join_session_keyring (3) .br .BR keyctl_link (3) .br .BR keyctl_move (3) .br .BR keyctl_negate (3) .br .BR keyctl_pkey_decrypt (3) .br .BR keyctl_pkey_encrypt (3) .br .BR keyctl_pkey_query (3) .br .BR keyctl_pkey_sign (3) .br .BR keyctl_pkey_verify (3) .br .BR keyctl_read (3) .br .BR keyctl_read_alloc (3) .br .BR keyctl_reject (3) .br .BR keyctl_restrict_keyring (3) .br .BR keyctl_revoke (3) .br .BR keyctl_search (3) .br .BR keyctl_session_to_parent (3) .br .BR keyctl_set_reqkey_keyring (3) .br .BR keyctl_set_timeout (3) .br .BR keyctl_setperm (3) .br .BR keyctl_unlink (3) .br .BR keyctl_update (3) .br .BR keyctl_watch_key (3) .\""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" .SH UTILITY FUNCTIONS .BR find_key_by_type_and_name (3) .br .BR recursive_key_scan (3) .br .BR recursive_session_key_scan (3) .\""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" .SH SEE ALSO .ad l .nh .BR keyctl (1), .BR add_key (2), .BR keyctl (2), .BR request_key (2), .BR keyrings (7), .BR keyutils (7) keyutils-1.6.3/man/keyctl_capabilities.3000066400000000000000000000102261370111642500202360ustar00rootroot00000000000000.\" .\" Copyright (C) 2019 Red Hat, Inc. All Rights Reserved. .\" Written by David Howells (dhowells@redhat.com) .\" .\" This program is free software; you can redistribute it and/or .\" modify it under the terms of the GNU General Public License .\" as published by the Free Software Foundation; either version .\" 2 of the License, or (at your option) any later version. .\" .TH KEYCTL_CAPABILITIES 3 "30 May 2019" Linux "Linux Key Management Calls" .\""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" .SH NAME keyctl_capabilities \- Query subsystem capabilities .\""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" .SH SYNOPSIS .nf .B #include .sp .BI "long keyctl_capabilities(unsigned char *" buffer ", size_t " buflen ");" .\""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" .SH DESCRIPTION .BR keyctl_capabilities () queries the keyrings subsystem in the kernel to ask about its capabilities and fills in the array in the buffer with bits that indicate the presence or absence of specific features in the keyrings subsystem. .P The function returns the amount of data the kernel has available, irrespective of the amount of buffer space available. If the buffer is shorter than the data, a short copy will be made; if the buffer is larger than the data, the excess space will be cleared. .P If this operation is not available in the kernel, the keyutils library will emulate it as best it can and the capability bit that indicates if the kernel operation is available will be cleared. .P In .IR buffer[0] , the following capabilities exist: .TP .B KEYCTL_CAPS0_CAPABILITIES This is set if the kernel supports this operation and cleared otherwise. If it is cleared, the rest of the flags are emulated. .TP .B KEYCTL_CAPS0_PERSISTENT_KEYRINGS This is set if the kernel supports persistent keyrings and cleared otherwise. See .BR keyctl_get_persistent ( 3 ). .TP .B KEYCTL_CAPS0_DIFFIE_HELLMAN This is set if the kernel supports Diffie-Hellman calculation and cleared otherwise. See .BR keyctl_dh_compute ( 3 ). .TP .B KEYCTL_CAPS0_PUBLIC_KEY This is set if the kernel supports public-key operations and cleared otherwise. See .BR keyctl_pkey_query ( 3 ). .TP .B KEYCTL_CAPS0_BIG_KEY This is set if the kernel supports the big_key key type and cleared otherwise. .TP .B KEYCTL_CAPS0_INVALIDATE This is set if the kernel supports key invalidation and cleared otherwise. See .BR keyctl_invalidate ( 3 ). .TP .B KEYCTL_CAPS0_RESTRICT_KEYRING This is set if the kernel supports restrictions on keyrings and cleared otherwise. See .BR keyctl_restrict_keyring ( 3 ). .TP .B KEYCTL_CAPS0_MOVE This is set if the kernel supports the move key operation and cleared otherwise. See .BR keyctl_move ( 3 ). .P In .IR buffer[1] , the following capabilities exist: .TP .B KEYCTL_CAPS1_NS_KEYRING_NAME This is set if the keyring names are segregated according to the user-namespace in which a keyring is created. .TP .B KEYCTL_CAPS1_NS_KEY_TAG This is set if a key or keyring may get tagged with a namespace, thereby allowing multiple keys with the same type and description, but different namespace tags, to coexist within the same keyring. Tagging may be automatic depending on the key type. Only network-namespace tagging is currently used. .P .\""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" .SH RETURN VALUE On success .BR keyctl_capabilities () returns the size of the data it has available, irrespective of the size of the buffer. On error, the value .B -1 will be returned and .I errno will have been set to an appropriate error. .\""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" .SH ERRORS .TP .B EFAULT The buffer cannot be written to. .\""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" .SH LINKING This is a library function that can be found in .IR libkeyutils . When linking, .B \-lkeyutils should be specified to the linker. .\""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" .SH SEE ALSO .ad l .nh .BR keyctl (1), .BR add_key (2), .BR keyctl (2), .BR request_key (2), .BR keyctl (3), .BR keyrings (7), .BR keyutils (7) keyutils-1.6.3/man/keyctl_chown.3000066400000000000000000000045731370111642500167330ustar00rootroot00000000000000.\" .\" Copyright (C) 2006 Red Hat, Inc. All Rights Reserved. .\" Written by David Howells (dhowells@redhat.com) .\" .\" This program is free software; you can redistribute it and/or .\" modify it under the terms of the GNU General Public License .\" as published by the Free Software Foundation; either version .\" 2 of the License, or (at your option) any later version. .\" .TH KEYCTL_CHOWN 3 "4 May 2006" Linux "Linux Key Management Calls" .\""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" .SH NAME keyctl_chown \- change the ownership of a key .\""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" .SH SYNOPSIS .nf .B #include .sp .BI "long keyctl_chown(key_serial_t " key ", uid_t " uid ", gid_t " gid ");" .\""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" .SH DESCRIPTION .BR keyctl_chown () changes the user and group ownership details of a key. .P A setting of .B -1 on either .I uid or .I gid will cause that setting to be ignored. .P A process that does not have the .B SysAdmin capability may not change a key's UID or set the key's GID to a value that does not match the process's GID or one of its group list. .P The caller must have .B setattr permission on a key to be able to change its ownership. .\""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" .SH RETURN VALUE On success .BR keyctl_chown () returns .B 0 . On error, the value .B -1 will be returned and .I errno will have been set to an appropriate error. .\""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" .SH ERRORS .TP .B ENOKEY The specified key does not exist. .TP .B EKEYEXPIRED The specified key has expired. .TP .B EKEYREVOKED The specified key has been revoked. .TP .B EDQUOT Changing the UID to the one specified would run that UID out of quota. .TP .B EACCES The key exists, but does not grant .B setattr permission to the calling process. .\""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" .SH LINKING This is a library function that can be found in .IR libkeyutils . When linking, .B \-lkeyutils should be specified to the linker. .\""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" .SH SEE ALSO .ad l .nh .BR keyctl (1), .BR add_key (2), .BR keyctl (2), .BR request_key (2), .BR keyctl (3), .BR keyrings (7), .BR keyutils (7) keyutils-1.6.3/man/keyctl_clear.3000066400000000000000000000037211370111642500166750ustar00rootroot00000000000000.\" .\" Copyright (C) 2006 Red Hat, Inc. All Rights Reserved. .\" Written by David Howells (dhowells@redhat.com) .\" .\" This program is free software; you can redistribute it and/or .\" modify it under the terms of the GNU General Public License .\" as published by the Free Software Foundation; either version .\" 2 of the License, or (at your option) any later version. .\" .TH KEYCTL_CLEAR 3 "4 May 2006" Linux "Linux Key Management Calls" .\""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" .SH NAME keyctl_clear \- clear a keyring .\""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" .SH SYNOPSIS .nf .B #include .sp .BI "long keyctl_clear(key_serial_t " keyring ");" .\""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" .SH DESCRIPTION .BR keyctl_clear () clears the contents of a .IR keyring . .P The caller must have .B write permission on a keyring to be able to clear it. .\""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" .SH RETURN VALUE On success .BR keyctl_clear () returns .BR 0 . On error, the value .B -1 will be returned and .I errno will have been set to an appropriate error. .\""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" .SH ERRORS .TP .B ENOKEY The keyring specified is invalid. .TP .B EKEYEXPIRED The keyring specified has expired. .TP .B EKEYREVOKED The keyring specified had been revoked. .TP .B EACCES The keyring exists, but is not .B writable by the calling process. .\""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" .SH LINKING This is a library function that can be found in .IR libkeyutils . When linking, .B \-lkeyutils should be specified to the linker. .\""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" .SH SEE ALSO .ad l .nh .BR keyctl (1), .BR add_key (2), .BR keyctl (2), .BR request_key (2), .BR keyctl (3), .BR keyrings (7), .BR keyutils (7) keyutils-1.6.3/man/keyctl_describe.3000066400000000000000000000066071370111642500173750ustar00rootroot00000000000000.\" .\" Copyright (C) 2006 Red Hat, Inc. All Rights Reserved. .\" Written by David Howells (dhowells@redhat.com) .\" .\" This program is free software; you can redistribute it and/or .\" modify it under the terms of the GNU General Public License .\" as published by the Free Software Foundation; either version .\" 2 of the License, or (at your option) any later version. .\" .TH KEYCTL_DESCRIBE 3 "4 May 2006" Linux "Linux Key Management Calls" .\""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" .SH NAME keyctl_describe \- describe a key .\""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" .SH SYNOPSIS .nf .B #include .sp .BI "long keyctl_describe(key_serial_t " key ", char *" buffer , .BI "size_t" buflen ");" .sp .BI "long keyctl_describe_alloc(key_serial_t " key ", char **" _buffer ");" .\""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" .SH DESCRIPTION .BR keyctl_describe () describes the attributes of a key as a NUL-terminated string. .P The caller must have .B view permission on a key to be able to get a description of it. .P .I buffer and .I buflen specify the buffer into which the key description will be placed. If the buffer is too small, the full size of the description will be returned, and no copy will take place. .P .BR keyctl_describe_alloc () is similar to .BR keyctl_describe () except that it allocates a buffer big enough to hold the description and places the description in it. If successful, A pointer to the buffer is placed in .IR *_buffer . The caller must free the buffer. .P The description will be a string of format: .IP .B "\*(lq%s;%d;%d;%08x;%s\*(rq" .P where the arguments are: key type name, key UID, key GID, key permissions mask and key description. .P .B NOTE! The key description will not contain any semicolons, so that should be separated out by working backwards from the end of the string. This permits extra information to be inserted before it by later versions of the kernel simply by inserting more semicolon-terminated substrings. .\""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" .SH RETURN VALUE On success .BR keyctl_describe () returns the amount of data placed into the buffer. If the buffer was too small, then the size of buffer required will be returned, but no data will be transferred. On error, the value .B -1 will be returned and .I errno will have been set to an appropriate error. .P On success .BR keyctl_describe_alloc () returns the amount of data in the buffer, less the NUL terminator. On error, the value .B -1 will be returned and .I errno will have been set to an appropriate error. .\""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" .SH ERRORS .TP .B ENOKEY The key specified is invalid. .TP .B EKEYEXPIRED The key specified has expired. .TP .B EKEYREVOKED The key specified had been revoked. .TP .B EACCES The key exists, but is not .B viewable by the calling process. .\""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" .SH LINKING This is a library function that can be found in .IR libkeyutils . When linking, .B \-lkeyutils should be specified to the linker. .\""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" .SH SEE ALSO .ad l .nh .BR keyctl (1), .BR add_key (2), .BR keyctl (2), .BR request_key (2), .BR keyctl (3), .BR keyrings (7), .BR keyutils (7) keyutils-1.6.3/man/keyctl_dh_compute.3000066400000000000000000000116351370111642500177410ustar00rootroot00000000000000.\" .\" Copyright (C) 2006 Red Hat, Inc. All Rights Reserved. .\" Copyright (C) 2016 Intel Corporation. All rights reserved. .\" .\" This program is free software; you can redistribute it and/or .\" modify it under the terms of the GNU General Public License .\" as published by the Free Software Foundation; either version .\" 2 of the License, or (at your option) any later version. .\" .TH KEYCTL_DH_COMPUTE 3 "07 Apr 2016" Linux "Linux Key Management Calls" .\""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" .SH NAME keyctl_dh_compute \- Compute a Diffie-Hellman shared secret or public key .br keyctl_dh_compute_kdf \- Derive key from a Diffie-Hellman shared secret .\""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" .SH SYNOPSIS .nf .B #include .sp .BI "long keyctl_dh_compute(key_serial_t " private ", key_serial_t " prime , .BI "key_serial_t " base ", char *" buffer ", size_t " buflen ");" .sp .BI "long keyctl_dh_compute_alloc(key_serial_t " private, .BI "key_serial_t " prime ", key_serial_t " base ", void **" _buffer ");" .sp .BI "long keyctl_dh_compute_kdf(key_serial_t " private ", key_serial_t " prime , .BI "key_serial_t " base ", char *" hashname ", char *" otherinfo ", .BI "size_t " otherinfolen ", char *" buffer ", size_t " buflen ");" .\""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" .SH DESCRIPTION .BR keyctl_dh_compute () computes a Diffie-Hellman public key or shared secret. That computation is: .IP .I base ^ .I private ( mod .I prime ) .P When .I base is a key containing the shared generator value, the remote public key is computed. When .I base is a key containing the remote public key, the shared secret is computed. .P .IR base ", " private ", and " prime must all refer to .BR user -type keys containing the parameters for the computation. Each of these keys must grant the caller .B read permission in order for them to be used. .P .I buffer and .I buflen specify the buffer into which the computed result will be placed. .I buflen may be zero, in which case the buffer is not used and the minimum buffer length is fetched. .P .BR keyctl_dh_compute_alloc () is similar to .BR keyctl_dh_compute () except that it allocates a buffer big enough to hold the payload data and places the data in it. If successful, a pointer to the buffer is placed in .IR *_buffer . The caller must free the buffer. .P .BR keyctl_dh_compute_kdf () derives a key from a Diffie-Hellman shared secret according to the protocol specified in SP800-56A. The Diffie-Hellman computation is based on the same primitives as discussed for .BR keyctl_dh_compute (). .P To implement the protocol of SP800-56A .I base is a key containing the remote public key to compute the Diffie-Hellman shared secret. That shared secret is post-processed with a key derivation function. .P The .I hashname specifies the Linux kernel crypto API name for a hash that shall be used for the key derivation function, such as sha256. The .I hashname must be a NULL terminated string. See .I /proc/crypto for available hashes on the system. .P Following the specification of SP800-56A section 5.8.1.2 the .I otherinfo parameter may be provided. The format of the OtherInfo field is defined by the caller. The caller may also specify NULL as a valid argument when no OtherInfo data shall be processed. The length of the .I otherinfo parameter is specified with .I otherinfolen and is restricted to a maximum length by the kernel. .P The KDF returns the requested number of bytes specified with the .I genlen or the .I buflen parameter depending on the invoked function. .P .I buffer and .I buflen specify the buffer into which the computed result will be placed. .P .\""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" .SH RETURN VALUE On success .BR keyctl_dh_compute () returns the amount of data placed into the buffer when .I buflen is non-zero. When .I buflen is zero, the minimum buffer length to hold the data is returned. .P On success .BR keyctl_dh_compute_alloc () returns the amount of data in the buffer. .P On error, both functions set errno to an appropriate code and return the value .BR -1 . .\""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" .SH ERRORS .TP .B ENOKEY One of the keys specified is invalid or not readable. .TP .B EINVAL The buffer pointer is invalid or buflen is too small. .TP .B EOPNOTSUPP One of the keys was not a valid user key. .TP .B EMSGSIZE When using .BR keyctl_dh_compute_kdf (), the size of either .I otherinfolen or .I buflen is too big. .\""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" .SH LINKING This is a library function that can be found in .IR libkeyutils . When linking, .B \-lkeyutils should be specified to the linker. .\""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" .SH SEE ALSO .BR keyctl (1), .br .BR keyctl (2), .br .BR keyctl (3), .br .BR keyutils (7) keyutils-1.6.3/man/keyctl_get_keyring_ID.3000066400000000000000000000057371370111642500205030ustar00rootroot00000000000000.\" .\" Copyright (C) 2006 Red Hat, Inc. All Rights Reserved. .\" Written by David Howells (dhowells@redhat.com) .\" .\" This program is free software; you can redistribute it and/or .\" modify it under the terms of the GNU General Public License .\" as published by the Free Software Foundation; either version .\" 2 of the License, or (at your option) any later version. .\" .TH KEYCTL_GET_KEYRING_ID 3 "4 May 2006" Linux "Linux Key Management Calls" .\""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" .SH NAME keyctl_get_keyring_ID \- get the ID of a special keyring .\""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" .SH SYNOPSIS .nf .B #include .sp .BI "key_serial_t keyctl_get_keyring_ID(key_serial_t " key "," .BI " int " create ");" .\""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" .SH DESCRIPTION .BR keyctl_get_keyring_ID () maps a special .I key or keyring ID to the serial number of the key actually representing that feature. The serial number will be returned if that key exists. .P If the key or keyring does not yet exist, then if .I create is non-zero, the key or keyring will be created if it is appropriate to do so. .P The following special key IDs may be specified as .IR key : .TP .B KEY_SPEC_THREAD_KEYRING This specifies the caller's thread-specific keyring. .TP .B KEY_SPEC_PROCESS_KEYRING This specifies the caller's process-specific keyring. .TP .B KEY_SPEC_SESSION_KEYRING This specifies the caller's session-specific keyring. .TP .B KEY_SPEC_USER_KEYRING This specifies the caller's UID-specific keyring. .TP .B KEY_SPEC_USER_SESSION_KEYRING This specifies the caller's UID-session keyring. .TP .B KEY_SPEC_REQKEY_AUTH_KEY This specifies the authorisation key created by .BR request_key () and passed to the process it spawns to generate a key. .P If a valid keyring ID is passed in, then this will simply be returned if the key exists; an error will be issued if it doesn't exist. .\""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" .SH RETURN VALUE On success .BR keyctl_get_keyring_ID () returns the serial number of the key it found. On error, the value .B -1 will be returned and .I errno will have been set to an appropriate error. .\""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" .SH ERRORS .TP .B ENOKEY No matching key was found. .TP .B ENOMEM Insufficient memory to create a key. .TP .B EDQUOT The key quota for this user would be exceeded by creating this key or linking it to the keyring. .\""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" .SH LINKING This is a library function that can be found in .IR libkeyutils . When linking, .B \-lkeyutils should be specified to the linker. .\""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" .SH SEE ALSO .ad l .nh .BR keyctl (1), .BR add_key (2), .BR keyctl (2), .BR request_key (2), .BR keyctl (3), .BR keyrings (7), .BR keyutils (7) keyutils-1.6.3/man/keyctl_get_persistent.3000066400000000000000000000064201370111642500206450ustar00rootroot00000000000000.\" .\" Copyright (C) 2013 Red Hat, Inc. All Rights Reserved. .\" Written by David Howells (dhowells@redhat.com) .\" .\" This program is free software; you can redistribute it and/or .\" modify it under the terms of the GNU General Public License .\" as published by the Free Software Foundation; either version .\" 2 of the License, or (at your option) any later version. .\" .TH KEYCTL_GET_PERSISTENT 3 "20 Feb 2014" Linux "Linux Key Management Calls" .\""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" .SH NAME keyctl_get_persistent \- get the persistent keyring for a user .\""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" .SH SYNOPSIS .nf .B #include .sp .BI "long keyctl_get_persistent(uid_t " uid ", key_serial_t " keyring ");" .\""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" .SH DESCRIPTION .BR keyctl_get_persistent () gets the persistent keyring for the specified user ID. Unlike the session and user keyrings, this keyring will persist once all login sessions have been deleted and can thus be used to carry authentication tokens for processes that run without user interaction, such as programs started by cron. .P The persistent keyring will be created by the kernel if it does not yet exist. Each time this function is called, the persistent keyring will have its expiration timeout reset to the value in: .IP /proc/sys/kernel/keys/persistent_keyring_expiry .P (by default three days). Should the timeout be reached, the persistent keyring will be removed and everything it pins can then be garbage collected. .P If .I uid is .B -1 then the calling process's real user ID will be used. If .I uid is not .B -1 then error .B EPERM will be given if the user ID requested does not match either the caller's real or effective user IDs or if the calling process does not have .B SetUid capability. .P If successful, a link to the persistent keyring will be added into .IR keyring . .\""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" .SH RETURN VALUE On success .BR keyctl_get_persistent () returns the serial number of the persistent keyring. On error, the value .B -1 will be returned and .I errno will have been set to an appropriate error. .\""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" .SH ERRORS .TP .B EPERM Not permitted to access the persistent keyring for the requested .IR uid . .TP .B ENOMEM Insufficient memory to create the persistent keyring or to extend .IR keyring . .TP .B ENOKEY .I keyring does not exist. .TP .B EKEYEXPIRED .I keyring has expired. .TP .B EKEYREVOKED .I keyring has been revoked. .TP .B EDQUOT The user does not have sufficient quota to extend .IR keyring . .TP .B EACCES .I keyring exists, but does not grant .B write permission to the calling process. .\""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" .SH LINKING This is a library function that can be found in .IR libkeyutils . When linking, .B \-lkeyutils should be specified to the linker. .\""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" .SH SEE ALSO .ad l .nh .BR keyctl (1), .BR add_key (2), .BR keyctl (2), .BR request_key (2), .BR keyctl (3), .BR keyrings (7), .BR keyutils (7), .BR persistent\-keyring (7), keyutils-1.6.3/man/keyctl_get_security.3000066400000000000000000000062021370111642500203120ustar00rootroot00000000000000.\" .\" Copyright (C) 2010 Red Hat, Inc. All Rights Reserved. .\" Written by David Howells (dhowells@redhat.com) .\" .\" This program is free software; you can redistribute it and/or .\" modify it under the terms of the GNU General Public License .\" as published by the Free Software Foundation; either version .\" 2 of the License, or (at your option) any later version. .\" .TH KEYCTL_GET_SECURITY 3 "26 Feb 2010" Linux "Linux Key Management Calls" .\""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" .SH NAME keyctl_get_security \- retrieve a key's security context .\""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" .SH SYNOPSIS .nf .B #include .sp .BI "long keyctl_get_security(key_serial_t " key ", char *" buffer , .BI "size_t " buflen ");" .sp .BI "long keyctl_get_security_alloc(key_serial_t " key ", char **" _buffer ");" .\""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" .SH DESCRIPTION .BR keyctl_get_security () retrieves the security context of a key as a NUL-terminated string. This will be rendered in a form appropriate to the LSM in force - for instance, with SELinux, it may look like .IP .B "unconfined_u:unconfined_r:unconfined_t:s0\-s0:c0.c1023" .P The caller must have .B view permission on a key to be able to get its security context. .P .I buffer and .I buflen specify the buffer into which the string will be placed. If the buffer is too small, the full size of the string will be returned, and no copy will take place. .P .BR keyctl_get_security_alloc () is similar to .BR keyctl_get_security () except that it allocates a buffer big enough to hold the string and copies the string into it. If successful, A pointer to the buffer is placed in .IR *_buffer . The caller must free the buffer. .\""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" .SH RETURN VALUE On success .BR keyctl_get_security () returns the amount of data placed into the buffer. If the buffer was too small, then the size of buffer required will be returned, but no data will be transferred. On error, the value .B -1 will be returned and .I errno will have been set to an appropriate error. .P On success .BR keyctl_get_security_alloc () returns the amount of data in the buffer, less the NUL terminator. On error, the value .B -1 will be returned and .I errno will have been set to an appropriate error. .\""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" .SH ERRORS .TP .B ENOKEY The key specified is invalid. .TP .B EKEYEXPIRED The key specified has expired. .TP .B EKEYREVOKED The key specified had been revoked. .TP .B EACCES The key exists, but is not .B viewable by the calling process. .\""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" .SH LINKING This is a library function that can be found in .IR libkeyutils . When linking, .B \-lkeyutils should be specified to the linker. .\""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" .SH SEE ALSO .ad l .nh .BR keyctl (1), .BR add_key (2), .BR keyctl (2), .BR request_key (2), .BR keyctl (3), .BR keyrings (7), .BR keyutils (7) keyutils-1.6.3/man/keyctl_instantiate.3000066400000000000000000000135611370111642500201350ustar00rootroot00000000000000.\" .\" Copyright (C) 2006 Red Hat, Inc. All Rights Reserved. .\" Written by David Howells (dhowells@redhat.com) .\" .\" This program is free software; you can redistribute it and/or .\" modify it under the terms of the GNU General Public License .\" as published by the Free Software Foundation; either version .\" 2 of the License, or (at your option) any later version. .\" .TH KEYCTL_INSTANTIATE 3 "4 May 2006" Linux "Linux Key Management Calls" .\""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" .SH NAME keyctl_assume_authority, keyctl_instantiate, keyctl_instantiate_iov, keyctl_reject, keyctl_negate \- key instantiation functions .\""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" .SH SYNOPSIS .nf .B #include .sp .BI "long keyctl_assume_authority(key_serial_t " key ");" .sp .BI "long keyctl_instantiate(key_serial_t " key ", const void *" payload , .BI "size_t " plen ", key_serial_t " keyring ");" .sp .BI "long keyctl_instantiate_iov(key_serial_t " key , .BI "const struct iovec *" payload_iov ", unsigned " ioc , .BI "key_serial_t " keyring ");" .sp .BI "long keyctl_negate(key_serial_t " key ", unsigned " timeout , .BI "key_serial_t " keyring ");" .sp .BI "long keyctl_reject(key_serial_t " key ", unsigned " timeout , .BI "unsigned " error ", key_serial_t " keyring ");" .\""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" .SH DESCRIPTION .BR keyctl_assume_authority () assumes the authority for the calling thread to deal with and instantiate the specified uninstantiated .IR key . .P The calling thread must have the appropriate authorisation key resident in one of its keyrings for this to succeed, and that authority must not have been revoked. .P The authorising key is allocated by .BR request_key() when it needs to invoke userspace to generate a key for the requesting process. This is then attached to one of the keyrings of the userspace process to which the task of instantiating the key is given: .IP requester -> request_key() -> instantiator .P Calling this function modifies the way .BR request_key () works when called thereafter by the calling (instantiator) thread; once the authority is assumed, the keyrings of the initial process are added to the search path, using the initial process's UID, GID, groups and security context. .P If a thread has multiple instantiations to deal with, it may call this function to change the authorisation key currently in effect. Supplying a .B zero .I key de-assumes the currently assumed authority. .P .B NOTE! This is a per-thread setting and not a per-process setting so that a multithreaded process can be used to instantiate several keys at once. .P .BR keyctl_instantiate () instantiates the payload of an uninstantiated key from the data specified. .I payload and .I plen specify the data for the new payload. .I payload may be NULL and .I plen may be zero if the key type permits that. The key type may reject the data if it's in the wrong format or in some other way invalid. .P .BR keyctl_instantiate_iov () is similar, but the data is passed in an array of iovec structs instead of in a flat buffer. .I payload_iov points to the base of the array and .I ioc indicates how many elements there are. .I payload_iov may be NULL or .I ioc may be zero to indicate that no data is being supplied. .P .BR keyctl_reject () marks a key as negatively instantiated and sets the expiration timer on it. .I timeout specifies the lifetime of the key in seconds. .I error specifies the error to be returned when a search hits the key (this is typically .BR EKEYREJECTED ", " EKEYREVOKED " or " EKEYEXPIRED ")." Note that .BR keyctl_reject () falls back to .BR keyctl_negate () if the kernel does not support it. .P .BR keyctl_negate () as .BR keyctl_reject () with an error code of .IB ENOKEY . .P Only a key for which authority has been assumed may be instantiated or negatively instantiated, and once instantiated, the authorisation key will be revoked and the requesting process will be able to resume. .P The destination .IR keyring , if given, is assumed to belong to the initial requester, and not the instantiating process. Therefore, the special keyring IDs refer to the requesting process's keyrings, not the caller's, and the requester's UID, etc. will be used to access them. .P The destination keyring can be .B zero if no extra link is desired. .P The requester, not the caller, must have .B write permission on the destination for a link to be made there. .\""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" .SH RETURN VALUE On success .BR keyctl_instantiate () returns .BR 0 . On error, the value .B -1 will be returned and .I errno will have been set to an appropriate error. .\""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" .SH ERRORS .TP .B ENOKEY The key or keyring specified is invalid. .TP .B EKEYEXPIRED The keyring specified has expired. .TP .B EKEYREVOKED The key or keyring specified had been revoked, or the authorisation has been revoked. .TP .B EINVAL The payload data was invalid. .TP .B ENOMEM Insufficient memory to store the new payload or to expand the destination keyring. .TP .B EDQUOT The key quota for the key's user would be exceeded by increasing the size of the key to accommodate the new payload or the key quota for the keyring's user would be exceeded by expanding the destination keyring. .TP .B EACCES The key exists, but is not .B writable by the requester. .\""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" .SH LINKING This is a library function that can be found in .IR libkeyutils . When linking, .B \-lkeyutils should be specified to the linker. .\""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" .SH SEE ALSO .ad l .nh .BR keyctl (1), .BR add_key (2), .BR keyctl (2), .BR request_key (2), .BR keyctl (3), .BR keyrings (7), .BR keyutils (7), .BR request\-key (8) keyutils-1.6.3/man/keyctl_invalidate.3000066400000000000000000000042561370111642500177330ustar00rootroot00000000000000.\" .\" Copyright (C) 2013 Red Hat, Inc. All Rights Reserved. .\" Written by David Howells (dhowells@redhat.com) .\" .\" This program is free software; you can redistribute it and/or .\" modify it under the terms of the GNU General Public License .\" as published by the Free Software Foundation; either version .\" 2 of the License, or (at your option) any later version. .\" .TH KEYCTL_INVALIDATE 3 "29 Aug 2013" Linux "Linux Key Management Calls" .\""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" .SH NAME keyctl_invalidate \- invalidate a key .\""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" .SH SYNOPSIS .nf .B #include .sp .BI "long keyctl_invalidate(key_serial_t " key ");" .\""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" .SH DESCRIPTION .BR keyctl_invalidate () invalidates a .IR key . The key is scheduled for immediate removal from all the keyrings that point to it, after which it will be deleted. The key will be ignored by all searches once this function is called even if it is not yet fully dealt with. .P The caller must have .B search permission on a key to be able to invalidate it. .\""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" .SH RETURN VALUE On success .BR keyctl_invalidate () returns .BR 0 . On error, the value .B -1 will be returned and .I errno will have been set to an appropriate error. .\""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" .SH ERRORS .TP .B ENOKEY The key specified is invalid. .TP .B EKEYEXPIRED The key specified has expired. .TP .B EKEYREVOKED The key specified had been revoked. .TP .B EACCES The key exists, but is not .B searchable by the calling process. .\""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" .SH LINKING This is a library function that can be found in .IR libkeyutils . When linking, .B \-lkeyutils should be specified to the linker. .\""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" .SH SEE ALSO .ad l .nh .BR keyctl (1), .BR add_key (2), .BR keyctl (2), .BR request_key (2), .BR keyctl (3), .BR keyrings (7), .BR keyutils (7) keyutils-1.6.3/man/keyctl_join_session_keyring.3000066400000000000000000000051241370111642500220400ustar00rootroot00000000000000.\" .\" Copyright (C) 2006 Red Hat, Inc. All Rights Reserved. .\" Written by David Howells (dhowells@redhat.com) .\" .\" This program is free software; you can redistribute it and/or .\" modify it under the terms of the GNU General Public License .\" as published by the Free Software Foundation; either version .\" 2 of the License, or (at your option) any later version. .\" .TH KEYCTL_JOIN_SESSION_KEYRING 3 "20 Feb 2014" Linux "Linux Key Management Calls" .\""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" .SH NAME keyctl_join_session_keyring \- join a different session keyring .\""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" .SH SYNOPSIS .nf .B #include .sp .BI "key_serial_t keyctl_join_session_keyring(const char *" name ");" .\""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" .SH DESCRIPTION .BR keyctl_join_session_keyring () changes the session keyring to which a process is subscribed. .P If .I name is .B NULL then a new anonymous keyring will be created, and the process will be subscribed to that. .P If .I name points to a string, then if a keyring of that name is available, the process will attempt to subscribe to that keyring, giving an error if that is not permitted; otherwise a new keyring of that name is created and attached as the session keyring. .P To attach to an extant named keyring, the keyring must have .B search permission available to the calling process. .\""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" .SH RETURN VALUE On success .BR keyctl_join_session_keyring () returns the serial number of the key it found or created. On error, the value .B -1 will be returned and .I errno will have been set to an appropriate error. .\""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" .SH ERRORS .TP .B ENOMEM Insufficient memory to create a key. .TP .B EDQUOT The key quota for this user would be exceeded by creating this key or linking it to the keyring. .TP .B EACCES The named keyring exists, but is not .B searchable by the calling process. .\""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" .SH LINKING This is a library function that can be found in .IR libkeyutils . When linking, .B \-lkeyutils should be specified to the linker. .\""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" .SH SEE ALSO .ad l .nh .BR keyctl (1), .BR add_key (2), .BR keyctl (2), .BR request_key (2), .BR keyctl (3), .BR keyrings (7), .BR keyutils (7), .BR session\-keyring (7), .BR user\-session\-keyring (7) keyutils-1.6.3/man/keyctl_link.3000066400000000000000000000052441370111642500165460ustar00rootroot00000000000000.\" .\" Copyright (C) 2006 Red Hat, Inc. All Rights Reserved. .\" Written by David Howells (dhowells@redhat.com) .\" .\" This program is free software; you can redistribute it and/or .\" modify it under the terms of the GNU General Public License .\" as published by the Free Software Foundation; either version .\" 2 of the License, or (at your option) any later version. .\" .TH KEYCTL_LINK 3 "4 May 2006" Linux "Linux Key Management Calls" .\""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" .SH NAME keyctl_link, keyctl_unlink \- link/unlink a key to/from a keyring .\""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" .SH SYNOPSIS .nf .B #include .sp .BI "long keyctl_link(key_serial_t " key ", key_serial_t " keyring ");" .sp .BI "long keyctl_unlink(key_serial_t " key ", key_serial_t " keyring ");" .\""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" .SH DESCRIPTION .BR keyctl_link () creates a link from .I keyring to .IR key , displacing any link to another key of the same type and description in that keyring if one exists. .P .BR keyctl_unlink () removes the link from .I keyring to .I key if it exists. .P The caller must have .B write permission on a keyring to be able to create or remove links in it. .P The caller must have .B link permission on a key to be able to create a link to it. .\""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" .SH RETURN VALUE On success .BR keyctl_link () and .BR keyctl_unlink () return .BR 0 . On error, the value .B -1 will be returned and .I errno will have been set to an appropriate error. .\""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" .SH ERRORS .TP .B ENOKEY The key or the keyring specified are invalid. .TP .B EKEYEXPIRED The key or the keyring specified have expired. .TP .B EKEYREVOKED The key or the keyring specified have been revoked. .TP .B EACCES The keyring exists, but is not .B writable by the calling process. .P For .BR keyctl_link () only: .TP .B ENOMEM Insufficient memory to expand the keyring .TP .B EDQUOT Expanding the keyring would exceed the keyring owner's quota. .TP .B EACCES The key exists, but is not .B linkable by the calling process. .\""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" .SH LINKING This is a library function that can be found in .IR libkeyutils . When linking, .B \-lkeyutils should be specified to the linker. .\""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" .SH SEE ALSO .ad l .nh .BR keyctl (1), .BR add_key (2), .BR keyctl (2), .BR request_key (2), .BR keyctl (3), .BR keyrings (7), .BR keyutils (7) keyutils-1.6.3/man/keyctl_move.3000066400000000000000000000056001370111642500165530ustar00rootroot00000000000000.\" .\" Copyright (C) 2019 Red Hat, Inc. All Rights Reserved. .\" Written by David Howells (dhowells@redhat.com) .\" .\" This program is free software; you can redistribute it and/or .\" modify it under the terms of the GNU General Public License .\" as published by the Free Software Foundation; either version .\" 2 of the License, or (at your option) any later version. .\" .TH KEYCTL_MOVE 3 "29 May 2019" Linux "Linux Key Management Calls" .\""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" .SH NAME keyctl_move \- Move a key between keyrings .\""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" .SH SYNOPSIS .nf .B #include .sp .BI "long keyctl_move(key_serial_t " key ", key_serial_t " from_keyring "," .br .BI " key_serial_t " to_keyring ", unsigned int " flags ");" .\""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" .SH DESCRIPTION .BR keyctl_move () atomically unlinks .I key from .I from_keyring and links it into .I to_keyring in a single operation. Depending on the flags set, a link to any matching key in to_keyring may get displaced. .P .I flags is a bitwise-OR of zero or more of the following flags: .P .TP .B KEYCTL_MOVE_EXCL If there's a matching key in to_keyring, don't displace it but rather return an error. .P The caller must have .B write permission on both keyring to be able to create or remove links in them. .P The caller must have .B link permission on a key to be able to create a new link to it. .\""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" .SH RETURN VALUE On success .BR keyctl_move () return .BR 0 . On error, the value .B -1 will be returned and .I errno will have been set to an appropriate error. .\""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" .SH ERRORS .TP .B ENOKEY The key or one of the keyrings specified are invalid. .TP .B ENOKEY A key with the same type and description is present in to_keyring and KEYCTL_MOVE_EXCL is set. .TP .B EKEYEXPIRED The key or one of the keyrings specified have expired. .TP .B EKEYREVOKED The key or one of the keyrings specified have been revoked. .TP .B EACCES The key exists, but is not .B linkable by the calling process. .TP .B EACCES The keyrings exist, but are not .B writable by the calling process. .TP .B ENOMEM Insufficient memory to effect the changes. .TP .B EDQUOT Expanding to_keyring would exceed the keyring owner's quota. .\""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" .SH LINKING This is a library function that can be found in .IR libkeyutils . When linking, .B \-lkeyutils should be specified to the linker. .\""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" .SH SEE ALSO .ad l .nh .BR keyctl (1), .BR add_key (2), .BR keyctl (2), .BR request_key (2), .BR keyctl (3), .BR keyrings (7), .BR keyutils (7) keyutils-1.6.3/man/keyctl_pkey_decrypt.3000066400000000000000000000000321370111642500203010ustar00rootroot00000000000000.so keyctl_pkey_encrypt.3 keyutils-1.6.3/man/keyctl_pkey_encrypt.3000066400000000000000000000100761370111642500203240ustar00rootroot00000000000000.\" .\" Copyright (C) 2018 Red Hat, Inc. All Rights Reserved. .\" Written by David Howells (dhowells@redhat.com) .\" .\" This program is free software; you can redistribute it and/or .\" modify it under the terms of the GNU General Public Licence .\" as published by the Free Software Foundation; either version .\" 2 of the Licence, or (at your option) any later version. .\" .TH KEYCTL_PKEY_ENCRYPT 3 "8 Nov 2018" Linux "Linux Public-Key Encryption" .\""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" .SH NAME keyctl_pkey_encrypt, keyctl_pkey_decrypt \- Encrypt and decrypt data .\""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" .SH SYNOPSIS .nf .B #include .sp .BI "long keyctl_pkey_encrypt(key_serial_t " key ", const char *" info , .BI " const void *" data ", size_t " data_len , .BI " void *" enc ", size_t " enc_len ");" .sp .BI "long keyctl_pkey_decrypt(key_serial_t " key ", const char *" info , .BI " const void *" enc ", size_t " enc_len , .BI " void *" data ", size_t " data_len ");" .\""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" .SH DESCRIPTION .BR keyctl_pkey_encrypt () asks the kernel to use the crypto material attached to a key to encrypt a blob of data and .BR keyctl_pkey_decrypt () asks the kernel to use the key to reverse the operation and recover the original data. Note that these operations may involve the kernel calling out to cryptographic hardware. The caller must have .B search permission on a key to be able to use them in this manner. .PP .PP When invoking the function, .I key indicates the key that will provide the cryptographic material and .I info points to a space- or tab-separated string of "key[=value]" parameters that indicate things like encoding forms and passwords to unlock the key; see asymmetric-key(7) for more information. .PP .IR data " and " datalen indicate the address and size of the decrypted data buffer and .IR enc " and " enclen indicate the address and size of the encrypted data buffer. The encrypt function draws data from the decrypted data buffer and places the output into the encryption buffer. The decrypt function does the reverse, drawing from the encryption buffer and writing into the data buffer. .PP .BR keyctl_pkey_query (2) can be called to find out how large the buffers need to be. .PP Note that not all asymmetric-type keys will support these operations; further, the operations available may depend on which components of the key material are available: typically encryption only requires the public key, but decryption requires the private key as well. Which operations are supported on a particular key can also be determined using the query function. .\""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" .SH RETURN VALUE On success .BR keyctl_pkey_encrypt "() and " keyctl_pkey_decrypt () return the amount of data written into the output buffer. On error, the value .B -1 will be returned and .I errno will have been set to an appropriate error. .\""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" .SH ERRORS .TP .B ENOKEY The key specified is invalid. .TP .B EKEYEXPIRED The key specified has expired. .TP .B EKEYREVOKED The key specified has been revoked. .TP .B EACCES The key exists, but is not .B searchable by the calling process. .TP .B ENOPKG Some facility needed to complete the requested operation is not available. This is most probably a requested or required digest or encryption algorithm. .TP .B EFAULT Bad address. .\""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" .SH LINKING This is a library function that can be found in .IR libkeyutils . When linking, .B \-lkeyutils should be specified to the linker. .\""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" .SH SEE ALSO .ad l .nh .BR keyctl (1), .BR add_key (2), .BR keyctl (2), .BR keyctl (3), .BR keyctl_pkey_query (3), .BR keyctl_pkey_sign (3), .BR keyrings (7), .BR keyutils (7) keyutils-1.6.3/man/keyctl_pkey_query.3000066400000000000000000000074711370111642500200120ustar00rootroot00000000000000.\" .\" Copyright (C) 2018 Red Hat, Inc. All Rights Reserved. .\" Written by David Howells (dhowells@redhat.com) .\" .\" This program is free software; you can redistribute it and/or .\" modify it under the terms of the GNU General Public Licence .\" as published by the Free Software Foundation; either version .\" 2 of the Licence, or (at your option) any later version. .\" .TH KEYCTL_PKEY_QUERY 3 "8 Nov 2018" Linux "Linux Key Management Calls" .\""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" .SH NAME keyctl_pkey_query \- Query public key parameters .\""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" .SH SYNOPSIS .nf .B #include .sp .BI "long keyctl_pkey_query(key_serial_t " key ", const char *" info , .BI " struct keyctl_pkey_query *" result ");" .\""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" .SH DESCRIPTION .BR keyctl_pkey_query () queries the public key parameters associated with a kernel key that supports these operations (typically .BR asymmetric -type). The caller must have .B search permission on the target key to be able to query its parameters. .PP When invoking the function, .I key indicates the key to be queried, .I info points to a space- or tab-separated string of "key[=value]" parameters and .I result points to a buffer in which the result will be placed. .PP The parameters that can be used in the .I info parameter string are dependent on the type of key. Parameters can specify such things as encoding types (such as "enc=pkcs1"); see asymmetric-key(7) for more information. .PP If successful, the result is written into the following struct: .PP .in +4n .EX struct keyctl_pkey_query { unsigned int supported_ops; unsigned int key_size; unsigned short max_data_size; unsigned short max_sig_size; unsigned short max_enc_size; unsigned short max_dec_size; }; .EE .in .PP The .I supported_ops field contains a bitmask of the following constants: .PP .in +4n .TS lB l. KEYCTL_SUPPORTS_ENCRYPT KEYCTL_SUPPORTS_DECRYPT KEYCTL_SUPPORTS_SIGN KEYCTL_SUPPORTS_VERIFY .TE .in .PP indicating what operations are supported and thus which of the other .BR keyctl_pkey_* () operations can be used with this key. .PP The .I key_size field indicates the number of bits in the key size and the .IR max_data_size ", " max_sig_size ", " max_enc_size " and " max_dec_size fields indicate the maximum sizes in bytes of a blob of data to be signed, a signature blob, a blob to be encrypted and a blob to be decrypted respectively. .\""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" .SH RETURN VALUE On success .BR keyctl_pkey_query () returns .BR 0 . On error, the value .B -1 will be returned and .I errno will have been set to an appropriate error. .\""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" .SH ERRORS .TP .B ENOKEY The key specified is invalid. .TP .B EKEYEXPIRED The key specified has expired. .TP .B EKEYREVOKED The key specified has been revoked. .TP .B EACCES The key exists, but is not .B searchable by the calling process. .TP .B ENOPKG Some facility needed to complete the requested operation is not available. This is most probably a requested or required digest or encryption algorithm. .TP .B EFAULT Bad address. .\""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" .SH LINKING This is a library function that can be found in .IR libkeyutils . When linking, .B \-lkeyutils should be specified to the linker. .\""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" .SH SEE ALSO .ad l .nh .BR keyctl (1), .BR add_key (2), .BR keyctl (2), .BR keyctl (3), .BR keyctl_pkey_encrypt (3), .BR keyctl_pkey_sign (3), .BR asymmetric-key (7), .BR keyrings (7), .BR keyutils (7) keyutils-1.6.3/man/keyctl_pkey_sign.3000066400000000000000000000114321370111642500175750ustar00rootroot00000000000000.\" .\" Copyright (C) 2018 Red Hat, Inc. All Rights Reserved. .\" Written by David Howells (dhowells@redhat.com) .\" .\" This program is free software; you can redistribute it and/or .\" modify it under the terms of the GNU General Public Licence .\" as published by the Free Software Foundation; either version .\" 2 of the Licence, or (at your option) any later version. .\" .TH KEYCTL_PKEY_SIGN 3 "8 Nov 2018" Linux "Linux Public-Key Signatures" .\""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" .SH NAME keyctl_pkey_sign, keyctl_pkey_verify \- Generate and verify signatures .\""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" .SH SYNOPSIS .nf .B #include .sp .BI "long keyctl_pkey_sign(key_serial_t " key ", const char *" info , .BI " const void *" data ", size_t " data_len , .BI " void *" sig ", size_t " sig_len ");" .sp .BI "long keyctl_pkey_verify(key_serial_t " key ", const char *" info , .BI " const void *" data ", size_t " data_len , .BI " const void *" sig ", size_t " sig_len ");" .\""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" .SH DESCRIPTION .BR keyctl_pkey_sign () asks the kernel to use the crypto data attached to a key to generate a detached signature for a blob of data. Note that this may involve calling out to cryptographic hardware. .PP .BR keyctl_pkey_verify () asks the kernel to use the key to generate a verify the signature against the same blob of data. This may also involve calling out to cryptographic hardware. .PP The caller must have .B search permission on a key to be able to perform either operation. .PP .PP When invoking the function, .I key indicates the key that will provide the cryptographic material and .I info points to a space- or tab-separated string of "key[=value]" parameters that indicate things like encoding forms and passwords to unlock the key; see asymmetric-key(7) for more information. .PP .IR data " and " datalen indicate the address and size of the buffer of data to be signed and .IR sig " and " siglen indicate the address and size of the signature buffer. The sign function draws data from the data buffer, generates a signature from it and places the output into the signature buffer. The verify function also draws data from the data buffer, then decrypts the signature and compares the result. .PP Note that the data buffer is strictly limited in capacity, typically unable to hold more bits than the size of the key. The caller is expected to have pre-digested the actual data and will thus pass the digest output to this function. The name of the digest used should be passed as part of the info string as \fPhash=\fR for use in constructing the signature metadata. .PP .BR keyctl_pkey_query (2) can be called to find out how large the buffers need to be and what the maximum size of the data can be for a specific signature encoding. .PP Note that not all asymmetric-type keys will support these operations; further, the operations available may depend on which components of the key material are available: typically encryption only requires the public key, but decryption requires the private key as well. Which operations are supported on a particular key can also be determined using the query function. .\""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" .SH RETURN VALUE On success .BR keyctl_pkey_sign () returns the amount of data written into the signature buffer. .BR keyctl_pkey_verify () will return 0 in this case as it doesn't write to userspace. .PP On error the value .B -1 will be returned and .I errno will have been set to an appropriate error. .\""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" .SH ERRORS .TP .B ENOKEY The key specified is invalid. .TP .B EKEYEXPIRED The key specified has expired. .TP .B EKEYREVOKED The key specified has been revoked. .TP .B EACCES The key exists, but is not .B searchable by the calling process. .TP .BR EINVAL ", " EBADMSG ", " EOVERFLOW Some part of the key material or signature data is bad. .TP .BR EKEYREJECTED Signature verification failed. .TP .B ENOPKG Some facility needed to complete the requested operation is not available. This is most probably a requested or required digest or encryption algorithm. .TP .B EFAULT Bad address. .\""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" .SH LINKING This is a library function that can be found in .IR libkeyutils . When linking, .B \-lkeyutils should be specified to the linker. .\""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" .SH SEE ALSO .ad l .nh .BR keyctl (1), .BR add_key (2), .BR keyctl (2), .BR keyctl (3), .BR keyctl_pkey_query (3), .BR keyrings (7), .BR keyutils (7) keyutils-1.6.3/man/keyctl_pkey_verify.3000066400000000000000000000000271370111642500201370ustar00rootroot00000000000000.so keyctl_pkey_sign.3 keyutils-1.6.3/man/keyctl_read.3000066400000000000000000000070211370111642500165170ustar00rootroot00000000000000.\" .\" Copyright (C) 2006 Red Hat, Inc. All Rights Reserved. .\" Written by David Howells (dhowells@redhat.com) .\" .\" This program is free software; you can redistribute it and/or .\" modify it under the terms of the GNU General Public License .\" as published by the Free Software Foundation; either version .\" 2 of the License, or (at your option) any later version. .\" .TH KEYCTL_READ 3 "21 Feb 2014" Linux "Linux Key Management Calls" .\""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" .SH NAME keyctl_read \- read a key .\""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" .SH SYNOPSIS .nf .B #include .sp .BI "long keyctl_read(key_serial_t " key ", char *" buffer ", size_t " buflen ");" .sp .BI "long keyctl_read_alloc(key_serial_t " key ", void **" _buffer ");" .\""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" .SH DESCRIPTION .BR keyctl_read () reads the payload of a key if the key type supports it. .P The caller must have .B read permission on a key to be able to read it. .P .I buffer and .I buflen specify the buffer into which the payload data will be placed. If the buffer is too small, then the full size of the payload will be returned, and the contents of the buffer may be overwritten in some undefined way. .P .BR keyctl_read_alloc () is similar to .BR keyctl_read () except that it allocates a buffer big enough to hold the payload data and places the data in it. If successful, a pointer to the buffer is placed in .IR *_buffer . The caller must free the buffer. .P .BR keyctl_read_alloc () adds a NUL character after the data it retrieves, though this is not counted in the size value it returns. .\""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" .SH READING KEYRINGS This call can be used to list the contents of a keyring. The data is presented to the user as an array of .B key_serial_t values, each of which corresponds to a key to which the keyring holds a link. .P The size of the keyring will be sizeof(key_serial_t) multiplied by the number of keys. The size of key_serial_t is invariant across different word sizes, though the byte-ordering is as appropriate for the kernel. .\""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" .SH RETURN VALUE On success .BR keyctl_read () returns the amount of data placed into the buffer. If the buffer was too small, then the size of buffer required will be returned, and the contents of the buffer may have been overwritten in some undefined way. .P On success .BR keyctl_read_alloc () returns the amount of data in the buffer. .P On error, both functions set .I errno to an appropriate code and return the value .BR -1 . .\""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" .SH ERRORS .TP .B ENOKEY The key specified is invalid. .TP .B EKEYEXPIRED The key specified has expired. .TP .B EKEYREVOKED The key specified had been revoked. .TP .B EACCES The key exists, but is not .B readable by the calling process. .TP .B EOPNOTSUPP The key type does not support reading of the payload data. .\""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" .SH LINKING This is a library function that can be found in .IR libkeyutils . When linking, .B \-lkeyutils should be specified to the linker. .\""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" .SH SEE ALSO .ad l .nh .BR keyctl (1), .BR add_key (2), .BR keyctl (2), .BR request_key (2), .BR keyctl (3), .BR keyrings (7), .BR keyutils (7) keyutils-1.6.3/man/keyctl_restrict_keyring.3000066400000000000000000000047231370111642500212010ustar00rootroot00000000000000.\" .\" Copyright (C) 2006 Red Hat, Inc. All Rights Reserved. .\" Copyright (C) 2017 Intel Corporation. All rights reserved. .\" .\" This program is free software; you can redistribute it and/or .\" modify it under the terms of the GNU General Public License .\" as published by the Free Software Foundation; either version .\" 2 of the License, or (at your option) any later version. .\" .TH KEYCTL_RESTRICT_KEYRING 3 "28 Feb 2017" Linux "Linux Key Management Calls" .\""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" .SH NAME keyctl_restrict_keyring \- restrict keys that may be linked to a keyring .\""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" .SH SYNOPSIS .nf .B #include .sp .BI "long keyctl_restrict_keyring(key_serial_t " keyring , .BI "const char *" type ", const char *" restriction ");" .\""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" .SH DESCRIPTION .BR keyctl_restrict_keyring () limits the linkage of keys to the given .I keyring using a provided key .I type and .I restriction scheme. The available options vary depending on the key type, and typically contain a restriction name possibly followed by key ids or other data relevant to the restriction. If the type and restriction are both .B NULL, the keyring will reject all links. .P .\""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" .SH RETURN VALUE On success .BR keyctl_restrict_keyring () returns .BR 0 . On error, the value .B -1 will be returned and .I errno will have been set to an appropriate error. .\""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" .SH ERRORS .TP .B EDEADLK A restriction cycle was avoided. Two keyrings cannot restrict each other. .TP .B EEXIST The keyring is already restricted. .TP .B EINVAL The restriction string is invalid or too large. .TP .B ENOKEY The key type in the restriction is invalid or not available. .TP .B ENOTDIR The provided key id references an item that is not a keyring. .TP .B ENOENT The key type exists but does not support restrictions. .\""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" .SH LINKING This is a library function that can be found in .IR libkeyutils . When linking, .B \-lkeyutils should be specified to the linker. .\""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" .SH SEE ALSO .ad l .nh .BR keyctl (1), .BR keyctl (2), .BR keyctl (3), .BR keyutils (7) keyutils-1.6.3/man/keyctl_revoke.3000066400000000000000000000037731370111642500171110ustar00rootroot00000000000000.\" .\" Copyright (C) 2006 Red Hat, Inc. All Rights Reserved. .\" Written by David Howells (dhowells@redhat.com) .\" .\" This program is free software; you can redistribute it and/or .\" modify it under the terms of the GNU General Public License .\" as published by the Free Software Foundation; either version .\" 2 of the License, or (at your option) any later version. .\" .TH KEYCTL_REVOKE 3 "4 May 2006" Linux "Linux Key Management Calls" .\""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" .SH NAME keyctl_revoke \- revoke a key .\""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" .SH SYNOPSIS .nf .B #include .sp .BI "long keyctl_revoke(key_serial_t " key ");" .\""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" .SH DESCRIPTION .BR keyctl_revoke () marks a key as being revoked. .P After this operation has been performed on a key, attempts to access it will meet with error .BR EKEYREVOKED . .P The caller must have .B write permission on a key to be able to revoke it. .\""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" .SH RETURN VALUE On success .BR keyctl_revoke () returns .BR 0 . On error, the value .B -1 will be returned and .I errno will have been set to an appropriate error. .\""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" .SH ERRORS .TP .B ENOKEY The specified key does not exist. .TP .B EKEYREVOKED The key has already been revoked. .TP .B EACCES The named key exists, but is not .B writable by the calling process. .\""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" .SH LINKING This is a library function that can be found in .IR libkeyutils . When linking, .B \-lkeyutils should be specified to the linker. .\""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" .SH SEE ALSO .ad l .nh .BR keyctl (1), .BR add_key (2), .BR keyctl (2), .BR request_key (2), .BR keyctl (3), .BR keyrings (7), .BR keyutils (7) keyutils-1.6.3/man/keyctl_search.3000066400000000000000000000101611370111642500170500ustar00rootroot00000000000000.\" .\" Copyright (C) 2006 Red Hat, Inc. All Rights Reserved. .\" Written by David Howells (dhowells@redhat.com) .\" .\" This program is free software; you can redistribute it and/or .\" modify it under the terms of the GNU General Public License .\" as published by the Free Software Foundation; either version .\" 2 of the License, or (at your option) any later version. .\" .TH KEYCTL_SEARCH 3 "4 May 2006" Linux "Linux Key Management Calls" .\""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" .SH NAME keyctl_search \- search a keyring for a key .\""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" .SH SYNOPSIS .nf .B #include .sp .BI "long keyctl_search(key_serial_t " keyring ", const char *" type , .BI "const char *" description ", key_serial_t " destination ");" .\""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" .SH DESCRIPTION .BR keyctl_search () recursively searches the .I keyring for a key of the specified .I type and .IR description . .P If found, the key will be attached to the .I destination keyring (if given), and its serial number will be returned. .P The source keyring must grant .B search permission to the caller, and for a key to be found, it must also grant .B search permission to the caller. Child keyrings will be only be recursively searched if they grant .B search permission to the caller as well. .P If the destination keyring is .BR zero , no attempt will be made to forge a link to the key, and just the serial number will be returned. .P If the destination keyring is given, then the link may only be formed if the found key grants the caller .B link permission and the destination keyring grants the caller .B write permission. .P If the search is successful, and if the destination keyring already contains a link to a key that matches the specified .IR type " and " description , then that link will be replaced by a link to the found key. .P The source keyring and destination keyring serial numbers may be those of valid keyrings to which the caller has appropriate permission, or they may be special keyring IDs: .TP .B KEY_SPEC_THREAD_KEYRING This specifies the caller's thread-specific keyring. .TP .B KEY_SPEC_PROCESS_KEYRING This specifies the caller's process-specific keyring. .TP .B KEY_SPEC_SESSION_KEYRING This specifies the caller's session-specific keyring. .TP .B KEY_SPEC_USER_KEYRING This specifies the caller's UID-specific keyring. .TP .B KEY_SPEC_USER_SESSION_KEYRING This specifies the caller's UID-session keyring. .\""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" .SH RETURN VALUE On success .BR keyctl_search () returns the serial number of the key it found. On error, the value .B -1 will be returned and .I errno will have been set to an appropriate error. .\""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" .SH ERRORS .TP .B ENOKEY One of the keyrings doesn't exist, no key was found by the search, or the only key found by the search was a negative key. .TP .B ENOTDIR One of the keyrings is a valid key that isn't a keyring. .TP .B EKEYEXPIRED One of the keyrings has expired, or the only key found was expired. .TP .B EKEYREVOKED One of the keyrings has been revoked, or the only key found was revoked. .TP .B ENOMEM Insufficient memory to expand the destination keyring. .TP .B EDQUOT The key quota for this user would be exceeded by creating a link to the found key in the destination keyring. .TP .B EACCES The source keyring didn't grant .B search permission, the destination keyring didn't grant .B write permission or the found key didn't grant .B link permission to the caller. .\""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" .SH LINKING Although this is a Linux system call, it is not present in .I libc but can be found rather in .IR libkeyutils . When linking, .B \-lkeyutils should be specified to the linker. .\""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" .SH SEE ALSO .ad l .nh .BR keyctl (1), .BR add_key (2), .BR keyctl (2), .BR request_key (2), .BR keyctl (3), .BR keyrings (7), .BR keyutils (7) keyutils-1.6.3/man/keyctl_session_to_parent.3000066400000000000000000000047321370111642500213500ustar00rootroot00000000000000.\" .\" Copyright (C) 2010 Red Hat, Inc. All Rights Reserved. .\" Written by David Howells (dhowells@redhat.com) .\" .\" This program is free software; you can redistribute it and/or .\" modify it under the terms of the GNU General Public License .\" as published by the Free Software Foundation; either version .\" 2 of the License, or (at your option) any later version. .\" .TH KEYCTL_SESSION_TO_PARENT 3 "20 Feb 2014" Linux "Linux Key Management Calls" .\""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" .SH NAME keyctl_session_to_parent \- set the parent process's session keyring .\""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" .SH SYNOPSIS .nf .B #include .sp .BI "long keyctl_session_to_parent();" .\""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" .SH DESCRIPTION .BR keyctl_session_to_parent () changes the session keyring to which the calling process's parent subscribes to be the that of the calling process. .P The keyring must have .B link permission available to the calling process, the parent process must have the same UIDs/GIDs as the calling process, and the LSM must not reject the replacement. Furthermore, this may not be used to affect init or a kernel thread. .P Note that the replacement will not take immediate effect upon the parent process, but will rather be deferred to the next time it returns to userspace from kernel space. .\""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" .SH RETURN VALUE On success .BR keyctl_session_to_parent () returns 0. On error, the value .B -1 will be returned and .I errno will have been set to an appropriate error. .\""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" .SH ERRORS .TP .B ENOMEM Insufficient memory to create a key. .TP .B EPERM The credentials of the parent don't match those of the caller. .TP .B EACCES The named keyring exists, but is not .B linkable by the calling process. .\""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" .SH LINKING This is a library function that can be found in .IR libkeyutils . When linking, .B \-lkeyutils should be specified to the linker. .\""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" .SH SEE ALSO .ad l .nh .BR keyctl (1), .BR add_key (2), .BR keyctl (2), .BR request_key (2), .BR keyctl (3), .BR keyrings (7), .BR keyutils (7), .BR session\-keyring (7), .BR user\-session-keyring (7) keyutils-1.6.3/man/keyctl_set_reqkey_keyring.3000066400000000000000000000061501370111642500215110ustar00rootroot00000000000000.\" .\" Copyright (C) 2006 Red Hat, Inc. All Rights Reserved. .\" Written by David Howells (dhowells@redhat.com) .\" .\" This program is free software; you can redistribute it and/or .\" modify it under the terms of the GNU General Public License .\" as published by the Free Software Foundation; either version .\" 2 of the License, or (at your option) any later version. .\" .TH KEYCTL_SET_REQKEY_KEYRING 3 "4 May 2006" Linux "Linux Key Management Calls" .\""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" .SH NAME keyctl_set_reqkey_keyring \- set the implicit destination keyring .\""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" .SH SYNOPSIS .nf .B #include .sp .BI "long keyctl_set_reqkey_keyring(int " reqkey_defl ");" .\""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" .SH DESCRIPTION .BR keyctl_set_reqkey_keyring () sets the default destination for implicit key requests for the current thread and returns the old setting. .P After this operation has been issued, keys acquired by implicit key requests, such as might be performed by .BR open () on an AFS or NFS filesystem, will be linked by default to the specified keyring by this function. .P The valid values of .I reqkey_defl are: .TP .B KEY_REQKEY_DEFL_NO_CHANGE This makes no change to the current setting. .TP .B KEY_REQKEY_DEFL_THREAD_KEYRING This makes the thread-specific keyring the default destination. .TP .B KEY_REQKEY_DEFL_PROCESS_KEYRING This makes the process-specific keyring the default destination. .TP .B KEY_REQKEY_DEFL_SESSION_KEYRING This makes the session keyring the default destination. .TP .B KEY_REQKEY_DEFL_USER_KEYRING This makes the UID-specific keyring the default destination. .TP .B KEY_REQKEY_DEFL_USER_SESSION_KEYRING This makes the UID-specific session keyring the default destination. .TP .B KEY_REQKEY_DEFL_DEFAULT This selects the default behaviour which is to use the thread-specific keyring if there is one, otherwise the process-specific keyring if there is one, otherwise the session keyring if there is one, otherwise the UID-specific session keyring. .P This setting is inherited across .BR fork () and .BR exec (). .\""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" .SH RETURN VALUE On success .BR keyctl_set_reqkey_keyring () returns the serial number of the keyring which was the previous default for the current thread. On error, the value .B -1 will be returned and .I errno will have been set to an appropriate error. .\""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" .SH ERRORS .TP .B EINVAL The value of .I reqkey_defl is invalid. .\""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" .SH LINKING This is a library function that can be found in .IR libkeyutils . When linking, .B \-lkeyutils should be specified to the linker. .\""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" .SH SEE ALSO .ad l .nh .BR keyctl (1), .BR add_key (2), .BR keyctl (2), .BR request_key (2), .BR keyctl (3), .BR keyutils (7), .BR keyrings (7), .BR request\-key (8) keyutils-1.6.3/man/keyctl_set_timeout.3000066400000000000000000000044321370111642500201500ustar00rootroot00000000000000.\" .\" Copyright (C) 2006 Red Hat, Inc. All Rights Reserved. .\" Written by David Howells (dhowells@redhat.com) .\" .\" This program is free software; you can redistribute it and/or .\" modify it under the terms of the GNU General Public License .\" as published by the Free Software Foundation; either version .\" 2 of the License, or (at your option) any later version. .\" .TH KEYCTL_SET_TIMEOUT 3 "4 May 2006" Linux "Linux Key Management Calls" .\""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" .SH NAME keyctl_set_timeout \- set the expiration timer on a key .\""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" .SH SYNOPSIS .nf .B #include .sp .BI "long keyctl_set_timeout(key_serial_t " key ", unsigned " timeout ");" .\""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" .SH DESCRIPTION .BR keyctl_set_timeout () sets the expiration timer on a key to .I timeout seconds into the future. Setting .I timeout to .B zero cancels the expiration, assuming the key hasn't already expired. .P When the key expires, further attempts to access it will be met with error .BR EKEYEXPIRED . .P The caller must have .B setattr permission on a key to be able to change its permissions mask. .\""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" .SH RETURN VALUE On success .BR keyctl_set_timeout () returns .B 0 . On error, the value .B -1 will be returned and .I errno will have been set to an appropriate error. .\""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" .SH ERRORS .TP .B ENOKEY The specified key does not exist. .TP .B EKEYEXPIRED The specified key has already expired. .TP .B EKEYREVOKED The specified key has been revoked. .TP .B EACCES The named key exists, but does not grant .B setattr permission to the calling process. .\""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" .SH LINKING This is a library function that can be found in .IR libkeyutils . When linking, .B \-lkeyutils should be specified to the linker. .\""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" .SH SEE ALSO .ad l .nh .BR keyctl (1), .BR add_key (2), .BR keyctl (2), .BR request_key (2), .BR keyctl (3), .BR keyrings (7), .BR keyutils (7) keyutils-1.6.3/man/keyctl_setperm.3000066400000000000000000000072521370111642500172710ustar00rootroot00000000000000.\" .\" Copyright (C) 2006 Red Hat, Inc. All Rights Reserved. .\" Written by David Howells (dhowells@redhat.com) .\" .\" This program is free software; you can redistribute it and/or .\" modify it under the terms of the GNU General Public License .\" as published by the Free Software Foundation; either version .\" 2 of the License, or (at your option) any later version. .\" .TH KEYCTL_SETPERM 3 "4 May 2006" Linux "Linux Key Management Calls" .\""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" .SH NAME keyctl_setperm \- change the permissions mask on a key .\""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" .SH SYNOPSIS .nf .B #include .sp .BI "long keyctl_setperm(key_serial_t " key ", key_perm_t " perm ");" .\""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" .SH DESCRIPTION .BR keyctl_setperm () changes the permissions mask on a key. .P A process that does not have the .B SysAdmin capability may not change the permissions mask on a key that doesn't have the same UID as the caller. .P The caller must have .B setattr permission on a key to be able to change its permissions mask. .P The permissions mask is a bitwise-OR of the following flags: .TP .B KEY_xxx_VIEW Grant permission to view the attributes of a key. .TP .B KEY_xxx_READ Grant permission to read the payload of a key or to list a keyring. .TP .B KEY_xxx_WRITE Grant permission to modify the payload of a key or to add or remove links to/from a keyring. .TP .B KEY_xxx_SEARCH Grant permission to find a key or to search a keyring. .TP .B KEY_xxx_LINK Grant permission to make links to a key. .TP .B KEY_xxx_SETATTR Grant permission to change the ownership and permissions attributes of a key. .TP .B KEY_xxx_ALL Grant all the above. .P The .RB ' xxx ' in the above should be replaced by one of: .TP .B POS Grant the permission to a process that possesses the key (has it attached searchably to one of the process's keyrings). .TP .B USR Grant the permission to a process with the same UID as the key. .TP .B GRP Grant the permission to a process with the same GID as the key, or with a match for the key's GID amongst that process's Groups list. .TP .B OTH Grant the permission to any other process. .P Examples include: .BR KEY_POS_VIEW ", " KEY_USR_READ ", " KEY_GRP_SEARCH " and " KEY_OTH_ALL . .P User, group and other grants are exclusive: if a process qualifies in the 'user' category, it will not qualify in the 'groups' category; and if a process qualifies in either 'user' or 'groups' then it will not qualify in the 'other' category. .P Possessor grants are cumulative with the grants from the 'user', 'groups' and 'other' categories. .\""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" .SH RETURN VALUE On success .BR keyctl_setperm () returns .B 0 . On error, the value .B -1 will be returned and .I errno will have been set to an appropriate error. .\""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" .SH ERRORS .TP .B ENOKEY The specified key does not exist. .TP .B EKEYEXPIRED The specified key has expired. .TP .B EKEYREVOKED The specified key has been revoked. .TP .B EACCES The named key exists, but does not grant .B setattr permission to the calling process. .\""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" .SH LINKING This is a library function that can be found in .IR libkeyutils . When linking, .B \-lkeyutils should be specified to the linker. .\""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" .SH SEE ALSO .ad l .nh .BR keyctl (1), .BR add_key (2), .BR keyctl (2), .BR request_key (2), .BR keyctl (3), .BR keyrings (7), .BR keyutils (7) keyutils-1.6.3/man/keyctl_update.3000066400000000000000000000050351370111642500170710ustar00rootroot00000000000000.\" .\" Copyright (C) 2006 Red Hat, Inc. All Rights Reserved. .\" Written by David Howells (dhowells@redhat.com) .\" .\" This program is free software; you can redistribute it and/or .\" modify it under the terms of the GNU General Public License .\" as published by the Free Software Foundation; either version .\" 2 of the License, or (at your option) any later version. .\" .TH KEYCTL_UPDATE 3 "4 May 2006" Linux "Linux Key Management Calls" .\""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" .SH NAME keyctl_update \- update a key .\""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" .SH SYNOPSIS .nf .B #include .sp .BI "long keyctl_update(key_serial_t " key ", const void *" payload , .BI "size_t " plen ");" .\""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" .SH DESCRIPTION .BR keyctl_update () updates the payload of a key if the key type permits it. .P The caller must have .B write permission on a key to be able to update it. .P .I payload and .I plen specify the data for the new payload. .I payload may be NULL and .I plen may be zero if the key type permits that. The key type may reject the data if it's in the wrong format or in some other way invalid. .\""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" .SH RETURN VALUE On success .BR keyctl_update () returns .BR 0 . On error, the value .B -1 will be returned and .I errno will have been set to an appropriate error. .\""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" .SH ERRORS .TP .B ENOKEY The key specified is invalid. .TP .B EKEYEXPIRED The key specified has expired. .TP .B EKEYREVOKED The key specified had been revoked. .TP .B EINVAL The payload data was invalid. .TP .B ENOMEM Insufficient memory to store the new payload. .TP .B EDQUOT The key quota for this user would be exceeded by increasing the size of the key to accommodate the new payload. .TP .B EACCES The key exists, but is not .B writable by the calling process. .TP .B EOPNOTSUPP The key type does not support the update operation on its keys. .\""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" .SH LINKING This is a library function that can be found in .IR libkeyutils . When linking, .B \-lkeyutils should be specified to the linker. .\""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" .SH SEE ALSO .ad l .nh .BR keyctl (1), .BR add_key (2), .BR keyctl (2), .BR request_key (2), .BR keyctl (3), .BR keyrings (7), .BR keyutils (7) keyutils-1.6.3/man/keyctl_watch_key.3000066400000000000000000000125141370111642500175650ustar00rootroot00000000000000.\" .\" Copyright (C) 2019 Red Hat, Inc. All Rights Reserved. .\" Written by David Howells (dhowells@redhat.com) .\" .\" This program is free software; you can redistribute it and/or .\" modify it under the terms of the GNU General Public License .\" as published by the Free Software Foundation; either version .\" 2 of the License, or (at your option) any later version. .\" .TH KEYCTL_GRANT_PERMISSION 3 "28 Aug 2019" Linux "Linux Key Management Calls" .\""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" .SH NAME keyctl_watch_key \- Watch for changes to a key .\""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" .SH SYNOPSIS .nf .B #include .sp .BI "long keyctl_watch_key(key_serial_t " key , .BI " int " watch_queue_fd .BI " int " watch_id ");" .\""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" .SH DESCRIPTION .BR keyctl_watch_key () sets or removes a watch on .IR key . .PP .I watch_id specifies the ID for a watch that will be included in notification messages. It can be between 0 and 255 to add a key; it should be -1 to remove a key. .PP .I watch_queue_fd is a file descriptor attached to a watch_queue device instance. Multiple openings of a device provide separate instances. Each device instance can only have one watch on any particular key. .\""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" .SS Notification Record .PP Key-specific notification messages that the kernel emits into the buffer have the following format: .PP .in +4n .EX struct key_notification { struct watch_notification watch; __u32 key_id; __u32 aux; }; .EE .in .PP The .I watch.type field will be set to .B WATCH_TYPE_KEY_NOTIFY and the .I watch.subtype field will contain one of the following constants, indicating the event that occurred and the watch_id passed to keyctl_watch_key() will be placed in .I watch.info in the ID field. The following events are defined: .TP .B NOTIFY_KEY_INSTANTIATED This indicates that a watched key got instantiated or negatively instantiated. .I key_id indicates the key that was instantiated and .I aux is unused. .TP .B NOTIFY_KEY_UPDATED This indicates that a watched key got updated or instantiated by update. .I key_id indicates the key that was updated and .I aux is unused. .TP .B NOTIFY_KEY_LINKED This indicates that a key got linked into a watched keyring. .I key_id indicates the keyring that was modified .I aux indicates the key that was added. .TP .B NOTIFY_KEY_UNLINKED This indicates that a key got unlinked from a watched keyring. .I key_id indicates the keyring that was modified .I aux indicates the key that was removed. .TP .B NOTIFY_KEY_CLEARED This indicates that a watched keyring got cleared. .I key_id indicates the keyring that was cleared and .I aux is unused. .TP .B NOTIFY_KEY_REVOKED This indicates that a watched key got revoked. .I key_id indicates the key that was revoked and .I aux is unused. .TP .B NOTIFY_KEY_INVALIDATED This indicates that a watched key got invalidated. .I key_id indicates the key that was invalidated and .I aux is unused. .TP .B NOTIFY_KEY_SETATTR This indicates that a watched key had its attributes (owner, group, permissions, timeout) modified. .I key_id indicates the key that was modified and .I aux is unused. .\""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" .SS Removal Notification When a watched key is garbage collected, all of its watches are automatically destroyed and a notification is delivered to each watcher. This will normally be an extended notification of the form: .PP .in +4n .EX struct watch_notification_removal { struct watch_notification watch; __u64 id; }; .EE .in .PP The .I watch.type field will be set to .B WATCH_TYPE_META and the .I watch.subtype field will contain .BR WATCH_META_REMOVAL_NOTIFICATION . If the extended notification is given, then the length will be 2 units, otherwise it will be 1 and only the header will be present. .PP The watch_id passed to .IR keyctl_watch_key () will be placed in .I watch.info in the ID field. .PP If the extension is present, .I id will be set to the ID of the destroyed key. .PP .\""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" .SH RETURN VALUE On success .BR keyctl_watch_key () returns .B 0 . On error, the value .B -1 will be returned and .I errno will have been set to an appropriate error. .\""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" .SH ERRORS .TP .B ENOKEY The specified key does not exist. .TP .B EKEYEXPIRED The specified key has expired. .TP .B EKEYREVOKED The specified key has been revoked. .TP .B EACCES The named key exists, but does not grant .B view permission to the calling process. .TP .B EBUSY The specified key already has a watch on it for that device instance (add only). .TP .B EBADSLT The specified key doesn't have a watch on it (removal only). .\""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" .SH LINKING This is a library function that can be found in .IR libkeyutils . When linking, .B \-lkeyutils should be specified to the linker. .\""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" .SH SEE ALSO .ad l .nh .BR keyctl (1), .BR add_key (2), .BR keyctl (2), .BR request_key (2), .BR keyctl (3), .BR keyrings (7), .BR keyutils (7) keyutils-1.6.3/man/keyutils.7000066400000000000000000000052311370111642500161070ustar00rootroot00000000000000.\" .\" Copyright (C) 2014 Red Hat, Inc. All Rights Reserved. .\" Written by David Howells (dhowells@redhat.com) .\" .\" This program is free software; you can redistribute it and/or .\" modify it under the terms of the GNU General Public Licence .\" as published by the Free Software Foundation; either version .\" 2 of the Licence, or (at your option) any later version. .\" .TH KEYUTILS 7 "21 Feb 2014" Linux "Kernel key management" .\""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" .SH NAME keyutils \- in-kernel key management utilities .\""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" .SH DESCRIPTION The .B keyutils package is a library and a set of utilities for accessing the kernel \fBkeyrings\fP facility. .P A header file is supplied to provide the definitions and declarations required to access the library: .P .RS .B #include .RE .P To link with the library, the following: .P .RS .B \-lkeyutils .RE .P should be specified to the linker. .P Three system calls are provided: .TP .BR add_key (2) Supply a new key to the kernel. .TP .BR request_key (2) Find an existing key for use, or, optionally, create one if one does not exist. .TP .BR keyctl (2) Control a key in various ways. The library provides a variety of wrappers around this system call and those should be used rather than calling it directly. .P See the .BR add_key (2), .BR request_key (2), and .BR keyctl (2) manual pages for more information. .P The \fBkeyctl\fP() wrappers are listed on the .BR keyctl (3) manual page. .\""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" .SH UTILITIES .P A program is provided to interact with the kernel facility by a number of subcommands, e.g.: .P .RS .B keyctl add user foo bar @s .RE .P See the .BR keyctl (1) manual page for information on that. .P The kernel has the ability to upcall to userspace to fabricate new keys. This can be triggered by \fBrequest_key\fP(), but userspace is better off using \fBadd_key\fP() instead if it possibly can. .P The upcalling mechanism is usually routed via the .BR request\-key (8) program. What this does with any particular key is configurable in: .P .RS .I /etc/request\-key.conf .br .I /etc/request\-key.d/ .RE .P See the .BR request\-key.conf (5) and the .BR request\-key (8) manual pages for more information. .\""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" .SH SEE ALSO .ad l .nh .BR keyctl (1), .BR keyctl (3), .BR keyrings (7), .BR persistent\-keyring (7), .BR process\-keyring (7), .BR session\-keyring (7), .BR thread\-keyring (7), .BR user\-keyring (7), .BR user\-session\-keyring (7), .BR pam_keyinit (8) keyutils-1.6.3/man/recursive_key_scan.3000066400000000000000000000060351370111642500201200ustar00rootroot00000000000000.\" .\" Copyright (C) 2011 Red Hat, Inc. All Rights Reserved. .\" Written by David Howells (dhowells@redhat.com) .\" .\" This program is free software; you can redistribute it and/or .\" modify it under the terms of the GNU General Public Licence .\" as published by the Free Software Foundation; either version .\" 2 of the Licence, or (at your option) any later version. .\" .TH RECURSIVE_KEY_SCAN 3 "10 Mar 2011" Linux "Linux Key Utility Calls" .\""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" .SH NAME recursive_key_scan, recursive_session_key_scan \- apply a function to all keys in a keyring tree .\""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" .SH SYNOPSIS .nf .B #include .sp .BI "typedef int (*" recursive_key_scanner_t ")(key_serial_t " parent , .BI " key_serial_t " key ", char *" desc ", int " desc_len ", void *" data ");" .sp .BI "long recursive_key_scan(key_serial_t " keyring , .BI " recursive_key_scanner_t " func ", void *" data ");" .br .BI "long recursive_session_key_scan(recursive_key_scanner_t " func , .BI " void *" data ");" .\""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" .SH DESCRIPTION .BR recursive_key_scan () performs a depth-first recursive scan of the specified .I keyring tree and applies .I func to every link found in the accessible keyrings in that tree. .I data is passed to each invocation of func. .P The return values of .I func are summed and returned as the overall return value. Errors are ignored. Inaccessible keyrings are not scanned, but links to them are still passed to func. .P .BR recursive_session_key_scan () works exactly like .BR recursive_key_scan () with the caller's session keyring specified as the starting keyring. .P The callback function is called for each link found in all the keyrings in the nominated tree and so may be called multiple times for a particular key if that key has multiple links to it. .P The callback function is passed the following parameters: .TP .B parent The keyring containing the link or 0 for the initial key. .TP .BR key The key to which the link points. .TP .BR desc " and " desc_len A pointer to the raw description and its length as retrieved with .BR keyctl_describe_alloc (). These will be NULL and \-1 respectively if the description couldn't be retrieved and .I errno will retain the error from .BR keyctl_describe_alloc (). .TP .B data The data passed to the scanner function. .\""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" .SH RETURN VALUE These functions return the sum of the results of the callback functions they invoke. .\""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" .SH ERRORS Ignored. .\""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" .SH LINKING When linking, .B \-lkeyutils should be specified to the linker. .\""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" .SH SEE ALSO .ad l .nh .BR keyctl (3), .BR keyctl_describe_alloc (3), .BR keyrings (7) keyutils-1.6.3/man/request-key.8000066400000000000000000000041771370111642500165250ustar00rootroot00000000000000.\" .\" Copyright (C) 2004 Red Hat, Inc. All Rights Reserved. .\" Written by David Howells (dhowells@redhat.com) .\" .\" This program is free software; you can redistribute it and/or .\" modify it under the terms of the GNU General Public License .\" as published by the Free Software Foundation; either version .\" 2 of the License, or (at your option) any later version. .\" .TH REQUEST-KEY 8 "15 Nov 2011" Linux "Linux Key Management Utilities" .SH NAME request\-key \- handle key instantiation callback requests from the kernel .SH SYNOPSIS \fB/sbin/request\-key \fR [] .SH DESCRIPTION This program is invoked by the kernel when the kernel is asked for a key that it doesn't have immediately available. The kernel creates a partially set up key and then calls out to this program to instantiate it. It is not intended to be called directly. .PP However, for debugging purposes, it can be given some options on the command line: .IP \fB-d\fP Turn on debugging mode. In this mode, no attempts are made to access any keys and, if a handler program is selected, it won't be executed; instead, this program will print a message and exit 0. .IP \fB-D \fP In debugging mode, use the proposed key description specified with this rather than the sample ("user;0;0;1f0000;debug:1234") built into the program. .IP \fB-l\fP Use configuration from the current directory. The program will use .IR request-key.d/* " and " request-key.conf from the current directory rather than from .IR /etc . .IP \fB-n\fP Don't log to the system log. Ordinarily, error messages and debugging messages will be copied to the system log - this will prevent that. .IP \fB-v\fP Turn on debugging output. This may be specified multiple times to produce increasing levels of verbosity. .IP \fB--version\fP Print the program version and exit. .SH ERRORS All errors will be logged to the syslog. .SH FILES .ul /etc/request\-key.d/*.conf .ul 0 Individual configuration files. .P .ul /etc/request\-key.conf .ul 0 Fallback configuration file. .SH SEE ALSO .ad l .nh .BR keyctl (1), .BR request\-key.conf (5), .BR keyrings (7) keyutils-1.6.3/man/request-key.conf.5000066400000000000000000000106611370111642500174410ustar00rootroot00000000000000.\" -*- nroff -*- .\" Copyright (C) 2005 Red Hat, Inc. All Rights Reserved. .\" Written by David Howells (dhowells@redhat.com) .\" .\" This program is free software; you can redistribute it and/or .\" modify it under the terms of the GNU General Public License .\" as published by the Free Software Foundation; either version .\" 2 of the License, or (at your option) any later version. .\" .TH REQUEST-KEY.CONF 5 "15 November 2011" Linux "Linux Key Management Utilities" .SH NAME request\-key.conf \- Instantiation handler configuration file .SH DESCRIPTION .P These files are used by the /sbin/request\-key program to determine which program it should run to instantiate a key. .P request\-key looks for the best match, reading all the following files: .IP /etc/request\-key.d/*.conf .br /etc/request\-key.conf .P If it doesn't find a match, it will return an error and the kernel will automatically negate the key. .P The best match is defined as the line with the shortest wildcard skips, ranking the columns in order left to right. If two lines have the same length skips, then the first read is the one taken. .P In the files, any blank line or line beginning with a hash mark '#' is considered to be a comment and ignored. .P All other lines are assumed to be command lines with a number of white space separated fields: .P ... .P The first four fields are used to match the parameters passed to request\-key by the kernel. \fIop\fR is the operation type; currently the only supported operation is "create". .P \fItype\fR, \fIdescription\fR and \fIcallout\-info\fR match the three parameters passed to \fBkeyctl request2\fR or the \fBrequest_key()\fR system call. Each of these may contain one asterisk '*' character as a wildcard anywhere within the string. .P Should a match be made, the program specified by will be exec'd. This must have a fully qualified path name. argv[0] will be set from the part of the program name that follows the last slash '/' character. .P If the program name is prefixed with a pipe bar character '|', then the program will be forked and exec'd attached to three pipes. The callout information will be piped to it on it's stdin and the intended payload data will be retrieved from its stdout. Anything sent to stderr will be posted in syslog. If the program exits 0, then /sbin/request\-key will attempt to instantiate the key with the data read from stdout. If it fails in any other way, then request\-key will attempt to execute the appropriate 'negate' operation command. .P The program arguments can be substituted with various macros. Only complete argument substitution is supported - macro substitutions can't be embedded. All macros begin with a percent character '%'. An argument beginning with two percent characters will have one of them discarded. .P The following macros are supported: .P .RS %o Operation type .br %k Key ID .br %t Key type .br %d Key description .br %c Callout information .br %u Key UID .br %g Key GID .br %T Requestor's thread keyring .br %P Requestor's process keyring .br %S Requestor's session keyring .RE .P There's another macro substitution too that permits the interpolation of the contents of a key: .P .RS %{:} .RE .P This performs a lookup for a key of the given type and description on the requestor's keyrings, and if found, substitutes the contents for the macro. If not found an error will be logged and the key under construction will be negated. .SH EXAMPLE .P A basic file will be installed in the /etc. This will contain two debugging lines that can be used to test the installation: .P .RS create user debug:* negate /bin/keyctl negate %k 30 %S .br create user debug:loop:* * |/bin/cat .br create user debug:* * /usr/share/keyutils/request\-key\-debug.sh %k %d %c %S .br negate * * * /bin/keyctl negate %k 30 %S .RE .P This is set up so that something like: .P .RS keyctl request2 user debug:xxxx negate .RE .P will create a negative user-defined key, something like: .P .RS keyctl request2 user debug:yyyy spoon .RE .P will create an instantiated user-defined key with "Debug spoon" as the payload, and something like: .P .RS keyctl request2 user debug:loop:zzzz abcdefghijkl .RE .P will create an instantiated user-defined key with the callout information as the payload. .SH FILES .ul /etc/request\-key.conf .ul 0 .br .ul /etc/request\-key.d/*.conf .ul 0 .SH SEE ALSO \fBkeyctl\fR(1), \fBrequest\-key.conf\fR(5) keyutils-1.6.3/request-key-debug.sh000077500000000000000000000016121370111642500172730ustar00rootroot00000000000000#!/bin/sh ############################################################################### # # Copyright (C) 2005 Red Hat, Inc. All Rights Reserved. # Written by David Howells (dhowells@redhat.com) # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License # as published by the Free Software Foundation; either version # 2 of the License, or (at your option) any later version. # ############################################################################### # # Request key debugging # # Call: request-key-debug.sh # echo RQDebug keyid: $1 echo RQDebug desc: $2 echo RQDebug callout: $3 echo RQDebug session keyring: $4 if [ "$3" != "neg" ] then keyctl instantiate $1 "Debug $3" $4 || exit 1 else cat /proc/keys echo keyctl negate $1 30 $4 keyctl negate $1 30 $4 fi exit 0 keyutils-1.6.3/request-key.c000066400000000000000000000515551370111642500160270ustar00rootroot00000000000000/* request-key.c: hand a key request off to the appropriate process * * Copyright (C) 2005 Red Hat, Inc. All Rights Reserved. * Written by David Howells (dhowells@redhat.com) * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version * 2 of the License, or (at your option) any later version. * * /sbin/request-key [] * * Searches the specified session ring for a key indicating the command to run: * type: "user" * desc: "request-key:" * data: command name, e.g.: "/home/dhowells/request-key-create.sh" */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "keyutils.h" struct parameters { key_serial_t key_id; char *op; char *key_type; char *key_desc; char *callout_info; char *key; char *uid; char *gid; char *thread_keyring; char *process_keyring; char *session_keyring; int len; int oplen; int ktlen; int kdlen; int cilen; }; static int verbosity; static int xlocaldirs; static int xnolog; static int debug_mode; static char conffile[PATH_MAX + 1]; static int confline; static int norecurse; static char cmd[4096 + 2], cmd_conffile[PATH_MAX + 1]; static unsigned int cmd_wildness[4] = { UINT_MAX, UINT_MAX, UINT_MAX, UINT_MAX }; static int cmd_len, cmd_confline; static void lookup_action(struct parameters *params) __attribute__((noreturn)); static void scan_conf_dir(struct parameters *params, const char *confdir); static void scan_conf_file(struct parameters *params, int dirfd, const char *conffile); static void execute_program(struct parameters *params, char *cmdline) __attribute__((noreturn)); static void pipe_to_program(struct parameters *params, char *prog, char **argv) __attribute__((noreturn)); static int match(const char *pattern, int plen, const char *datum, int dlen, unsigned int *wildness); static void debug(const char *fmt, ...) __attribute__((format(printf, 1, 2))); static void debug(const char *fmt, ...) { va_list va; if (verbosity) { va_start(va, fmt); vfprintf(stderr, fmt, va); va_end(va); if (!xnolog) { openlog("request-key", 0, LOG_AUTHPRIV); va_start(va, fmt); vsyslog(LOG_DEBUG, fmt, va); va_end(va); closelog(); } } } static void error(const char *fmt, ...) __attribute__((noreturn, format(printf, 1, 2))); static void error(const char *fmt, ...) { va_list va; if (verbosity) { va_start(va, fmt); vfprintf(stderr, fmt, va); va_end(va); } if (!xnolog) { openlog("request-key", 0, LOG_AUTHPRIV); va_start(va, fmt); vsyslog(LOG_ERR, fmt, va); va_end(va); closelog(); } exit(1); } #define file_error(FMT, ...) error("%s: "FMT, conffile, ## __VA_ARGS__) #define line_error(FMT, ...) error("%s:%d: "FMT, conffile, confline, ## __VA_ARGS__) static void oops(int x) { error("Died on signal %d", x); } /*****************************************************************************/ /* * */ int main(int argc, char *argv[]) { struct parameters params; char *test_desc = "user;0;0;1f0000;debug:1234"; char *buf; int ret, ntype, dpos, n, fd, opt; if (argc == 2 && strcmp(argv[1], "--version") == 0) { printf("request-key from %s (Built %s)\n", keyutils_version_string, keyutils_build_string); return 0; } signal(SIGSEGV, oops); signal(SIGBUS, oops); signal(SIGPIPE, SIG_IGN); while (opt = getopt(argc, argv, "D:dlnv"), opt != -1) { switch (opt) { case 'D': test_desc = optarg; break; case 'd': debug_mode = 1; break; case 'l': xlocaldirs = 1; break; case 'n': xnolog = 1; break; case 'v': verbosity++; break; } } argc -= optind; argv += optind; if (argc != 7 && argc != 8) error("Unexpected argument count: %d\n", argc); fd = open("/dev/null", O_RDWR); if (fd < 0) error("open"); if (fd > 2) { close(fd); } else if (fd < 2) { ret = dup(fd); if (ret < 0) error("dup failed: %m\n"); if (ret < 2 && dup(fd) < 0) error("dup failed: %m\n"); } params.op = argv[0]; params.key = argv[1]; params.uid = argv[2]; params.gid = argv[3]; params.thread_keyring = argv[4]; params.process_keyring = argv[5]; params.session_keyring = argv[6]; params.callout_info = argv[7]; params.key_id = atoi(params.key); /* assume authority over the key * - older kernel doesn't support this function */ if (!debug_mode) { ret = keyctl_assume_authority(params.key_id); if (ret < 0 && !(argc == 8 || errno == EOPNOTSUPP)) error("Failed to assume authority over key %d (%m)\n", params.key_id); } /* ask the kernel to describe the key to us */ if (!debug_mode) { ret = keyctl_describe_alloc(params.key_id, &buf); if (ret < 0) goto inaccessible; } else { buf = strdup(test_desc); } /* extract the type and description from the key */ debug("Key descriptor: \"%s\"\n", buf); ntype = -1; dpos = -1; n = sscanf(buf, "%*[^;]%n;%*d;%*d;%x;%n", &ntype, &n, &dpos); if (n != 1) error("Failed to parse key description\n"); params.key_type = buf; params.key_type[ntype] = 0; params.key_desc = buf + dpos; debug("Key type: %s\n", params.key_type); debug("Key desc: %s\n", params.key_desc); /* get hold of the callout info */ if (!params.callout_info) { void *tmp; if (keyctl_read_alloc(KEY_SPEC_REQKEY_AUTH_KEY, &tmp) < 0) error("Failed to retrieve callout info (%m)\n"); params.callout_info = tmp; } debug("CALLOUT: '%s'\n", params.callout_info); /* determine the action to perform */ params.oplen = strlen(params.op); params.ktlen = strlen(params.key_type); params.kdlen = strlen(params.key_desc); params.cilen = strlen(params.callout_info); lookup_action(¶ms); inaccessible: error("Key %d is inaccessible (%m)\n", params.key_id); } /* end main() */ /*****************************************************************************/ /* * determine the action to perform */ static void lookup_action(struct parameters *params) { if (!xlocaldirs) { scan_conf_dir(params, "/etc/request-key.d"); scan_conf_file(params, AT_FDCWD, "/etc/request-key.conf"); } else { scan_conf_dir(params, "request-key.d"); scan_conf_file(params, AT_FDCWD, "request-key.conf"); } if (cmd_len > 0) execute_program(params, cmd); file_error("No matching action\n"); } /*****************************************************************************/ /* * Scan the files in a configuration directory. */ static void scan_conf_dir(struct parameters *params, const char *confdir) { struct dirent *d; DIR *dir; int l; debug("__ SCAN %s __\n", confdir); dir = opendir(confdir); if (!dir) { if (errno == ENOENT) return; error("Cannot open %s: %m\n", confdir); } while ((d = readdir(dir))) { if (d->d_name[0] == '.') continue; if (d->d_type != DT_UNKNOWN && d->d_type != DT_REG) continue; l = strlen(d->d_name); if (l < 5) continue; if (memcmp(d->d_name + l - 5, ".conf", 5) != 0) continue; scan_conf_file(params, dirfd(dir), d->d_name); } closedir(dir); } /*****************************************************************************/ /* * Scan the contents of a configuration file. */ static void scan_conf_file(struct parameters *params, int dirfd, const char *conffile) { char buf[4096 + 2], *p, *q; FILE *conf; int fd; debug("__ read %s __\n", conffile); fd = openat(dirfd, conffile, O_RDONLY); if (fd < 0) { if (errno == ENOENT) return; error("Cannot open %s: %m\n", conffile); } conf = fdopen(fd, "r"); if (!conf) error("Cannot open %s: %m\n", conffile); for (confline = 1;; confline++) { unsigned int wildness[4] = {}; unsigned int len; /* read the file line-by-line */ if (!fgets(buf, sizeof(buf), conf)) { if (feof(conf)) break; file_error("error %m\n"); } len = strlen(buf); if (len >= sizeof(buf) - 2) line_error("Line too long\n"); /* ignore blank lines and comments */ if (len == 1 || buf[0] == '#' || isspace(buf[0])) continue; buf[--len] = 0; p = buf; /* attempt to match the op */ q = p; while (*p && !isspace(*p)) p++; if (!*p) goto syntax_error; *p = 0; if (!match(q, p - q, params->op, params->oplen, &wildness[0])) continue; p++; /* attempt to match the type */ while (isspace(*p)) p++; if (!*p) goto syntax_error; q = p; while (*p && !isspace(*p)) p++; if (!*p) goto syntax_error; *p = 0; if (!match(q, p - q, params->key_type, params->ktlen, &wildness[1])) continue; p++; /* attempt to match the description */ while (isspace(*p)) p++; if (!*p) goto syntax_error; q = p; while (*p && !isspace(*p)) p++; if (!*p) goto syntax_error; *p = 0; if (!match(q, p - q, params->key_desc, params->kdlen, &wildness[2])) continue; p++; /* attempt to match the callout info */ while (isspace(*p)) p++; if (!*p) goto syntax_error; q = p; while (*p && !isspace(*p)) p++; if (!*p) goto syntax_error; *p = 0; if (!match(q, p - q, params->callout_info, params->cilen, &wildness[3])) continue; p++; /* we've got a match */ while (isspace(*p)) p++; if (!*p) goto syntax_error; debug("%s:%d: Line matches '%s' (%u,%u,%u,%u)\n", conffile, confline, p, wildness[0], wildness[1], wildness[2], wildness[3]); if (wildness[0] < cmd_wildness[0] || (wildness[0] == cmd_wildness[0] && wildness[1] < cmd_wildness[1]) || (wildness[0] == cmd_wildness[0] && wildness[1] == cmd_wildness[1] && wildness[2] < cmd_wildness[2]) || (wildness[0] == cmd_wildness[0] && wildness[1] == cmd_wildness[1] && wildness[2] == cmd_wildness[2] && wildness[3] < cmd_wildness[3]) ) { memcpy(cmd_wildness, wildness, sizeof(cmd_wildness)); cmd_len = len - (p - buf); cmd_confline = confline; debug("%s:%d: Prefer command (%u,%u,%u,%u)\n", conffile, confline, wildness[0], wildness[1], wildness[2], wildness[3]); memcpy(cmd, p, cmd_len + 1); strcpy(cmd_conffile, conffile); } } fclose(conf); return; syntax_error: line_error("Syntax error\n"); } /*****************************************************************************/ /* * attempt to match a datum to a pattern * - one asterisk is allowed anywhere in the pattern to indicate a wildcard * - returns true if matched, false if not * - adds the total number of chars skipped by wildcard to *_wildness */ static int match(const char *pattern, int plen, const char *datum, int dlen, unsigned int *_wildness) { const char *asterisk; int n; if (verbosity >= 2) debug("match(%*.*s,%*.*s)", plen, plen, pattern, dlen, dlen, datum); asterisk = memchr(pattern, '*', plen); if (!asterisk) { /* exact match only if no wildcard */ if (plen == dlen && memcmp(pattern, datum, dlen) == 0) goto yes; goto no; } /* the datum mustn't be shorter than the pattern without the asterisk */ if (dlen < plen - 1) goto no; n = asterisk - pattern; if (n == 0) { /* wildcard at beginning of pattern */ pattern++; if (!*pattern) goto yes_wildcard; /* "*" matches everything */ /* match the end of the datum */ if (memcmp(pattern, datum + (dlen - (plen - 1)), plen - 1) == 0) goto yes_wildcard; goto no; } /* need to match beginning of datum for "abc*" and "abc*def" */ if (memcmp(pattern, datum, n) != 0) goto no; if (!asterisk[1]) goto yes_wildcard; /* "abc*" matches */ /* match the end of the datum */ asterisk++; n = plen - n - 1; if (memcmp(pattern, datum + (dlen - n), n) == 0) goto yes_wildcard; no: if (verbosity >= 2) debug(" = no\n"); return 0; yes: if (verbosity >= 2) debug(" = yes (w=0)\n"); return 1; yes_wildcard: *_wildness += dlen - (plen - 1); if (verbosity >= 2) debug(" = yes (w=%u)\n", dlen - (plen - 1)); return 1; } /* end match() */ /*****************************************************************************/ /* * execute a program to deal with a key */ static void execute_program(struct parameters *params, char *cmdline) { char *argv[256]; char *prog, *p, *q; int argc, pipeit; debug("execute_program('%s','%s')\n", params->callout_info, cmdline); /* if the commandline begins with a bar, then we pipe the callout data into it and read * back the payload data */ pipeit = 0; if (cmdline[0] == '|') { pipeit = 1; cmdline++; } /* extract the path to the program to run */ prog = p = cmdline; while (*p && !isspace(*p)) p++; // if (!*p) // line_error("No command path\n"); // *p++ = 0; if (*p) *p++ = 0; argv[0] = strrchr(prog, '/') + 1; /* extract the arguments */ for (argc = 1; p; argc++) { while (isspace(*p)) p++; if (!*p) break; if (argc >= 254) line_error("Too many arguments\n"); argv[argc] = q = p; while (*p && !isspace(*p)) p++; if (*p) *p++ = 0; else p = NULL; debug("argv[%d]: '%s'\n", argc, argv[argc]); if (*q != '%') continue; /* it's a macro */ q++; if (!*q) line_error("Missing macro name\n"); if (*q == '%') { /* it's actually an anti-macro escape "%%..." -> "%..." */ argv[argc]++; continue; } /* single character macros */ if (!q[1]) { switch (*q) { case 'o': argv[argc] = params->op; continue; case 'k': argv[argc] = params->key; continue; case 't': argv[argc] = params->key_type; continue; case 'd': argv[argc] = params->key_desc; continue; case 'c': argv[argc] = params->callout_info; continue; case 'u': argv[argc] = params->uid; continue; case 'g': argv[argc] = params->gid; continue; case 'T': argv[argc] = params->thread_keyring; continue; case 'P': argv[argc] = params->process_keyring; continue; case 'S': argv[argc] = params->session_keyring; continue; default: line_error("Unsupported macro\n"); } } /* keysub macro */ if (*q == '{') { key_serial_t keysub; void *tmp; char *ksdesc, *end, *subdata; int ret, loop; /* extract type and description */ q++; ksdesc = strchr(q, ':'); if (!ksdesc) line_error("Keysub macro lacks ':'\n"); *ksdesc++ = 0; end = strchr(ksdesc, '}'); if (!end) line_error("Unterminated keysub macro\n"); *end++ = 0; if (*end) line_error("Keysub macro has trailing rubbish\n"); debug("Keysub: %s key \"%s\"\n", q, ksdesc); if (!q[0]) line_error("Keysub type empty\n"); if (!ksdesc[0]) line_error("Keysub description empty\n"); /* look up the key in the requestor's keyrings, but fail immediately if the * key is not found rather than invoking /sbin/request-key again */ keysub = request_key(q, ksdesc, NULL, 0); if (keysub < 0) line_error("Keysub key not found: %m\n"); ret = keyctl_read_alloc(keysub, &tmp); if (ret < 0) line_error("Can't read keysub %d data: %m\n", keysub); subdata = tmp; for (loop = 0; loop < ret; loop++) if (!isprint(subdata[loop])) error("keysub %d data not printable ('%02hhx')\n", keysub, subdata[loop]); argv[argc] = subdata; continue; } } if (argc == 0) line_error("No arguments\n"); argv[argc] = NULL; if (verbosity) { char **ap; debug("%s %s\n", pipeit ? "PipeThru" : "Run", prog); for (ap = argv; *ap; ap++) debug("- argv[%td] = \"%s\"\n", ap - argv, *ap); } /* become the same UID/GID as the key requesting process */ //setgid(atoi(xuid)); //setuid(atoi(xgid)); /* if the last argument is a single bar, we spawn off the program dangling on the end of * three pipes and read the key material from the program, otherwise we just exec */ if (debug_mode) { printf("-- exec disabled --\n"); exit(0); } if (pipeit) pipe_to_program(params, prog, argv); /* attempt to execute the command */ execv(prog, argv); line_error("Failed to execute '%s': %m\n", prog); } /* end execute_program() */ /*****************************************************************************/ /* * pipe the callout information to the specified program and retrieve the * payload data over another pipe */ static void pipe_to_program(struct parameters *params, char *prog, char **argv) { char errbuf[512], payload[32768 + 1], *pp, *pc, *pe; int ipi[2], opi[2], epi[2], childpid; int ifl, ofl, efl, npay, ninfo, espace, tmp; debug("pipe_to_program(%s -> %s)", params->callout_info, prog); if (pipe(ipi) < 0 || pipe(opi) < 0 || pipe(epi) < 0) error("pipe failed: %m"); childpid = fork(); if (childpid == -1) error("fork failed: %m"); if (childpid == 0) { /* child process */ if (dup2(ipi[0], 0) < 0 || dup2(opi[1], 1) < 0 || dup2(epi[1], 2) < 0) error("dup2 failed: %m"); close(ipi[0]); close(ipi[1]); close(opi[0]); close(opi[1]); close(epi[0]); close(epi[1]); execv(prog, argv); line_error("Failed to execute '%s': %m\n", prog); } /* parent process */ close(ipi[0]); close(opi[1]); close(epi[1]); #define TOSTDIN ipi[1] #define FROMSTDOUT opi[0] #define FROMSTDERR epi[0] ifl = fcntl(TOSTDIN, F_GETFL); ofl = fcntl(FROMSTDOUT, F_GETFL); efl = fcntl(FROMSTDERR, F_GETFL); if (ifl < 0 || ofl < 0 || efl < 0) error("fcntl/F_GETFL failed: %m"); ifl |= O_NONBLOCK; ofl |= O_NONBLOCK; efl |= O_NONBLOCK; if (fcntl(TOSTDIN, F_SETFL, ifl) < 0 || fcntl(FROMSTDOUT, F_SETFL, ofl) < 0 || fcntl(FROMSTDERR, F_SETFL, efl) < 0) error("fcntl/F_SETFL failed: %m"); ninfo = params->cilen; pc = params->callout_info; npay = sizeof(payload); pp = payload; espace = sizeof(errbuf); pe = errbuf; do { fd_set rfds, wfds; FD_ZERO(&rfds); FD_ZERO(&wfds); if (TOSTDIN != -1) { if (ninfo > 0) { FD_SET(TOSTDIN, &wfds); } else { close(TOSTDIN); TOSTDIN = -1; continue; } } if (FROMSTDOUT != -1) FD_SET(FROMSTDOUT, &rfds); if (FROMSTDERR != -1) FD_SET(FROMSTDERR, &rfds); tmp = TOSTDIN > FROMSTDOUT ? TOSTDIN : FROMSTDOUT; tmp = tmp > FROMSTDERR ? tmp : FROMSTDERR; tmp++; debug("select r=%d,%d w=%d m=%d\n", FROMSTDOUT, FROMSTDERR, TOSTDIN, tmp); tmp = select(tmp, &rfds, &wfds, NULL, NULL); if (tmp < 0) error("select failed: %m\n"); if (TOSTDIN != -1 && FD_ISSET(TOSTDIN, &wfds)) { tmp = write(TOSTDIN, pc, ninfo); if (tmp < 0) { if (errno != EPIPE) error("write failed: %m\n"); debug("EPIPE"); ninfo = 0; } else { debug("wrote %d\n", tmp); pc += tmp; ninfo -= tmp; } } if (FROMSTDOUT != -1 && FD_ISSET(FROMSTDOUT, &rfds)) { tmp = read(FROMSTDOUT, pp, npay); if (tmp < 0) error("read failed: %m\n"); debug("read %d\n", tmp); if (tmp == 0) { close(FROMSTDOUT); FROMSTDOUT = -1; } else { pp += tmp; npay -= tmp; if (npay == 0) error("Too much data read from query program\n"); } } if (FROMSTDERR != -1 && FD_ISSET(FROMSTDERR, &rfds)) { char *nl; tmp = read(FROMSTDERR, pe, espace); if (tmp < 0) error("read failed: %m\n"); debug("read err %d\n", tmp); if (tmp == 0) { close(FROMSTDERR); FROMSTDERR = -1; continue; } pe += tmp; espace -= tmp; while ((nl = memchr(errbuf, '\n', pe - errbuf))) { int n, rest; nl++; n = nl - errbuf; if (verbosity) fprintf(stderr, "Child: %*.*s", n, n, errbuf); if (!xnolog) { openlog("request-key", 0, LOG_AUTHPRIV); syslog(LOG_ERR, "Child: %*.*s", n, n, errbuf); closelog(); } rest = pe - nl; if (rest > 0) { memmove(errbuf, nl, rest); pe -= n; espace += n; } else { pe = errbuf; espace = sizeof(errbuf); } } if (espace == 0) { int n = sizeof(errbuf); if (verbosity) fprintf(stderr, "Child: %*.*s", n, n, errbuf); if (!xnolog) { openlog("request-key", 0, LOG_AUTHPRIV); syslog(LOG_ERR, "Child: %*.*s", n, n, errbuf); closelog(); } pe = errbuf; espace = sizeof(errbuf); } } } while (TOSTDIN != -1 || FROMSTDOUT != -1 || FROMSTDERR != -1); /* wait for the program to exit */ if (waitpid(childpid, &tmp, 0) != childpid) error("wait for child failed: %m\n"); /* if the process exited non-zero or died on a signal, then we call back in to ourself to * decide on negation * - this is not exactly beautiful but the quickest way of having configurable negation * settings */ if (WIFEXITED(tmp) && WEXITSTATUS(tmp) != 0) { if (norecurse) error("child exited %d\n", WEXITSTATUS(tmp)); norecurse = 1; debug("child exited %d\n", WEXITSTATUS(tmp)); params->op = "negate"; lookup_action(params); } if (WIFSIGNALED(tmp)) { if (norecurse) error("child died on signal %d\n", WTERMSIG(tmp)); norecurse = 1; params->op = "negate"; lookup_action(params); } /* attempt to instantiate the key */ debug("instantiate with %td bytes\n", pp - payload); if (keyctl_instantiate(params->key_id, payload, pp - payload, 0) < 0) error("instantiate key failed: %m\n"); debug("instantiation successful\n"); exit(0); } /* end pipe_to_program() */ keyutils-1.6.3/request-key.conf000066400000000000000000000033731370111642500165250ustar00rootroot00000000000000############################################################################### # # Copyright (C) 2005 Red Hat, Inc. All Rights Reserved. # Written by David Howells (dhowells@redhat.com) # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License # as published by the Free Software Foundation; either version # 2 of the License, or (at your option) any later version. # ############################################################################### ############################################################################### # # We can run programs or scripts # - Macro substitutions in arguments: # %%... %... # %o operation name # %k ID of key being operated upon # %t type of key being operated upon # %d description of key being operated upon # %c callout info # %u UID of requestor # %g GID of requestor # %T thread keyring of requestor (may be 0) # %P process keyring of requestor (may be 0) # %S session keyring of requestor (may be the user's default session) # ################################################################################ #OP TYPE DESCRIPTION CALLOUT INFO PROGRAM ARG1 ARG2 ARG3 ... #====== ======= =============== =============== =============================== create dns_resolver * * /sbin/key.dns_resolver %k create user debug:* negate /bin/keyctl negate %k 30 %S create user debug:* rejected /bin/keyctl reject %k 30 %c %S create user debug:* expired /bin/keyctl reject %k 30 %c %S create user debug:* revoked /bin/keyctl reject %k 30 %c %S create user debug:loop:* * |/bin/cat create user debug:* * /usr/share/keyutils/request-key-debug.sh %k %d %c %S negate * * * /bin/keyctl negate %k 30 %S keyutils-1.6.3/tests/000077500000000000000000000000001370111642500145345ustar00rootroot00000000000000keyutils-1.6.3/tests/Makefile000066400000000000000000000050751370111642500162030ustar00rootroot00000000000000# Copyright (c) 2015 Red Hat, Inc. All rights reserved. This copyrighted material # is made available to anyone wishing to use, modify, copy, or # redistribute it subject to the terms and conditions of the GNU General # Public License v.2. # # This program is distributed in the hope that it will be useful, but WITHOUT ANY # WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. See the GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. # # Author: David Howells # Updated to new Make model by Bill Peck # The toplevel namespace within which the test lives. TOPLEVEL_NAMESPACE=/kernel # The name of the package under test: PACKAGE_NAME=keyutils # The path of the test below the package: RELATIVE_PATH=testsuite # Version of the Test. Used with make tag. export TESTVERSION=1.3 # The combined namespace of the test. export TEST=$(TOPLEVEL_NAMESPACE)/$(PACKAGE_NAME)/$(RELATIVE_PATH) .PHONY: all install download clean TESTS = $(shell /usr/bin/find . -name runtest.sh | \ /bin/sed -e 's/runtest.sh//g;s/^\.\///;s/\/$$//') BUILT_FILES= FILES=$(METADATA) *.sh Makefile PURPOSE bugzillas keyctl run: $(FILES) build bash runtest.sh $(TESTS) build: $(BUILT_FILES) clean: rm -f *~ *.rpm $(BUILT_FILES) find * -name test.out -delete # You may need to add other targets e.g. to build executables from source code # Add them here: # Include Common Makefile ifneq ($(wildcard /usr/share/rhts/lib/rhts-make.include),) include /usr/share/rhts/lib/rhts-make.include # Generate the testinfo.desc here: $(METADATA): Makefile @touch $(METADATA) @echo "Owner: David Howells " > $(METADATA) @echo "Name: $(TEST)" >> $(METADATA) @echo "Path: $(TEST_DIR)" >> $(METADATA) @echo "License: Unknown" >> $(METADATA) @echo "TestVersion: $(TESTVERSION)" >> $(METADATA) @echo "Description: testsuite to verify keyutils ">> $(METADATA) @echo "TestTime: 30m" >> $(METADATA) @echo "RunFor: $(PACKAGE_NAME)" >> $(METADATA) @echo "Requires: $(PACKAGE_NAME)" >> $(METADATA) @echo "Requires: redhat-lsb-core" >> $(METADATA) @echo "Releases: -RHEL2.1 -RHEL3" >> $(METADATA) @echo "Type: Tier1" >> $(METADATA) @echo "Type: KernelTier1" >> $(METADATA) @echo "Destructive: no" >> $(METADATA) rhts-lint $(METADATA) endif keyutils-1.6.3/tests/PURPOSE000066400000000000000000000100341370111642500156120ustar00rootroot00000000000000The purpose of this testsuite is to do negative and positive testing against the keyutils package. Sub Test Description ------------------ ----------------------------------------------------- /listing/noargs Check list/rlist subcommands fail with the wrong number of arguments /listing/bad-args Check list/rlist subcommands fail with bad arguments /listing/valid Check list/rlist subcommands work /show/noargs Check show subcommand works with no arguments /reading/noargs Check read/pipe/print subcommands fail with the wrong number of arguments /reading/bad-args Check read/pipe/print subcommands fail with bad arguments /reading/valid Check read/pipe/print subcommands work /pupdate/noargs Check pupdate subcommand fails with the wrong number of arguments /pupdate/bad-args Check pupdate subcommand fails with bad arguments /pupdate/userupdate Check pupdate subcommand works for user defined keys /newring/noargs Check newring subcommand fails with the wrong number of arguments /newring/bad-args Check newring subcommand fails with a bad arguments /newring/valid Check newring subcommand works /session/bad-args Check session subcommand fails with bad arguments /session/valid Check session subcommand works /clear/noargs Check clear subcommand fails with the wrong number of arguments /clear/bad-args Check clear subcommand fails with a bad arguments /clear/valid Check clear subcommand works /instantiating/noargs Check instantiate/negate subcommands fail with the wrong number of arguments /instantiating/bad-args Check instantiate/negate subcommands fail with bad arguments /permitting/noargs Check chown/chgrp/setperm subcommands fail with the wrong number of arguments /permitting/bad-args Check chown/chgrp/setperm subcommands fail with bad arguments /permitting/valid Check chown/chgrp/setperm subcommands work /describing/noargs Check describe/rdescribe subcommands fail with the wrong number of arguments /describing/bad-args Check describe/rdescribe subcommands fail with bad arguments /describing/valid Check describe/rdescribe subcommands work /noargs Check keyutils with no args gives format list /revoke/noargs Check revoke subcommand fails with the wrong number of arguments /revoke/bad-args Check revoke subcommand fails with a bad arguments /revoke/valid Check revoke subcommand works /padd/noargs Check padd subcommand fails with the wrong number of arguments /padd/bad-args Check padd subcommand fails with bad arguments /padd/useradd Check padd subcommand works /timeout/noargs Check timeout subcommand fails with the wrong number of arguments /timeout/bad-args Check timeout subcommand fails with a bad arguments /timeout/valid Check timeout subcommand works /update/noargs Check update subcommand fails with the wrong number of arguments /update/bad-args Check update subcommand fails with bad arguments /update/userupdate Check update subcommand works for user defined keys /search/noargs Check search subcommand fails with the wrong number of arguments /search/bad-args Check search subcommand fails with a bad arguments /search/valid Check search subcommand works /link/recursion Check link subcommand handles recursive links correctly /link/noargs Check link subcommand fails with the wrong number of arguments /link/bad-args Check link subcommand fails with bad arguments /link/valid Check link subcommand works /add/noargs Check add subcommand fails with the wrong number of arguments /add/bad-args Check add subcommand fails with a bad arguments /add/useradd Check add subcommand works /requesting/piped Check request/prequest2 subcommands work /requesting/noargs Check request/request2 subcommands fail with the wrong number of arguments /requesting/bad-args Check request/request2 subcommands fail with bad arguments /requesting/valid Check request/request2 subcommands work /unlink/noargs Check unlink subcommand fails with the wrong number of arguments /unlink/bad-args Check unlink subcommand fails with a bad arguments /unlink/valid Check unlink subcommand works keyutils-1.6.3/tests/bugzillas/000077500000000000000000000000001370111642500165305ustar00rootroot00000000000000keyutils-1.6.3/tests/bugzillas/bz1031154/000077500000000000000000000000001370111642500177025ustar00rootroot00000000000000keyutils-1.6.3/tests/bugzillas/bz1031154/runtest.sh000066400000000000000000000046741370111642500217550ustar00rootroot00000000000000#!/bin/bash # Test for https://bugzilla.redhat.com/show_bug.cgi?id=1031154 . ../../prepare.inc.sh . ../../toolbox.inc.sh # We intentionally generate AVCs so the test system shouldn't fail us # because the AVCs were generated. export AVC_ERROR=+no_avc_check export RHTS_OPTION_STRONGER_AVC= # ---- do the actual testing ---- result=PASS if [ $have_big_key_type = 0 ] then toolbox_skip_test $TEST "SKIPPING TEST DUE TO LACK OF BIG_KEY TYPE" exit 0 fi require_selinux require_command getenforce require_command setenforce require_command runcon require_command ausearch echo "++++ BEGINNING TEST" >$OUTPUTFILE # we need a reference time to scan the audit log from so as not to pick up old # results from this test. base_date=`date +"%x@%X"` base_time=${base_date#*@} base_date=${base_date%@*} sleep 1 # reset the permissive audit log autocancel thing load_policy # we need to be in permissive mode marker "ENTER SELINUX PERMISSIVE MODE" mode=`getenforce` if [ "$mode" != "Permissive" ] then echo setenforce Permissive >>$OUTPUTFILE if ! setenforce Permissive then failed fi fi # create a big key to probe marker "CREATE BIG KEY" pcreate_key_by_size --new=id 8192 big_key test-key @s # check the big key is file backed and the right size marker "CHECK BIG KEY" xid=`printf %08x $id` pk=`cat /proc/keys | grep "^$xid.*test-key: 8192 \\[file\\]"` echo $pk >>$OUTPUTFILE if [ -z "$pk" ] then echo "+++ Incorrectly created key" >>$OUTPUTFILE cat /proc/keys | grep "^$xid" >>$OUTPUTFILE failed fi # use a separate context to access the key marker "ACCESS INTERCONTEXT" echo runcon system_u:system_r:httpd_t:s0-s0:c0.c1023 keyctl print $id >>$OUTPUTFILE if ! runcon system_u:system_r:httpd_t:s0-s0:c0.c1023 keyctl print $id >/dev/null 2>>$OUTPUTFILE then failed fi # examine the audit logs marker "EXAMINE AUDIT LOGS" echo ausearch -m AVC -i --subject httpd_t -ts $base_date $base_time \| audit2allow \| grep '-P "allow httpd_t user_tmpfs_t:file [{] (open |read )+[}];"' >>$OUTPUTFILE if ausearch -m AVC -i --subject httpd_t -ts $base_date $base_time 2>>$OUTPUTFILE | audit2allow 2>>$OUTPUTFILE | grep -P "allow httpd_t user_tmpfs_t:file [{] (open |read )+[}];" then failed fi marker "RESTORE SELINUX MODE" if [ "$mode" != "Permissive" ] then echo setenforce $mode >>$OUTPUTFILE if ! setenforce $mode then failed fi fi echo "++++ FINISHED TEST: $result" >>$OUTPUTFILE # --- then report the results in the database --- toolbox_report_result $TEST $result keyutils-1.6.3/tests/bugzillas/bz1033467/000077500000000000000000000000001370111642500177135ustar00rootroot00000000000000keyutils-1.6.3/tests/bugzillas/bz1033467/runtest.sh000066400000000000000000000026521370111642500217600ustar00rootroot00000000000000#!/bin/bash # Test for https://bugzilla.redhat.com/show_bug.cgi?id=1033467 . ../../prepare.inc.sh . ../../toolbox.inc.sh # ---- do the actual testing ---- result=PASS echo "++++ BEGINNING TEST" >$OUTPUTFILE # create a keyring and attach it to the session keyring marker "ADD SANDBOX KEYRING" create_keyring --new=sandbox sandbox @s # create a bunch of nested keyrings in the sandbox marker "ADD NESTED KEYRINGS" declare -a ring for ((i=0; i<=16; i++)) do create_keyring --new="ring[$i]" ring$i $sandbox done # create a key in each of those keyrings marker "ADD KEYS" keys="" for ((i=0; i<=16; i++)) do create_key --new=id user a$i a ${ring[$i]} keys="$keys $id" keyid[$i]=$id done # search for the added keys, beginning at sandbox and exercising the nesting marker "SEARCH KEYS" keys2="" for ((i=0; i<=16; i++)) do search_for_key --expect=${keyid[$i]} $sandbox user a$i keys2="$keys2 ${keyid[$i]}" done marker "COMPARE KEY LISTS" if [ "$keys" != "$keys2" ] then echo "Key lists differ" >>$OUTPUTFILE echo List 1: "\"$keys\"" >>$OUTPUTFILE echo List 2: "\"$keys2\"" >>$OUTPUTFILE failed fi # search for some unadded keys and make sure we get an error marker "SEARCH MISSES" for ((i=17; i<=20; i++)) do search_for_key --fail $sandbox user a$i expect_error ENOKEY done echo "++++ FINISHED TEST: $result" >>$OUTPUTFILE # --- then report the results in the database --- toolbox_report_result $TEST $result keyutils-1.6.3/tests/bugzillas/bz1071346/000077500000000000000000000000001370111642500177115ustar00rootroot00000000000000keyutils-1.6.3/tests/bugzillas/bz1071346/runtest.sh000066400000000000000000000042151370111642500217530ustar00rootroot00000000000000#!/bin/bash # Test for https://bugzilla.redhat.com/show_bug.cgi?id=1071346 . ../../prepare.inc.sh . ../../toolbox.inc.sh # ---- do the actual testing ---- result=PASS echo "++++ BEGINNING TEST" >$OUTPUTFILE # create a keyring and attach it to the session keyring marker "ADD SANDBOX KEYRING" create_keyring --new=sandbox sandbox @s # Add a second keyring of the same name into the sandbox marker "ADD SECOND SANDBOX KEYRING" create_keyring --new=second sandbox $sandbox # Now try and link keyrings together in ways that should fail marker "CHECK NO LINK SESSION TO SECOND" link_key --fail @s $second expect_error EDEADLK marker "CHECK NO LINK SANDBOX TO SECOND" link_key --fail $sandbox $second expect_error EDEADLK marker "CHECK NO LINK SECOND TO SECOND" link_key --fail $second $second expect_error EDEADLK # Add another keyring into sandbox and stick a third sandbox keyring in that marker "ADD SIDE KEYRING" create_keyring --new=side side $sandbox marker "ADD THIRD SANDBOX KEYRING" create_keyring --new=third sandbox $side # Make sure we can't link the session keyring, the sandbox, the side # keyring or the third keyring itself into the third keyring. marker "CHECK NO LINK SESSION TO THIRD" link_key --fail @s $third expect_error EDEADLK marker "CHECK NO LINK SANDBOX TO THIRD" link_key --fail $sandbox $third expect_error EDEADLK marker "CHECK NO LINK SIDE TO THIRD" link_key --fail $side $third expect_error EDEADLK marker "CHECK NO LINK THIRD TO THIRD" link_key --fail $sandbox $third expect_error EDEADLK # We should, however, be able to link second to third but not then # third to second marker "CHECK LINK SECOND TO THIRD" link_key $second $third marker "CHECK NO LINK THIRD TO SECOND" link_key --fail $third $second expect_error EDEADLK # We can then detach the link we just made and check the reverse # linkage. marker "UNLINK SECOND FROM THIRD" unlink_key $second $third marker "CHECK LINK THIRD TO SECOND" link_key $third $second marker "CHECK NO LINK SECOND TO THIRD" link_key --fail $second $third expect_error EDEADLK echo "++++ FINISHED TEST: $result" >>$OUTPUTFILE # --- then report the results in the database --- toolbox_report_result $TEST $result keyutils-1.6.3/tests/features/000077500000000000000000000000001370111642500163525ustar00rootroot00000000000000keyutils-1.6.3/tests/features/builtin_trusted/000077500000000000000000000000001370111642500215725ustar00rootroot00000000000000keyutils-1.6.3/tests/features/builtin_trusted/runtest.sh000066400000000000000000000107011370111642500236310ustar00rootroot00000000000000#!/bin/bash . ../../prepare.inc.sh . ../../toolbox.inc.sh # ---- do the actual testing ---- result=PASS echo "++++ BEGINNING TEST" >$OUTPUTFILE if [ $have_public_key = 0 ] then toolbox_skip_test $TEST "SKIPPING DUE TO LACK OF PUBLIC-KEY SUPPORT" exit 0 fi # Find the various trusted keys marker "FIND BUILTIN TRUSTED KEYRINGS" id_key --to=btk %:.builtin_trusted_keys id_key --to=stk %:.secondary_trusted_keys id_key --to=blk %:.blacklist # There should be at least one built-in trusted key for module signing. list_keyring $btk expect_keyring_rlist bkeys if [ `echo $bkeys | wc -w` = 0 ]; then fail; fi # Check we can't add random keys to those keyrings marker "TRY ADDING USER KEYS" create_key --fail user a a $btk expect_error EACCES create_key --fail user a a $stk expect_error EOPNOTSUPP create_key --fail user a a $blk expect_error EACCES # Try adding a key to the keyrings marker "TRY ADDING ASYMMETRIC KEYS" x509=" 308205a6 3082038e a0030201 02020900 ed049e52 489f38b0 300d0609 2a864886 f70d0101 05050030 50310d30 0b060355 040a0c04 504b4353 3111300f 06035504 030c0843 41206b65 79203131 2c302a06 092a8648 86f70d01 0901161d 736c6172 74696261 72746661 7374406d 61677261 74686561 2e683267 32301e17 0d313530 37333031 30313332 345a170d 31353038 32393130 31333234 5a305c31 0d300b06 0355040a 0c04504b 4353311d 301b0603 5504030c 144d6f64 756c6520 7369676e 696e6720 6b657920 31312c30 2a06092a 864886f7 0d010901 161d736c 61727469 62617274 66617374 406d6167 72617468 65612e68 32673230 82022230 0d06092a 864886f7 0d010101 05000382 020f0030 82020a02 82020100 bf29e7cc a69ff57e 665c10ae 0d84b0a7 3cb71fbb d9f7a40d cdaaafb6 34e44db1 44546020 43ae84fb d867638a 2aca75a5 9315efc0 9ad8f736 03f13ede 7c3fcab8 90bcb9ca ddcb7e71 f6fae4b5 6073e1c9 6a877857 b75e4ca2 259a17f5 0021d0be d87eb1d4 cfebeb75 d0e9cbce 30eb3d40 a431a761 aaf0443a 5e896fcf 459516b1 86e10c59 9e8026c0 d4e93686 d97ed7a5 315f1a43 93b40219 6482e471 1fda5f90 17c3bf73 cbc20e5c 5f03570f 336df7be c0d241bd a256fff0 2ce4d0d3 f31c847f a0ae38af a028656e be30f90c e0918cb1 23791733 597cdd42 551b7df6 dc8daf7c ecef601c 63da23ed f589d945 6e6d4d94 3a60c9d4 67f386aa 41615f49 4606be7d 9525a621 45ab1f77 3b1bf842 174b75db ada0c03d b4d5730d 99f80837 cac7ef59 5f7c10c6 d061663a a9293377 edefb9a8 80d65a95 c38a38c2 6973d338 75edc65f 4f968b59 5959fdd9 ac4306b7 69c131c6 dc40dd67 be2234c8 8b30bd20 655dc4f3 f0a9975b 69a0e9b0 da73b7cd fcf7c78e 6b80909b 0b246a57 237d3841 c33704c9 a21d0b6f 4ff60a43 eeca00ec 39f1d4d6 a11c6482 4a7230a3 cdbdebe0 ccc46d22 eaa1b8c8 96fff82c bc38ae82 0dd27672 71762c07 0f0e7866 24fd2f11 c8163d52 ffbb04e6 258dfc7c 885449d0 a39cde9b a231e4a9 c3ae1862 32eebdec 127159ea e61e0f54 e1c66a44 0167a123 8046e709 def7f0b7 f3400247 d879bcb6 c3d4b1cb 02030100 01a37730 75301d06 03551d0e 04160414 cc4e4c77 13b90773 7c54af46 dd576760 374022fa 301f0603 551d2304 18301680 14dee86f 2d22e7b1 213b44c1 43b5671c 73c1b96f 04300c06 03551d13 0101ff04 02300030 0b060355 1d0f0404 03020780 30180603 551d2501 01ff040e 300c060a 2b060104 01920810 0101300d 06092a86 4886f70d 01010505 00038202 0100805f 5fff469e dd0a83d7 1a0a7336 3b34d020 45c616ca 7c3a6cf9 63f03e95 ee9c560c 0bc08812 67e0c927 0aef98e8 695b3f56 67a9197a e8ab87d0 306f2f82 83f38967 3054abd2 56a53ac8 65896d43 37873f18 13d30bd4 483b560e b542103e 424f7afd e7f34c57 e575581a 0d2b8473 448a2e0b e0018743 a4aadc8d f0867a6d 89bcdb54 c2a6b095 f22d59d2 ef72bb3d ee7958d8 dda59b39 1083b2ed 2e8df5f9 36b3d6a8 ee8bf7e4 baa948e1 d1b66ce3 d4c6fab5 f937ed71 54e0ff59 b381ea18 61bfaf1f 340eeffc ea34baad 6016ecbe d8667bb9 90d4bf49 d976c1b4 4c97f4ab 09266a0a 8969d5e0 4c3d121a 4bf7219e 31833790 ef67f897 81d4c3a0 b17dadcd 07f16920 d43cecd3 49fdc209 3b91c014 500fd6dc 850c6018 98d63da6 568db3fb 16c6aa31 c38ce97b 1432a4a1 704eea79 91cbf89b f22997a9 54601b86 2a5dab5e 1a3d3a74 af46adf5 37a975e8 71d06700 74cf545c 13a1b34d 3652fcb2 9ee0e67a 14fd4724 8eb1fdbe 77875f18 729ed58b f713f343 5df1d621 23a3d16b cb55b741 ec6ac649 0fb831bf 7eb29394 7557410a 25c5488a fa7735b8 50d48fcf b22c54e4 b7834206 1f12726d 77d87ed5 f1b64bbb 71dbf606 35898e0d 7529ca4e bca021c1 a6edf677 18a6910d 6943b215 cd6d6903 eeb18ecf 606459b5 75c3f9ef c4c0d5f2 133b8abc 33a75a3d 933ff833 53e6d572 d3aca771 413e86e2 15aa4cfd d6e37474 0864" create_key --fail -x asymmetric "" "$x509" $btk expect_error EACCES create_key --fail -x asymmetric "" "$x509" $stk expect_error ENOKEY create_key --fail -x asymmetric "" "$x509" $blk expect_error EACCES echo "++++ FINISHED TEST: $result" >>$OUTPUTFILE # --- then report the results in the database --- toolbox_report_result $TEST $result keyutils-1.6.3/tests/features/limits/000077500000000000000000000000001370111642500176535ustar00rootroot00000000000000keyutils-1.6.3/tests/features/limits/runtest.sh000066400000000000000000000012041370111642500217100ustar00rootroot00000000000000#!/bin/bash . ../../prepare.inc.sh . ../../toolbox.inc.sh # ---- do the actual testing ---- result=PASS echo "++++ BEGINNING TEST" >$OUTPUTFILE # This doesn't work on MIPS earler than 3.19 because of a kernel bug kver=`uname -r` kmch=`uname -m` if kernel_at_or_later_than 3.19 || [ "$kmch" != "mips" -a "$kmch" != "mips64" ] then marker "TEST TYPE AND DESC LIMITS" if ! keyctl --test limits then failed fi fi marker "TEST PAYLOAD LIMIT" if ! keyctl --test limits2 then failed fi echo "++++ FINISHED TEST: $result" >>$OUTPUTFILE # --- then report the results in the database --- toolbox_report_result $TEST $result keyutils-1.6.3/tests/keyctl/000077500000000000000000000000001370111642500160275ustar00rootroot00000000000000keyutils-1.6.3/tests/keyctl/add/000077500000000000000000000000001370111642500165575ustar00rootroot00000000000000keyutils-1.6.3/tests/keyctl/add/bad-args/000077500000000000000000000000001370111642500202375ustar00rootroot00000000000000keyutils-1.6.3/tests/keyctl/add/bad-args/runtest.sh000066400000000000000000000037701370111642500223060ustar00rootroot00000000000000#!/bin/bash . ../../../prepare.inc.sh . ../../../toolbox.inc.sh # ---- do the actual testing ---- result=PASS echo "++++ BEGINNING TEST" >$OUTPUTFILE # check that an empty key type fails correctly marker "CHECK EMPTY KEY TYPE" create_key --fail "" wibble stuff @p expect_error EINVAL # check that an unsupported key type fails correctly marker "CHECK UNSUPPORTED KEY TYPE" create_key --fail lizardsgizzards wibble stuff @p expect_error ENODEV # check that an invalid key type fails correctly marker "CHECK INVALID KEY TYPE" create_key --fail .user wibble stuff @p expect_error EPERM # check that an maximum length invalid key type fails correctly marker "CHECK MAXLEN KEY TYPE" create_key --fail $maxtype wibble stuff @p expect_error ENODEV # check that an overlong key type fails correctly marker "CHECK OVERLONG KEY TYPE" create_key --fail a$maxtype wibble stuff @p expect_error EINVAL # check that creation of a keyring with non-empty payload fails correctly marker "CHECK ADD KEYRING WITH PAYLOAD" create_key --fail keyring wibble a @p expect_error EINVAL # check that an max length key description works correctly (PAGE_SIZE inc NUL) if [ $PAGE_SIZE -lt $maxsquota ] then marker "CHECK MAXLEN DESC" create_key --new=keyid user $maxdesc stuff @s clear_keyring @s else marker "CHECK MAXLEN DESC FAILS WITH EDQUOT" create_key --fail user $maxdesc stuff @p expect_error EDQUOT fi # This doesn't work on MIPS earlier than 3.19 because of a kernel bug kver=`uname -r` kmch=`uname -m` if kernel_at_or_later_than 3.19 || [ "$kmch" != "mips" -a "$kmch" != "mips64" ] then # check that an overlong key description fails correctly (>4095 inc NUL) marker "CHECK OVERLONG DESC" create_key --fail user a$maxdesc stuff @p expect_error EINVAL fi # check that a bad key ID fails correctly marker "CHECK BAD KEY ID" create_key --fail user wibble stuff 0 expect_error EINVAL echo "++++ FINISHED TEST: $result" >>$OUTPUTFILE # --- then report the results in the database --- toolbox_report_result $TEST $result keyutils-1.6.3/tests/keyctl/add/noargs/000077500000000000000000000000001370111642500200505ustar00rootroot00000000000000keyutils-1.6.3/tests/keyctl/add/noargs/runtest.sh000066400000000000000000000014671370111642500221200ustar00rootroot00000000000000#!/bin/bash . ../../../prepare.inc.sh . ../../../toolbox.inc.sh # ---- do the actual testing ---- result=PASS echo "++++ BEGINNING TEST" >$OUTPUTFILE # check that no arguments fails correctly marker "ADD NO ARGS" expect_args_error keyctl add # check that one argument fails correctly marker "ADD ONE ARG" expect_args_error keyctl add user # check that two arguments fail correctly marker "ADD TWO ARGS" expect_args_error keyctl add user wibble # check that three arguments fail correctly marker "ADD THREE ARGS" expect_args_error keyctl add user wibble stuff # check that five arguments fail correctly marker "ADD FIVE ARGS" expect_args_error keyctl add user wibble stuff @s x echo "++++ FINISHED TEST: $result" >>$OUTPUTFILE # --- then report the results in the database --- toolbox_report_result $TEST $result keyutils-1.6.3/tests/keyctl/add/useradd/000077500000000000000000000000001370111642500202065ustar00rootroot00000000000000keyutils-1.6.3/tests/keyctl/add/useradd/runtest.sh000066400000000000000000000023261370111642500222510ustar00rootroot00000000000000#!/bin/bash . ../../../prepare.inc.sh . ../../../toolbox.inc.sh # ---- do the actual testing ---- result=PASS echo "++++ BEGINNING TEST" >$OUTPUTFILE # check that we can add a user key to the session keyring marker "ADD USER KEY" create_key --new=keyid user wibble stuff @s # read back what we put in it marker "PRINT PAYLOAD" print_key $keyid expect_payload payload "stuff" # check that we can add a hex-encoded user key to the session keyring marker "ADD HEX USER KEY" create_key --update=$keyid -x user wibble "73 7475 66 66 " @s # read back what we put in it marker "PRINT PAYLOAD" print_key $keyid expect_payload payload "stuff" # check that we can update a user key marker "UPDATE USER KEY" create_key --update=$keyid user wibble lizard @s # read back what we changed it to marker "PRINT UPDATED PAYLOAD" print_key $keyid expect_payload payload "lizard" # attempt to add a key to that non-keyring key marker "ADD KEY TO NON-KEYRING" create_key --fail user lizard gizzards $keyid expect_error ENOTDIR # remove the key we added marker "UNLINK KEY" unlink_key $keyid @s keyctl show echo "++++ FINISHED TEST: $result" >>$OUTPUTFILE # --- then report the results in the database --- toolbox_report_result $TEST $result keyutils-1.6.3/tests/keyctl/clear/000077500000000000000000000000001370111642500171155ustar00rootroot00000000000000keyutils-1.6.3/tests/keyctl/clear/bad-args/000077500000000000000000000000001370111642500205755ustar00rootroot00000000000000keyutils-1.6.3/tests/keyctl/clear/bad-args/runtest.sh000066400000000000000000000015311370111642500226350ustar00rootroot00000000000000#!/bin/bash . ../../../prepare.inc.sh . ../../../toolbox.inc.sh # ---- do the actual testing ---- result=PASS echo "++++ BEGINNING TEST" >$OUTPUTFILE # check that a bad key ID fails correctly marker "CHECK CLEAR BAD KEY ID" clear_keyring --fail 0 expect_error EINVAL # create a non-keyring marker "CREATE KEY" create_key --new=keyid user lizard gizzard @s # check that a non-keyring ID fails correctly marker "CHECK CLEAR NON-KEYRING KEY" clear_keyring --fail $keyid expect_error ENOTDIR # dispose of the key we were using marker "UNLINK KEY" unlink_key --wait $keyid @s # check that a non-existent key ID fails correctly marker "CHECK CLEAR NON-EXISTENT KEY ID" clear_keyring --fail $keyid expect_error ENOKEY echo "++++ FINISHED TEST: $result" >>$OUTPUTFILE # --- then report the results in the database --- toolbox_report_result $TEST $result keyutils-1.6.3/tests/keyctl/clear/noargs/000077500000000000000000000000001370111642500204065ustar00rootroot00000000000000keyutils-1.6.3/tests/keyctl/clear/noargs/runtest.sh000066400000000000000000000007361370111642500224540ustar00rootroot00000000000000#!/bin/bash . ../../../prepare.inc.sh . ../../../toolbox.inc.sh # ---- do the actual testing ---- result=PASS echo "++++ BEGINNING TEST" >$OUTPUTFILE # check that no arguments fails correctly marker "NO ARGS" expect_args_error keyctl clear # check that one argument fails correctly marker "TWO ARGS" expect_args_error keyctl clear 0 0 echo "++++ FINISHED TEST: $result" >>$OUTPUTFILE # --- then report the results in the database --- toolbox_report_result $TEST $result keyutils-1.6.3/tests/keyctl/clear/valid/000077500000000000000000000000001370111642500202145ustar00rootroot00000000000000keyutils-1.6.3/tests/keyctl/clear/valid/runtest.sh000066400000000000000000000036621370111642500222630ustar00rootroot00000000000000#!/bin/bash . ../../../prepare.inc.sh . ../../../toolbox.inc.sh # ---- do the actual testing ---- result=PASS echo "++++ BEGINNING TEST" >$OUTPUTFILE # create a keyring and attach it to the session keyring marker "ADD KEYRING" create_keyring --new=keyringid wibble @s # validate the new keyring's name and type marker "VALIDATE KEYRING" describe_key $keyringid expect_key_rdesc rdesc 'keyring@.*@wibble' # check that we have an empty keyring marker "LIST KEYRING" list_keyring $keyringid expect_keyring_rlist rlist empty # clear the empty keyring marker "CLEAR EMPTY KEYRING" clear_keyring $keyringid # check that it's empty again marker "LIST KEYRING 2" list_keyring $keyringid expect_keyring_rlist rlist empty # stick a key in the keyring marker "ADD KEY" create_key --new=keyid user lizard gizzard $keyringid # check that we can list it marker "LIST KEYRING WITH ONE" list_keyring $keyringid expect_keyring_rlist rlist $keyid # clear the keyring marker "CLEAR KEYRING WITH ONE" clear_keyring $keyringid # check that it's now empty again marker "LIST KEYRING 3" list_keyring $keyringid expect_keyring_rlist rlist empty # stick forty keys in the keyring marker "ADD FORTY KEYS" keys="" for ((i=0; i<40; i++)) do create_key --new=x user lizard$i gizzard$i $keyringid keys="$keys $x" list_keyring $keyringid expect_keyring_rlist rlist $x done marker "CHECK KEYRING CONTENTS" list_keyring $keyringid for i in $keys do expect_keyring_rlist rlist $i done marker "SHOW KEYRING" if ! keyctl show >>$OUTPUTFILE 2>&1 then failed fi # clear the keyring marker "CLEAR KEYRING WITH MANY" clear_keyring $keyringid # check that it's now empty yet again marker "LIST KEYRING 4" list_keyring $keyringid expect_keyring_rlist rlist empty # remove the keyring we added marker "UNLINK KEY" unlink_key $keyringid @s echo "++++ FINISHED TEST: $result" >>$OUTPUTFILE # --- then report the results in the database --- toolbox_report_result $TEST $result keyutils-1.6.3/tests/keyctl/describing/000077500000000000000000000000001370111642500201405ustar00rootroot00000000000000keyutils-1.6.3/tests/keyctl/describing/bad-args/000077500000000000000000000000001370111642500216205ustar00rootroot00000000000000keyutils-1.6.3/tests/keyctl/describing/bad-args/runtest.sh000066400000000000000000000014271370111642500236640ustar00rootroot00000000000000#!/bin/bash . ../../../prepare.inc.sh . ../../../toolbox.inc.sh # ---- do the actual testing ---- result=PASS echo "++++ BEGINNING TEST" >$OUTPUTFILE # check that a bad key ID fails correctly marker "CHECK BAD KEY ID" describe_key --fail 0 expect_error EINVAL pretty_describe_key --fail 0 expect_error EINVAL # create a key marker "CREATE KEY" create_key --new=keyid user lizard gizzard @s # dispose of the key marker "UNLINK KEY" unlink_key --wait $keyid @s # check that a non-existent key ID fails correctly marker "CHECK NON-EXISTENT KEY ID" describe_key --fail $keyid expect_error ENOKEY pretty_describe_key --fail $keyid expect_error ENOKEY echo "++++ FINISHED TEST: $result" >>$OUTPUTFILE # --- then report the results in the database --- toolbox_report_result $TEST $result keyutils-1.6.3/tests/keyctl/describing/noargs/000077500000000000000000000000001370111642500214315ustar00rootroot00000000000000keyutils-1.6.3/tests/keyctl/describing/noargs/runtest.sh000066400000000000000000000007611370111642500234750ustar00rootroot00000000000000#!/bin/bash . ../../../prepare.inc.sh . ../../../toolbox.inc.sh # ---- do the actual testing ---- result=PASS echo "++++ BEGINNING TEST" >$OUTPUTFILE marker "NO ARGS" expect_args_error keyctl describe expect_args_error keyctl rdescribe marker "TWO ARGS" expect_args_error keyctl describe 0 0 marker "THREE ARGS" expect_args_error keyctl rdescribe 0 0 0 echo "++++ FINISHED TEST: $result" >>$OUTPUTFILE # --- then report the results in the database --- toolbox_report_result $TEST $result keyutils-1.6.3/tests/keyctl/describing/valid/000077500000000000000000000000001370111642500212375ustar00rootroot00000000000000keyutils-1.6.3/tests/keyctl/describing/valid/runtest.sh000066400000000000000000000032461370111642500233040ustar00rootroot00000000000000#!/bin/bash . ../../../prepare.inc.sh . ../../../toolbox.inc.sh # ---- do the actual testing ---- result=PASS echo "++++ BEGINNING TEST" >$OUTPUTFILE # create a keyring and attach it to the session keyring marker "ADD KEYRING" create_keyring --new=keyringid wibble @s # validate the new keyring's name and type marker "VALIDATE KEYRING" describe_key $keyringid expect_key_rdesc rdesc 'keyring@.*@wibble' # validate a pretty description of the keyring marker "VALIDATE PRETTY KEYRING" pretty_describe_key $keyringid expect_key_rdesc pdesc " *$keyringid: [-avrwsl]* *[-0-9]* *[-0-9]* keyring: wibble" # check that we have an empty keyring marker "LIST KEYRING" list_keyring $keyringid expect_keyring_rlist rlist empty # stick a key in the keyring marker "ADD KEY" create_key --new=keyid user lizard gizzard $keyringid # validate the new key's name and type marker "VALIDATE KEY" describe_key $keyid expect_key_rdesc rdesc 'user@.*@lizard' # validate a pretty description of the key marker "VALIDATE PRETTY KEY" pretty_describe_key $keyid expect_key_rdesc pdesc " *$keyid: [-avrwsl]* *[0-9]* *[-0-9]* user: lizard" # turn off view permission on the key marker "DISABLE VIEW PERM" set_key_perm $keyid 0x3e0000 describe_key --fail $keyid expect_error EACCES # turn on view permission on the key marker "REINSTATE VIEW PERM" set_key_perm $keyid 0x3f0000 describe_key $keyid # revoke the key marker "REVOKE KEY" revoke_key $keyid describe_key --fail $keyid expect_error EKEYREVOKED # remove the keyring we added marker "UNLINK KEY" unlink_key $keyringid @s echo "++++ FINISHED TEST: $result" >>$OUTPUTFILE # --- then report the results in the database --- toolbox_report_result $TEST $result keyutils-1.6.3/tests/keyctl/dh_compute/000077500000000000000000000000001370111642500201565ustar00rootroot00000000000000keyutils-1.6.3/tests/keyctl/dh_compute/bad-args/000077500000000000000000000000001370111642500216365ustar00rootroot00000000000000keyutils-1.6.3/tests/keyctl/dh_compute/bad-args/runtest.sh000066400000000000000000000050101370111642500236720ustar00rootroot00000000000000#!/bin/bash . ../../../prepare.inc.sh . ../../../toolbox.inc.sh # ---- do the actual testing ---- if [ $have_dh_compute = 0 ] then toolbox_skip_test $TEST "SKIPPING DUE TO LACK OF DIFFIE-HELLMAN" exit 0 fi result=PASS echo "++++ BEGINNING TEST" >$OUTPUTFILE # Prime, generator, and key values created with: # openssl dhparam 2048 -check -out dh.pem # openssl genpkey -paramfile dh.pem -text prime="00b6894d8ff7af56d446c950c7e91d" prime+="298a078daea77966f11fc16f229211" prime+="737f1f39cef3dad7872a538f6c8f9a" prime+="276a7cf77bb2d63a872a4db9ed12ae" prime+="0f1c69af9bf2f2e3691d3615a1d7d5" prime+="77a87d1cb4aba0494bae0c249b0cce" prime+="ef6b7ab9a7be70b5b45e4cf7cb71ad" prime+="8feb7a4d6c7ccb96d5298f0feeb478" prime+="77605e80a0338691e35862f0f4cbb2" prime+="09e17dd9febcce4c21577006ceb115" prime+="7b181592d2f784ba44e006c314df53" prime+="06bdbb17a010b3660d479356d8d52c" prime+="5af014536c20897e7653218e2c7a65" prime+="0a73dc27584598de92de5c62706771" prime+="fa2d67f625441d911ca03f2149b6d4" prime+="c76b5ecd9896e9d799a3a500ececc5" prime+="19e31b71154d7b361bd0dd15f7ce8d" prime+="fc63" generator="02" private="40949da2ca2b7c353de38fefb06ddd" private+="0d67479a6361c89e77b980d2486c4d" private+="31971eb88f6572069973e3ae5a43ce" private+="76bccb35ea05ac6538eb0ea6adee49" private+="37600435dd7940885d2e3f78c72808" private+="34f878d3d550cc9305330bb8f02085" private+="ee6c230d42d84eb67a245b92817fd1" private+="54bcb1394a289d11afb5a1e50e1395" private+="0908af70756704e9bf03dff0e5d490" private+="743841c534cb7e2cf4b9f0493a730b" private+="0d71096a16bdc0e852f175755134b2" private+="b41112280a88212728afbe16d417f3" private+="1893cbe442e06d212d8efe227aa003" private+="9a65ce998107fae278511c6bf4d599" private+="32534ae9fc39db80635163c0546657" private+="500866d5461c5fa3540238324a29f3" private+="16e068f3ba1737d042cb51a8971bc7" private+="a2" create_key --new=primeid -x user dh:prime $prime @s create_key --new=generatorid -x user dh:generator $generator @s create_key --new=privateid -x user dh:private $private @s create_key --new=logonid -x logon dh:logon "00" @s marker "CHECK WRONG KEY TYPE" dh_compute --fail $privateid $primeid $logonid expect_error ENOKEY dh_compute --fail $privateid $primeid @s expect_error EOPNOTSUPP marker "CHECK MISSING KEY" dh_compute --fail $privateid $primeid 0 expect_error ENOKEY unlink_key --wait $generatorid @s dh_compute --fail $privateid $primeid $generatorid expect_error ENOKEY echo "++++ FINISHED TEST: $result" >>$OUTPUTFILE # --- then report the results in the database --- toolbox_report_result $TEST $result keyutils-1.6.3/tests/keyctl/dh_compute/noargs/000077500000000000000000000000001370111642500214475ustar00rootroot00000000000000keyutils-1.6.3/tests/keyctl/dh_compute/noargs/runtest.sh000066400000000000000000000011111370111642500235010ustar00rootroot00000000000000#!/bin/bash . ../../../prepare.inc.sh . ../../../toolbox.inc.sh # ---- do the actual testing ---- if [ $have_dh_compute = 0 ] then toolbox_skip_test $TEST "SKIPPING DUE TO LACK OF DIFFIE-HELLMAN" exit 0 fi result=PASS echo "++++ BEGINNING TEST" >$OUTPUTFILE marker "NO ARGS" expect_args_error keyctl dh_compute marker "TWO ARGS" expect_args_error keyctl dh_compute 0 0 marker "FOUR ARGS" expect_args_error keyctl dh_compute 0 0 0 0 echo "++++ FINISHED TEST: $result" >>$OUTPUTFILE # --- then report the results in the database --- toolbox_report_result $TEST $result keyutils-1.6.3/tests/keyctl/dh_compute/valid/000077500000000000000000000000001370111642500212555ustar00rootroot00000000000000keyutils-1.6.3/tests/keyctl/dh_compute/valid/runtest.sh000066400000000000000000000212601370111642500233160ustar00rootroot00000000000000#!/bin/bash . ../../../prepare.inc.sh . ../../../toolbox.inc.sh # ---- do the actual testing ---- if [ $have_dh_compute = 0 ] then toolbox_skip_test $TEST "SKIPPING DUE TO LACK OF DIFFIE-HELLMAN" exit 0 fi result=PASS echo "++++ BEGINNING TEST" >$OUTPUTFILE # Prime, generator, and key values created with: # openssl dhparam 2048 -check -out dh.pem # openssl genpkey -paramfile dh.pem -text prime="00b6894d8ff7af56d446c950c7e91d" prime+="298a078daea77966f11fc16f229211" prime+="737f1f39cef3dad7872a538f6c8f9a" prime+="276a7cf77bb2d63a872a4db9ed12ae" prime+="0f1c69af9bf2f2e3691d3615a1d7d5" prime+="77a87d1cb4aba0494bae0c249b0cce" prime+="ef6b7ab9a7be70b5b45e4cf7cb71ad" prime+="8feb7a4d6c7ccb96d5298f0feeb478" prime+="77605e80a0338691e35862f0f4cbb2" prime+="09e17dd9febcce4c21577006ceb115" prime+="7b181592d2f784ba44e006c314df53" prime+="06bdbb17a010b3660d479356d8d52c" prime+="5af014536c20897e7653218e2c7a65" prime+="0a73dc27584598de92de5c62706771" prime+="fa2d67f625441d911ca03f2149b6d4" prime+="c76b5ecd9896e9d799a3a500ececc5" prime+="19e31b71154d7b361bd0dd15f7ce8d" prime+="fc63" generator="02" private="40949da2ca2b7c353de38fefb06ddd" private+="0d67479a6361c89e77b980d2486c4d" private+="31971eb88f6572069973e3ae5a43ce" private+="76bccb35ea05ac6538eb0ea6adee49" private+="37600435dd7940885d2e3f78c72808" private+="34f878d3d550cc9305330bb8f02085" private+="ee6c230d42d84eb67a245b92817fd1" private+="54bcb1394a289d11afb5a1e50e1395" private+="0908af70756704e9bf03dff0e5d490" private+="743841c534cb7e2cf4b9f0493a730b" private+="0d71096a16bdc0e852f175755134b2" private+="b41112280a88212728afbe16d417f3" private+="1893cbe442e06d212d8efe227aa003" private+="9a65ce998107fae278511c6bf4d599" private+="32534ae9fc39db80635163c0546657" private+="500866d5461c5fa3540238324a29f3" private+="16e068f3ba1737d042cb51a8971bc7" private+="a2" read -d '' public <<"EOF" a4cf1f93 95fce03f d02aaece da1f86bd d8d77b69 29039fcc bd138c98 2483bf9c 7e4406c1 4f3cea24 6cafb29e 95095d0c 6768f13b 31babb24 6c590d92 6c343e69 59dbd47f 65982a3b b1baa7a3 05a72054 89b6cd0d 78397962 fc834fc9 3ec0517e c218396f 9cff860e 29078aee 6b8598b6 79325014 bb84597d f031e149 edbe1c5a 2a55fe4e bbc64a52 6da59e71 1c7ae5e0 954ba23b 9d58c423 17d84841 815708c8 b9059987 48773eac 2244b286 cd118277 48b7ed3a 5af5cc0f 8f254190 5e16f998 a328e894 acc343f4 66a95281 86cea6a3 93eb4fee f83c0e2e f4a00ce6 fcc9ef81 cc4624d5 ba659411 d1ba7b5f 14a3e286 d42e6ac8 afa9f846 41cb7cb5 66965725 EOF marker "LOAD SOURCE KEYS" create_key --new=primeid -x user dh:prime $prime @s create_key --new=generatorid -x user dh:generator $generator @s create_key --new=privateid -x user dh:private $private @s marker "COMPUTE DH PUBLIC KEY" dh_compute $privateid $primeid $generatorid expect_multiline payload "$public" echo "++++ FINISHED TEST: $result" >>$OUTPUTFILE ################################################################ # Testing DH compute with KDF according to SP800-56A # # test vectors from http://csrc.nist.gov/groups/STM/cavp/documents/keymgmt/KASTestVectorsFFC2014.zip ################################################################ # SHA-256 marker "LOAD SHA-256 SOURCE KEYS" # XephemCAVS private="81b2c65f5cbac00b1353ac38bd77a25a" private+="8650ed485e413eac1d6c4885" # P prime="a3cc6223e50c6e3f7bb0581dcb9e9ff0" prime+="2c580768328a15207b1c32317fb78496" prime+="815e3cf7f9d09ccb9fa840ff4798511a" prime+="17b55928721e5dfbccc54147e0f05f85" prime+="b3ac410b6ae3f59b796f3feac7fc5249" prime+="217eb2a04588293a5ade227879f46ceb" prime+="56457b5c431293e5e104d1b964bd2cdf" prime+="deffa04049a91e67ee8c86e944f04f94" prime+="4a30e361f8d15d17e5010cabb4ef40c0" prime+="eba5f4a252d4fd6cf9dae60e86e4b300" prime+="9b1dfc926670357261587ad05c00a6c6" prime+="f0106cec8fc59131515084a870594165" prime+="b49390db2d00e7538f230d532f4a4eca" prime+="8309d707c0b3835cee04f3ca558a22c6" prime+="b520fe25de6ffa90efda4927d018594c" prime+="0c0b77067393b7f1e0fc7cf216aff39f" # YephemIUT xa="9a70822d3f06123d0e518ee11651e5f6" xa+="b119dc3b97d5b1c0a2a6f6de942564ba" xa+="10061eecdeb7369ca537499e04b036e9" xa+="7f445a956f6369ae6e63fd27eae3e347" xa+="855447d3bac1c60c10e7350772c6c0c6" xa+="fbf9ca3e38f0e8658825d3b20f1f028f" xa+="35e34d1235103df2339b5b099d3fe3e5" xa+="346a691642bac5b0bb03cd5d04d75626" xa+="21493ff1c4273b6a45c5ecb0b5e908a0" xa+="f9f562282e853efc9a7ea112e9474ff6" xa+="9418f7c47ae966d4524ca1701b60a4be" xa+="15c75e27b405806468156e02cbc58ff4" xa+="663c96ac0c87368135fa9b0bb6337ae2" xa+="58521d7d60c2a91b4ed772ad65034049" xa+="97f6799df663a8999cfd747fa067b905" xa+="8ab33bc14594366f28f5a2d900b6467a" # Z read -d '' shared <<"EOF" 0fdbd9a2 ebf50cba 489b4e4d 7cd6924a 42ee6324 a26988b2 22bc38e6 9cc445f1 eb47c1a4 62eca39f 39bcd7b8 19dede51 30bc38da ec99c16f 40a4e5c1 9c97b796 8b41823d a0650e37 13c73e6f 5f2a9dff 2e67dbf5 40ee66f4 e694c28f ba1d604b 71b57b8a eeb67a35 ba425a38 490b6fb9 f713db22 6f893b7a 8962f426 ba3046fb cff8538c 16f583e8 ae947672 0ba55ff9 75b440d0 c4565cc7 5837d23a fea61a39 e0b7f6c4 e24c2154 7eb19fce f8dbed10 b06a9cce 971c0f0f ba7c1d5c b5035eaa 4fddd3ba fe757339 e3321e3e 4ebfe9e7 9c6c0401 4df63cf9 28d0a2c0 5b2d5521 030c35f1 c84c97fe 64cad509 8012a003 d52d24c4 1a1f9348 b7575251 3facb02f EOF # OI otherinfo="a1b2c3d4e54341565369640d64c1b2" otherinfo+="3361b261de78688ea865fcff113c84" # DKM read -d '' derived <<"EOF" 8284e313 02c8a26b 393ec52d 9f9e0882 EOF create_key --update=primeid -x user dh:prime $prime @s create_key --new=xaid -x user dh:xa $xa @s create_key --update=privateid -x user dh:private $private @s marker "COMPUTE DH SHARED SECRET" dh_compute $privateid $primeid $xaid expect_multiline payload "$shared" marker "COMPUTE DERIVED KEY FROM DH SHARED SECRET (SHA-256)" echo -e -n $otherinfo | dh_compute_kdf_oi -x $privateid $primeid $xaid 16 "sha256" expect_multiline payload "$derived" create_key --new=lzid -x user dh:leadingzero "01" @s read -d '' derived2 <<"EOF" 0066207b cdab1d64 bbf489b3 d6a0dadc EOF marker "COMPUTE DERIVED KEY WITH LEADING ZEROS" echo -e -n $otherinfo | dh_compute_kdf_oi -x $privateid $primeid $lzid 16 "sha256" expect_multiline payload "$derived2" # SHA-224 marker "LOAD SHA-224 SOURCE KEYS" # XephemCAVS private="861ba259aba6aa577de22f508ecbbc26" private+="c5acfccb9ea23b434d6d2b79" # P prime="a5b1764e13c81699aba38f0dc0d15e15" prime+="f50fcd5cf7c22372cafc5ed762941bd9" prime+="e0fb9aabee7466d2c829aab031db7b1b" prime+="5a64e68ed53bafb283ba0f018beb3edc" prime+="957fe453be0daab61b3228763e80758c" prime+="6d8c283cf630edd9d70a8af330dd0af6" prime+="a8d594c23cdd24c8ad3fcfea41757772" prime+="ceed921e63862f246e6f49d8747e44ae" prime+="f01e309b6dcc80d450383bb1f94dd590" prime+="84f8e96f856ec7c8335edb055f8ec6c4" prime+="81520b3f28e80b6209b8ae61cc860e24" prime+="c822b66c4f97804993bcd0a972b35354" prime+="01330ebe4b2e923f189b633562e468eb" prime+="99a4bc88ccbff8df0fd5afcfe6ae1918" prime+="4214ab3fefb7f0668b8b2683bebd5651" prime+="a4c63843b9b14bc738d520b1b7212c69" # YephemIUT xa="17d71af4353c22122aeb2a0619cc2cf7" xa+="3553f28e9fb191fdb286b115b9fda866" xa+="2de5173b1aff70488d9bc848e537d7e5" xa+="021649d37dc78c94369db90c2784c94d" xa+="970ac9b5e35efd22d418d31b68d9550b" xa+="aa7716e98ea6783bb3a845059fbaa4a6" xa+="720a6a23c56ba52b4d9b726e0068e9eb" xa+="4d175bff4369f3d2a4af66eecd62ef7b" xa+="23c337d470952b1767c8bf782f0b58b4" xa+="fc8245f840787170f4b0a51b5eb46075" xa+="8addc9f44a73a3f607603bd35073d1a6" xa+="9a203a0494a8c2021ba0da1f0495f560" xa+="c0ba81794eeeeb825d1bd34316a52ae1" xa+="c900100c0d6fa02546ed7a9c38a6a343" xa+="d68659eeb59cf38104a96bb25a6dbbf0" xa+="cbc0ede73a7bba675181e0cd2e7b9f89" # Z read -d '' shared <<"EOF" 057c22b8 c5872fef 08ebe852 fafab4b7 c2c2ffbb 376d71bd a941b16e 32614adf ebb82aeb d50f29d3 cec63d10 77f50e21 cf381b87 a818c614 52c5cce2 af85f40c 06615b97 fe8c3a80 68990ac5 83957b52 8dd6d52d a3b51e84 aec355fd 4a3fe5ce faa3b17c 9e71cb4d 28ecab6d 21297280 e52397b7 ccb1b62d 8d5d3ce4 1d26b2a3 bdbf880b b39e8b02 8a745ff2 9f0984da efe97084 5d850884 525403ca d2a52956 f55b9a89 b2d801f1 710333c0 479c5955 b54c8163 83c65ad9 c78b8c67 cc1b211b 208b9fab b9c99a68 18293e6a 8da069e6 75eb4317 668a7d4b 6f235533 f3ff4ed0 4f8ad579 f9ad14e7 f68ae183 41d603d9 d6297123 00716c98 bbbf16eb 2a2cc92f EOF # OI otherinfo="a1b2c3d4e5434156536964aa27e249" otherinfo+="bf0a1276468d808259f3b8e2687851" # DKM read -d '' derived <<"EOF" 88bf39c0 08eec33a dc3b4430 054ba262 EOF create_key --update=primeid -x user dh:prime $prime @s create_key --update=xaid -x user dh:xa $xa @s create_key --update=privateid -x user dh:private $private @s marker "COMPUTE DH SHARED SECRET" dh_compute $privateid $primeid $xaid expect_multiline payload "$shared" marker "COMPUTE DERIVED KEY FROM DH SHARED SECRET (SHA-224)" echo -e -n $otherinfo | dh_compute_kdf_oi -x $privateid $primeid $xaid 16 "sha224" expect_multiline payload "$derived" # --- then report the results in the database --- toolbox_report_result $TEST $result keyutils-1.6.3/tests/keyctl/id/000077500000000000000000000000001370111642500164235ustar00rootroot00000000000000keyutils-1.6.3/tests/keyctl/id/bad-args/000077500000000000000000000000001370111642500201035ustar00rootroot00000000000000keyutils-1.6.3/tests/keyctl/id/bad-args/runtest.sh000066400000000000000000000007601370111642500221460ustar00rootroot00000000000000#!/bin/bash . ../../../prepare.inc.sh . ../../../toolbox.inc.sh # ---- do the actual testing ---- result=PASS echo "++++ BEGINNING TEST" >$OUTPUTFILE # check that a bad key ID fails correctly marker "CHECK BAD KEY ID" id_key --fail 0 expect_error EINVAL # check non-existent standard IDs marker "CHECK BAD IDS" id_key --fail2 @wwww id_key --fail2 @qqqq echo "++++ FINISHED TEST: $result" >>$OUTPUTFILE # --- then report the results in the database --- toolbox_report_result $TEST $result keyutils-1.6.3/tests/keyctl/id/noargs/000077500000000000000000000000001370111642500177145ustar00rootroot00000000000000keyutils-1.6.3/tests/keyctl/id/noargs/runtest.sh000066400000000000000000000007301370111642500217540ustar00rootroot00000000000000#!/bin/bash . ../../../prepare.inc.sh . ../../../toolbox.inc.sh # ---- do the actual testing ---- result=PASS echo "++++ BEGINNING TEST" >$OUTPUTFILE # check that no arguments fails correctly marker "NO ARGS" expect_args_error keyctl id # check that one argument fails correctly marker "TWO ARGS" expect_args_error keyctl id 0 0 echo "++++ FINISHED TEST: $result" >>$OUTPUTFILE # --- then report the results in the database --- toolbox_report_result $TEST $result keyutils-1.6.3/tests/keyctl/id/valid/000077500000000000000000000000001370111642500175225ustar00rootroot00000000000000keyutils-1.6.3/tests/keyctl/id/valid/runtest.sh000066400000000000000000000025571370111642500215730ustar00rootroot00000000000000#!/bin/bash . ../../../prepare.inc.sh . ../../../toolbox.inc.sh # ---- do the actual testing ---- result=PASS echo "++++ BEGINNING TEST" >$OUTPUTFILE # check standard IDs marker "CHECK STD IDS" id_key --fail @t expect_error ENOKEY id_key --fail @p expect_error ENOKEY id_key --to=x @s id_key --to=x @u id_key --to=x @us id_key --fail @g expect_error EINVAL id_key --fail @a expect_error ENOKEY # create a keyring marker "CREATE KEYRING" create_keyring --new=keyid lizard @s # check that a non-keyring ID works marker "CHECK NON-KEYRING KEY" id_key --to=x $keyid id_key --to=x %:lizard id_key --fail %:lizardx # dispose of the key we were using marker "UNLINK KEYRING" unlink_key --wait $keyid @s # check that a non-existent key ID fails correctly marker "CHECK NON-EXISTENT KEYRING ID" id_key --fail $keyid expect_error ENOKEY # create a non-keyring marker "CREATE KEY" create_key --new=keyid user lizard gizzard @s # check that a non-keyring ID works marker "CHECK NON-KEYRING KEY" id_key --to=x $keyid id_key --to=x %user:lizard # dispose of the key we were using marker "UNLINK KEY" unlink_key --wait $keyid @s # check that a non-existent key ID fails correctly marker "CHECK NON-EXISTENT KEY ID" id_key --fail $keyid expect_error ENOKEY echo "++++ FINISHED TEST: $result" >>$OUTPUTFILE # --- then report the results in the database --- toolbox_report_result $TEST $result keyutils-1.6.3/tests/keyctl/instantiating/000077500000000000000000000000001370111642500207035ustar00rootroot00000000000000keyutils-1.6.3/tests/keyctl/instantiating/bad-args/000077500000000000000000000000001370111642500223635ustar00rootroot00000000000000keyutils-1.6.3/tests/keyctl/instantiating/bad-args/runtest.sh000066400000000000000000000033051370111642500244240ustar00rootroot00000000000000#!/bin/bash . ../../../prepare.inc.sh . ../../../toolbox.inc.sh # ---- do the actual testing ---- result=PASS echo "++++ BEGINNING TEST" >$OUTPUTFILE # check that a bad key ID fails correctly marker "CHECK BAD KEY ID" instantiate_key --fail 0 a @p expect_error EPERM pinstantiate_key --fail a 0 @p expect_error EPERM negate_key --fail 0 10 @p expect_error EPERM reject_key --fail 0 10 rejected @p expect_error EPERM # create a non-keyring marker "CREATE KEY" create_key --new=keyid user lizard gizzard @s # check that instantiation of an instantiated key fails marker "CHECK ALREADY INSTANTIATED KEY" instantiate_key --fail $keyid a @p expect_error EPERM pinstantiate_key --fail a $keyid @p expect_error EPERM reject_key --fail $keyid 10 rejected @p expect_error EPERM negate_key --fail $keyid 10 @p expect_error EPERM # check reject key timeout must be a number marker "CHECK REJECT TIMEOUT" expect_args_error keyctl reject $keyid aa rejected @p # check reject key timeout must be a number marker "CHECK REJECT ERRORS" expect_args_error keyctl reject $keyid 10 notanerror @p # check negative key timeout must be a number marker "CHECK NEGATE TIMEOUT" expect_args_error keyctl negate $keyid aa @p # dispose of the key we were using marker "UNLINK KEY" unlink_key --wait $keyid @s # check that a non-existent key ID fails correctly marker "CHECK NON-EXISTENT KEY ID" instantiate_key --fail $keyid a @p expect_error EPERM pinstantiate_key --fail a $keyid @p expect_error EPERM reject_key --fail $keyid 10 rejected @p expect_error EPERM negate_key --fail $keyid 10 @p expect_error EPERM echo "++++ FINISHED TEST: $result" >>$OUTPUTFILE # --- then report the results in the database --- toolbox_report_result $TEST $result keyutils-1.6.3/tests/keyctl/instantiating/noargs/000077500000000000000000000000001370111642500221745ustar00rootroot00000000000000keyutils-1.6.3/tests/keyctl/instantiating/noargs/runtest.sh000066400000000000000000000014551370111642500242410ustar00rootroot00000000000000#!/bin/bash . ../../../prepare.inc.sh . ../../../toolbox.inc.sh # ---- do the actual testing ---- result=PASS echo "++++ BEGINNING TEST" >$OUTPUTFILE marker "NO ARGS" expect_args_error keyctl instantiate expect_args_error keyctl pinstantiate expect_args_error keyctl negate marker "ONE ARG" expect_args_error keyctl instantiate 0 expect_args_error keyctl pinstantiate 0 expect_args_error keyctl negate 0 marker "TWO ARGS" expect_args_error keyctl instantiate 0 0 expect_args_error keyctl negate 0 0 marker "THREE ARGS" expect_args_error keyctl pinstantiate 0 0 0 marker "FOUR ARGS" expect_args_error keyctl instantiate 0 0 0 0 expect_args_error keyctl negate 0 0 0 0 echo "++++ FINISHED TEST: $result" >>$OUTPUTFILE # --- then report the results in the database --- toolbox_report_result $TEST $result keyutils-1.6.3/tests/keyctl/invalidate/000077500000000000000000000000001370111642500201475ustar00rootroot00000000000000keyutils-1.6.3/tests/keyctl/invalidate/bad-args/000077500000000000000000000000001370111642500216275ustar00rootroot00000000000000keyutils-1.6.3/tests/keyctl/invalidate/bad-args/runtest.sh000066400000000000000000000015041370111642500236670ustar00rootroot00000000000000#!/bin/bash . ../../../prepare.inc.sh . ../../../toolbox.inc.sh # ---- do the actual testing ---- if [ $have_key_invalidate = 0 ] then toolbox_skip_test $TEST "SKIPPING DUE TO LACK OF KEY INVALIDATION" exit 0 fi result=PASS echo "++++ BEGINNING TEST" >$OUTPUTFILE # check that a bad key ID fails correctly marker "CHECK INVALIDATE BAD KEY ID" invalidate_key --fail 0 expect_error EINVAL # create a key marker "CREATE KEY" create_key --new=keyid user lizard gizzard @s # and dispose of it marker "UNLINK KEY" unlink_key --wait $keyid @s # check that a non-existent key ID fails correctly marker "CHECK INVALIDATE NON-EXISTENT KEY ID" invalidate_key --fail $keyid expect_error ENOKEY echo "++++ FINISHED TEST: $result" >>$OUTPUTFILE # --- then report the results in the database --- toolbox_report_result $TEST $result keyutils-1.6.3/tests/keyctl/invalidate/noargs/000077500000000000000000000000001370111642500214405ustar00rootroot00000000000000keyutils-1.6.3/tests/keyctl/invalidate/noargs/runtest.sh000066400000000000000000000011431370111642500234770ustar00rootroot00000000000000#!/bin/bash . ../../../prepare.inc.sh . ../../../toolbox.inc.sh # ---- do the actual testing ---- if [ $have_key_invalidate = 0 ] then toolbox_skip_test $TEST "SKIPPING DUE TO LACK OF KEY INVALIDATION" exit 0 fi result=PASS echo "++++ BEGINNING TEST" >$OUTPUTFILE # check that no arguments fails correctly marker "NO ARGS" expect_args_error keyctl invalidate # check that two arguments fail correctly marker "TWO ARGS" expect_args_error keyctl invalidate 0 0 echo "++++ FINISHED TEST: $result" >>$OUTPUTFILE # --- then report the results in the database --- toolbox_report_result $TEST $result keyutils-1.6.3/tests/keyctl/invalidate/valid/000077500000000000000000000000001370111642500212465ustar00rootroot00000000000000keyutils-1.6.3/tests/keyctl/invalidate/valid/runtest.sh000066400000000000000000000031431370111642500233070ustar00rootroot00000000000000#!/bin/bash . ../../../prepare.inc.sh . ../../../toolbox.inc.sh # ---- do the actual testing ---- if [ $have_key_invalidate = 0 ] then toolbox_skip_test $TEST "SKIPPING DUE TO LACK OF KEY INVALIDATION" exit 0 fi result=PASS echo "++++ BEGINNING TEST" >$OUTPUTFILE # create a keyring and attach it to the session keyring marker "ADD KEYRING" create_keyring --new=keyringid wibble @s # check that we have an empty keyring marker "LIST KEYRING" list_keyring $keyringid expect_keyring_rlist rlist empty # stick a key in the keyring marker "ADD KEY" create_key --new=keyid user lizard gizzard $keyringid # check that we can list it marker "LIST KEYRING 2" list_keyring $keyringid expect_keyring_rlist rlist $keyid # invalidate the key marker "INVALIDATE KEY" invalidate_key $keyid # need to wait for the gc sleep 1 # check that it's now empty again marker "LIST KEYRING 3" list_keyring $keyringid expect_keyring_rlist rlist empty # stick another key in the keyring marker "ADD KEY" create_key --new=keyid user lizard2 gizzard $keyringid # check that we can list it marker "LIST KEYRING 4" list_keyring $keyringid expect_keyring_rlist rlist $keyid # invalidate the keyring marker "INVALIDATE KEYRING" invalidate_key $keyringid # need to wait for the gc sleep 1 # check that the keyring no longer exists marker "CHECK KEYRING" list_keyring --fail $keyringid expect_error ENOKEY # check that the key got gc'd also marker "CHECK KEY" describe_key --fail $keyid expect_error ENOKEY echo "++++ FINISHED TEST: $result" >>$OUTPUTFILE # --- then report the results in the database --- toolbox_report_result $TEST $result keyutils-1.6.3/tests/keyctl/link/000077500000000000000000000000001370111642500167645ustar00rootroot00000000000000keyutils-1.6.3/tests/keyctl/link/bad-args/000077500000000000000000000000001370111642500204445ustar00rootroot00000000000000keyutils-1.6.3/tests/keyctl/link/bad-args/runtest.sh000066400000000000000000000020161370111642500225030ustar00rootroot00000000000000#!/bin/bash . ../../../prepare.inc.sh . ../../../toolbox.inc.sh # ---- do the actual testing ---- result=PASS echo "++++ BEGINNING TEST" >$OUTPUTFILE # check that a bad key ID fails correctly marker "CHECK LINK FROM BAD KEY ID" link_key --fail 0 @s expect_error EINVAL marker "CHECK LINK TO BAD KEY ID" link_key --fail @s 0 expect_error EINVAL # create a non-keyring marker "CREATE KEY" create_key --new=keyid user lizard gizzard @s # check that linking to a non-keyring ID fails correctly marker "CHECK LINK TO NON-KEYRING KEY" link_key --fail @s $keyid expect_error ENOTDIR # dispose of the key we were using marker "UNLINK KEY" unlink_key --wait $keyid @s # check that a non-existent key ID fails correctly marker "CHECK LINK TO NON-EXISTENT KEY ID" link_key --fail @s $keyid expect_error ENOKEY marker "CHECK LINK FROM NON-EXISTENT KEY ID" link_key --fail $keyid @s expect_error ENOKEY echo "++++ FINISHED TEST: $result" >>$OUTPUTFILE # --- then report the results in the database --- toolbox_report_result $TEST $result keyutils-1.6.3/tests/keyctl/link/noargs/000077500000000000000000000000001370111642500202555ustar00rootroot00000000000000keyutils-1.6.3/tests/keyctl/link/noargs/runtest.sh000066400000000000000000000011001370111642500223050ustar00rootroot00000000000000#!/bin/bash . ../../../prepare.inc.sh . ../../../toolbox.inc.sh # ---- do the actual testing ---- result=PASS echo "++++ BEGINNING TEST" >$OUTPUTFILE # check that no arguments fails correctly marker "NO ARGS" expect_args_error keyctl link # check that one argument fails correctly marker "ONE ARGS" expect_args_error keyctl link 0 # check that three arguments fails correctly marker "THREE ARGS" expect_args_error keyctl link 0 0 0 echo "++++ FINISHED TEST: $result" >>$OUTPUTFILE # --- then report the results in the database --- toolbox_report_result $TEST $result keyutils-1.6.3/tests/keyctl/link/recursion/000077500000000000000000000000001370111642500207755ustar00rootroot00000000000000keyutils-1.6.3/tests/keyctl/link/recursion/runtest.sh000066400000000000000000000103511370111642500230350ustar00rootroot00000000000000#!/bin/bash . ../../../prepare.inc.sh . ../../../toolbox.inc.sh # ---- do the actual testing ---- result=PASS echo "++++ BEGINNING TEST" >$OUTPUTFILE # create a keyring and attach it to the session keyring marker "CREATE KEYRING 1" create_keyring --new=keyringid "first" @s set_key_perm $keyringid 0x3f3f0000 # attempt to link a keyring to itself marker "RECURSE 1" link_key --fail $keyringid $keyringid expect_error EDEADLK # create a second keyring in the first marker "CREATE KEYRING 2" create_keyring --new=keyring2id "second" $keyringid set_key_perm $keyring2id 0x3f3f0000 # attempt to link a keyring to its child keyring marker "RECURSE 2" link_key --fail $keyringid $keyring2id expect_error EDEADLK # create a third keyring in the second marker "CREATE KEYRING 3" create_keyring --new=keyring3id "third" $keyring2id set_key_perm $keyring3id 0x3f3f0000 # attempt to link a keyring to its grandchild keyring marker "RECURSE 3" link_key --fail $keyringid $keyring3id expect_error EDEADLK # create a fourth keyring in the third marker "CREATE KEYRING 4" create_keyring --new=keyring4id "fourth" $keyring3id set_key_perm $keyring4id 0x3f3f0000 # attempt to link a keyring to its great grandchild keyring marker "RECURSE 4" link_key --fail $keyringid $keyring4id expect_error EDEADLK # create a fifth keyring in the fourth marker "CREATE KEYRING 5" create_keyring --new=keyring5id "fifth" $keyring4id set_key_perm $keyring5id 0x3f3f0000 # attempt to link a keyring to its great great grandchild keyring marker "RECURSE 5" link_key --fail $keyringid $keyring5id expect_error EDEADLK # create a sixth keyring in the fifth marker "CREATE KEYRING 6" create_keyring --new=keyring6id "sixth" $keyring5id set_key_perm $keyring6id 0x3f3f0000 # attempt to link a keyring to its great great great grandchild keyring marker "RECURSE 6" link_key --fail $keyringid $keyring6id expect_error EDEADLK # create a seventh keyring in the sixth marker "CREATE KEYRING 7" create_keyring --new=keyring7id "seventh" $keyring6id set_key_perm $keyring7id 0x3f3f0000 # attempt to link a keyring to its great great great great grandchild keyring marker "RECURSE 7" link_key --fail $keyringid $keyring7id expect_error EDEADLK # create an eighth keyring in the seventh marker "CREATE KEYRING 8" create_keyring --new=keyring8id "eighth" @s set_key_perm $keyring8id 0x3f3f0000 link_key $keyring8id $keyring7id unlink_key $keyring8id @s # attempt to link a keyring to its great great great great great grandchild keyring marker "RECURSE 8" link_key --fail $keyringid $keyring8id expect_error EDEADLK # create a ninth keyring in the eighth marker "CREATE KEYRING 9" create_keyring --new=keyring9id "ninth" @s set_key_perm $keyring9id 0x3f3f0000 link_key $keyring9id $keyring8id unlink_key $keyring9id @s # attempt to link a keyring to its great great great great great great grandchild keyring marker "RECURSE 9" link_key --fail $keyringid $keyring9id expect_error ELOOP # remove the first keyring we added marker "UNLINK KEYRING" unlink_key $keyringid @s # create two stacks of keyrings marker "CREATE KEYRING STACKS" create_keyring --new=aroot "A1" @s create_keyring --new=broot "B1" @s a=$aroot b=$broot for ((i=2; i<=4; i++)) do create_keyring --new=a "A$i" $a create_keyring --new=b "B$i" $b done # make sure we can't create a cycle by linking the two stacks together marker "LINK A TO B" link_key $aroot $b marker "LINK B TO A" link_key --fail $broot $a expect_error EDEADLK marker "UNLINK A FROM B" unlink_key $aroot $b marker "LINK B TO A" link_key $broot $a marker "LINK A TO B" link_key --fail $aroot $b expect_error EDEADLK marker "UNLINK B FROM A" unlink_key $broot $a # extend the stacks marker "EXTEND STACKS" create_keyring --new=a "A5" $a create_keyring --new=b "B5" $b # make sure we can't hide a cycle by linking the two bigger stacks together marker "CHECK MAXDEPTH A TO B" link_key $aroot $b link_key --fail $broot $a expect_error ELOOP unlink_key $aroot $b marker "CHECK MAXDEPTH B TO A" link_key $broot $a link_key --fail $aroot $b expect_error ELOOP unlink_key $broot $a # remove the two stacks marker "UNLINK STACKS" unlink_key $aroot @s unlink_key $broot @s echo "++++ FINISHED TEST: $result" >>$OUTPUTFILE # --- then report the results in the database --- toolbox_report_result $TEST $result keyutils-1.6.3/tests/keyctl/link/valid/000077500000000000000000000000001370111642500200635ustar00rootroot00000000000000keyutils-1.6.3/tests/keyctl/link/valid/runtest.sh000066400000000000000000000055101370111642500221240ustar00rootroot00000000000000#!/bin/bash . ../../../prepare.inc.sh . ../../../toolbox.inc.sh # ---- do the actual testing ---- result=PASS echo "++++ BEGINNING TEST" >$OUTPUTFILE # create a keyring and attach it to the session keyring marker "ADD KEYRING" create_keyring --new=keyringid wibble @s # validate the new keyring's name and type marker "VALIDATE KEYRING" describe_key $keyringid expect_key_rdesc rdesc 'keyring@.*@wibble' # check that we can list it marker "LIST KEYRING" list_keyring $keyringid expect_keyring_rlist rlist empty # stick a key in the keyring marker "ADD KEY" create_key --new=keyid user lizard gizzard $keyringid # check that we can list it marker "LIST KEYRING WITH ONE" list_keyring $keyringid expect_keyring_rlist rlist $keyid # link the key across to the session keyring marker "LINK KEY 1" link_key $keyid @s marker "CHECK KEY LINKAGE" list_keyring @s expect_keyring_rlist srlist $keyid # link the key across to the session keyring again and again marker "LINK KEY 2" link_key $keyid @s marker "LINK KEY 3" link_key $keyid @s # subsequent links should displace earlier links, giving us a maximum of 1 link marker "COUNT LINKS" list_keyring @s expect_keyring_rlist srlist nlinks=0 for i in $srlist do if [ "x$i" = "x$keyid" ] then nlinks=$(($nlinks + 1)) fi done if [ $nlinks != 1 ] then failed fi # remove the links marker "UNLINK KEY FROM SESSION" unlink_key $keyid @s # removing again should fail unlink_key --fail $keyid @s expect_error ENOENT # remove that key from the keyring (the key should be destroyed) marker "UNLINK KEY FROM KEYRING" unlink_key --wait $keyid $keyringid # and a second time should fail, but now the key doesn't exist unlink_key --fail $keyid $keyringid expect_error ENOKEY # create a second keyring in the first create_keyring --new=keyring2id "zebra" $keyringid # link thrice across to the session keyring marker "LINK 2ND KEYRING TO SESSION" link_key $keyring2id @s link_key $keyring2id @s link_key $keyring2id @s # subsequent links should displace earlier links, giving us a maximum of 1 link marker "COUNT KEYRING LINKS" list_keyring @s expect_keyring_rlist srlist nlinks=0 for i in $srlist do if [ "x$i" = "x$keyring2id" ] then nlinks=$(($nlinks + 1)) fi done if [ $nlinks != 1 ] then failed fi # remove the keyring links marker "UNLINK 2ND KEYRING FROM SESSION" unlink_key $keyring2id @s # removing again should fail unlink_key --fail $keyring2id @s expect_error ENOENT # make another keyring link marker "LINK 2ND KEYRING TO SESSION" link_key $keyring2id @s # remove the first keyring we added marker "UNLINK KEYRING" unlink_key --wait $keyringid @s # remove the second keyring we added marker "UNLINK 2ND KEYRING" unlink_key --wait $keyring2id @s echo "++++ FINISHED TEST: $result" >>$OUTPUTFILE # --- then report the results in the database --- toolbox_report_result $TEST $result keyutils-1.6.3/tests/keyctl/listing/000077500000000000000000000000001370111642500175005ustar00rootroot00000000000000keyutils-1.6.3/tests/keyctl/listing/bad-args/000077500000000000000000000000001370111642500211605ustar00rootroot00000000000000keyutils-1.6.3/tests/keyctl/listing/bad-args/runtest.sh000066400000000000000000000014551370111642500232250ustar00rootroot00000000000000#!/bin/bash . ../../../prepare.inc.sh . ../../../toolbox.inc.sh # ---- do the actual testing ---- result=PASS echo "++++ BEGINNING TEST" >$OUTPUTFILE # check that a bad key ID fails correctly marker "CHECK BAD KEY ID" list_keyring --fail 0 expect_error ENOKEY pretty_list_keyring --fail 0 expect_error ENOKEY # create a non-keyring marker "CREATE KEY" create_key --new=keyid user lizard gizzard @s # dispose of the key we were using marker "UNLINK KEY" unlink_key --wait $keyid @s # check that a non-existent key ID fails correctly marker "CHECK NON-EXISTENT KEY ID" list_keyring --fail $keyid expect_error ENOKEY pretty_list_keyring --fail $keyid expect_error ENOKEY echo "++++ FINISHED TEST: $result" >>$OUTPUTFILE # --- then report the results in the database --- toolbox_report_result $TEST $result keyutils-1.6.3/tests/keyctl/listing/noargs/000077500000000000000000000000001370111642500207715ustar00rootroot00000000000000keyutils-1.6.3/tests/keyctl/listing/noargs/runtest.sh000066400000000000000000000007121370111642500230310ustar00rootroot00000000000000#!/bin/bash . ../../../prepare.inc.sh . ../../../toolbox.inc.sh # ---- do the actual testing ---- result=PASS echo "++++ BEGINNING TEST" >$OUTPUTFILE marker "NO ARGS" expect_args_error keyctl list expect_args_error keyctl rlist marker "TWO ARGS" expect_args_error keyctl list 0 0 expect_args_error keyctl rlist 0 0 echo "++++ FINISHED TEST: $result" >>$OUTPUTFILE # --- then report the results in the database --- toolbox_report_result $TEST $result keyutils-1.6.3/tests/keyctl/listing/valid/000077500000000000000000000000001370111642500205775ustar00rootroot00000000000000keyutils-1.6.3/tests/keyctl/listing/valid/runtest.sh000066400000000000000000000045131370111642500226420ustar00rootroot00000000000000#!/bin/bash . ../../../prepare.inc.sh . ../../../toolbox.inc.sh # ---- do the actual testing ---- result=PASS echo "++++ BEGINNING TEST" >$OUTPUTFILE # create a keyring and attach it to the session keyring marker "ADD KEYRING" create_keyring --new=keyringid wibble @s # validate the new keyring's name and type marker "VALIDATE KEYRING" describe_key $keyringid expect_key_rdesc rdesc 'keyring@.*@wibble' # check that we have an empty keyring marker "LIST KEYRING" list_keyring $keyringid expect_keyring_rlist rlist empty marker "PRETTY LIST KEYRING" pretty_list_keyring $keyringid expect_payload payload "keyring is empty" # stick a key in the keyring marker "ADD KEY" create_key --new=keyid user lizard gizzard $keyringid # check that we can list it marker "LIST KEYRING WITH ONE" list_keyring $keyringid expect_keyring_rlist rlist $keyid # check that we can pretty list it marker "PRETTY LIST KEYRING WITH ONE" pretty_list_keyring $keyringid expect_payload payload if ! expr "$payload" : " *$keyid:.*user: lizard" >&/dev/null then failed fi # stick a second key in the keyring marker "ADD KEY 2" create_key --new=keyid2 user snake skin $keyringid # check that we can see both keys marker "LIST KEYRING WITH TWO" list_keyring $keyringid expect_keyring_rlist rlist if [ "x$rlist" != "x$keyid $keyid2" ] then failed fi # check that we can see both keys prettily marker "PRETTY LIST KEYRING WITH TWO" pretty_list_keyring $keyringid prlist="" for i in `tail -2 $OUTPUTFILE | cut -d: -f1 | sed -e 's@ +@@g'` do prlist="$prlist $i" done if [ "x$prlist" != "x $keyid $keyid2" ] then failed fi # turn off read permission on the keyring marker "DISABLE READ PERM" set_key_perm $keyringid 0x3d0000 list_keyring $keyringid # turn off read and search permission on the keyring marker "DISABLE SEARCH PERM" set_key_perm $keyringid 0x350000 list_keyring --fail $keyringid expect_error EACCES # turn on read permission on the keyring marker "REINSTATE READ PERM" set_key_perm $keyringid 0x370000 list_keyring $keyringid # revoke the keyring marker "REVOKE KEYRING" revoke_key $keyringid list_keyring --fail $keyringid expect_error EKEYREVOKED # remove the keyring we added marker "UNLINK KEY" unlink_key $keyringid @s echo "++++ FINISHED TEST: $result" >>$OUTPUTFILE # --- then report the results in the database --- toolbox_report_result $TEST $result keyutils-1.6.3/tests/keyctl/move/000077500000000000000000000000001370111642500167755ustar00rootroot00000000000000keyutils-1.6.3/tests/keyctl/move/bad-args/000077500000000000000000000000001370111642500204555ustar00rootroot00000000000000keyutils-1.6.3/tests/keyctl/move/bad-args/runtest.sh000066400000000000000000000026001370111642500225130ustar00rootroot00000000000000#!/bin/bash . ../../../prepare.inc.sh . ../../../toolbox.inc.sh # ---- do the actual testing ---- result=PASS echo "++++ BEGINNING TEST" >$OUTPUTFILE # check that a bad key ID fails correctly marker "CHECK MOVE OF BAD KEY ID" move_key --fail 0 @u @s expect_error EINVAL marker "CHECK MOVE FROM BAD KEYRING ID" move_key --fail @u 0 @s expect_error EINVAL marker "CHECK MOVE TO BAD KEYRING ID" move_key --fail @u @s 0 expect_error EINVAL marker "CHECK FORCED MOVE OF BAD KEY ID" move_key --fail -f 0 @u @s expect_error EINVAL marker "CHECK FORCED MOVE FROM BAD KEYRING ID" move_key --fail -f @u 0 @s expect_error EINVAL marker "CHECK FORCED MOVE TO BAD KEYRING ID" move_key --fail -f @u @s 0 expect_error EINVAL # create a pair of non-keyrings marker "CREATE KEY" create_key --new=keyid user lizard gizzard @s marker "CREATE KEY2" create_key --new=keyid2 user zebra stripes @s # check that linking to a non-keyring ID fails correctly marker "CHECK MOVE FROM NON-KEYRING KEY" move_key --fail $keyid $keyid2 @s expect_error ENOTDIR marker "CHECK MOVE TO NON-KEYRING KEY" move_key --fail $keyid @s $keyid2 expect_error ENOTDIR # dispose of the keys we were using marker "UNLINK KEY" unlink_key --wait $keyid @s marker "UNLINK KEY2" unlink_key --wait $keyid2 @s echo "++++ FINISHED TEST: $result" >>$OUTPUTFILE # --- then report the results in the database --- toolbox_report_result $TEST $result keyutils-1.6.3/tests/keyctl/move/noargs/000077500000000000000000000000001370111642500202665ustar00rootroot00000000000000keyutils-1.6.3/tests/keyctl/move/noargs/runtest.sh000066400000000000000000000016121370111642500223260ustar00rootroot00000000000000#!/bin/bash . ../../../prepare.inc.sh . ../../../toolbox.inc.sh # ---- do the actual testing ---- result=PASS echo "++++ BEGINNING TEST" >$OUTPUTFILE # check that no arguments fails correctly marker "NO ARGS" expect_args_error keyctl move marker "NO ARGS (F)" expect_args_error keyctl move -f # check that one argument fails correctly marker "ONE ARGS" expect_args_error keyctl move 0 marker "ONE ARGS (F)" expect_args_error keyctl move -f 0 # check that two arguments fails correctly marker "TWO ARGS" expect_args_error keyctl move 0 0 marker "TWO ARGS (F)" expect_args_error keyctl move -f 0 0 # check that four arguments fails correctly marker "FOUR ARGS" expect_args_error keyctl link 0 0 0 0 marker "FOUR ARGS (F)" expect_args_error keyctl link -f 0 0 0 0 echo "++++ FINISHED TEST: $result" >>$OUTPUTFILE # --- then report the results in the database --- toolbox_report_result $TEST $result keyutils-1.6.3/tests/keyctl/move/recursion/000077500000000000000000000000001370111642500210065ustar00rootroot00000000000000keyutils-1.6.3/tests/keyctl/move/recursion/runtest.sh000066400000000000000000000120561370111642500230520ustar00rootroot00000000000000#!/bin/bash . ../../../prepare.inc.sh . ../../../toolbox.inc.sh # ---- do the actual testing ---- result=PASS echo "++++ BEGINNING TEST" >$OUTPUTFILE # create a keyring and attach it to the session keyring marker "CREATE KEYRING 1" create_keyring --new=keyringid "first" @s set_key_perm $keyringid 0x3f3f0000 # attempt to move a keyring to itself marker "RECURSE 1" move_key --fail $keyringid @s $keyringid expect_error EDEADLK marker "RECURSE 1F" move_key --fail -f $keyringid @s $keyringid expect_error EDEADLK # create a second keyring in the first marker "CREATE KEYRING 2" create_keyring --new=keyring2id "second" $keyringid set_key_perm $keyring2id 0x3f3f0000 # attempt to move a keyring to its child keyring marker "RECURSE 2" move_key --fail $keyringid @s $keyring2id expect_error EDEADLK marker "RECURSE 2F" move_key --fail -f $keyringid @s $keyring2id expect_error EDEADLK # create a third keyring in the second marker "CREATE KEYRING 3" create_keyring --new=keyring3id "third" $keyring2id set_key_perm $keyring3id 0x3f3f0000 # attempt to move a keyring to its grandchild keyring marker "RECURSE 3" move_key --fail $keyringid @s $keyring3id expect_error EDEADLK marker "RECURSE 3F" move_key --fail -f $keyringid @s $keyring3id expect_error EDEADLK # create a fourth keyring in the third marker "CREATE KEYRING 4" create_keyring --new=keyring4id "fourth" $keyring3id set_key_perm $keyring4id 0x3f3f0000 # attempt to move a keyring to its great grandchild keyring marker "RECURSE 4" move_key --fail $keyringid @s $keyring4id expect_error EDEADLK marker "RECURSE 4F" move_key --fail -f $keyringid @s $keyring4id expect_error EDEADLK # create a fifth keyring in the fourth marker "CREATE KEYRING 5" create_keyring --new=keyring5id "fifth" $keyring4id set_key_perm $keyring5id 0x3f3f0000 # attempt to move a keyring to its great great grandchild keyring marker "RECURSE 5" move_key --fail $keyringid @s $keyring5id expect_error EDEADLK marker "RECURSE 5F" move_key --fail -f $keyringid @s $keyring5id expect_error EDEADLK # create a sixth keyring in the fifth marker "CREATE KEYRING 6" create_keyring --new=keyring6id "sixth" $keyring5id set_key_perm $keyring6id 0x3f3f0000 # attempt to move a keyring to its great great great grandchild keyring marker "RECURSE 6" move_key --fail $keyringid @s $keyring6id expect_error EDEADLK marker "RECURSE 6F" move_key --fail -f $keyringid @s $keyring6id expect_error EDEADLK # create a seventh keyring in the sixth marker "CREATE KEYRING 7" create_keyring --new=keyring7id "seventh" $keyring6id set_key_perm $keyring7id 0x3f3f0000 # attempt to move a keyring to its great great great great grandchild keyring marker "RECURSE 7" move_key --fail $keyringid @s $keyring7id expect_error EDEADLK marker "RECURSE 7F" move_key --fail -f $keyringid @s $keyring7id expect_error EDEADLK # create an eigth keyring in the seventh marker "CREATE KEYRING 8" create_keyring --new=keyring8id "eighth" @s set_key_perm $keyring8id 0x3f3f0000 move_key $keyring8id @s $keyring7id # attempt to move a keyring to its great great great great great grandchild keyring marker "RECURSE 8" move_key --fail $keyringid @s $keyring8id expect_error EDEADLK # create a ninth keyring in the eighth marker "CREATE KEYRING 9" create_keyring --new=keyring9id "ninth" @s set_key_perm $keyring9id 0x3f3f0000 move_key $keyring9id @s $keyring8id # attempt to move a keyring to its great great great great great great grandchild keyring marker "RECURSE 9" move_key --fail $keyringid @s $keyring9id expect_error ELOOP marker "RECURSE 9F" move_key --fail -f $keyringid @s $keyring9id expect_error ELOOP # remove the first keyring we added marker "UNLINK KEYRING" unlink_key $keyringid @s # create two stacks of keyrings marker "CREATE KEYRING STACKS" create_keyring --new=aroot "A1" @s create_keyring --new=broot "B1" @s a=$aroot b=$broot for ((i=2; i<=4; i++)) do create_keyring --new=a "A$i" $a create_keyring --new=b "B$i" $b done # make sure we can't create a cycle by linking the two stacks together marker "LINK A TO B" link_key $aroot $b marker "MOVE B TO A" move_key --fail $broot @s $a expect_error EDEADLK marker "FORCE MOVE B TO A" move_key --fail -f $broot @s $a expect_error EDEADLK marker "UNLINK A FROM B" unlink_key $aroot $b marker "LINK B TO A" link_key $broot $a marker "MOVE A TO B" move_key --fail $aroot @s $b expect_error EDEADLK marker "FORCE MOVE A TO B" move_key --fail -f $aroot @s $b expect_error EDEADLK marker "UNLINK B FROM A" unlink_key $broot $a # extend the stacks marker "EXTEND STACKS" create_keyring --new=a "A5" $a create_keyring --new=b "B5" $b # make sure we can't hide a cycle by linking the two bigger stacks together marker "CHECK MAXDEPTH A TO B" link_key $aroot $b move_key --fail $broot @s $a expect_error ELOOP unlink_key $aroot $b marker "CHECK MAXDEPTH B TO A" link_key $broot $a move_key --fail $aroot @s $b expect_error ELOOP unlink_key $broot $a # remove the two stacks marker "UNLINK STACKS" unlink_key $aroot @s unlink_key $broot @s echo "++++ FINISHED TEST: $result" >>$OUTPUTFILE # --- then report the results in the database --- toolbox_report_result $TEST $result keyutils-1.6.3/tests/keyctl/move/valid/000077500000000000000000000000001370111642500200745ustar00rootroot00000000000000keyutils-1.6.3/tests/keyctl/move/valid/runtest.sh000066400000000000000000000121441370111642500221360ustar00rootroot00000000000000#!/bin/bash . ../../../prepare.inc.sh . ../../../toolbox.inc.sh # ---- do the actual testing ---- result=PASS echo "++++ BEGINNING TEST" >$OUTPUTFILE # create a keyring and attach it to the session keyring marker "ADD KEYRING" create_keyring --new=keyringid wibble @s # stick a key in the keyring marker "ADD KEY" create_key --new=keyid user lizard gizzard $keyringid # check that we can list it marker "LIST KEYRING WITH ONE" list_keyring $keyringid expect_keyring_rlist rlist $keyid # move the key across to the session keyring marker "MOVE KEY 1" move_key $keyid $keyringid @s marker "CHECK KEY LINKAGE" list_keyring @s expect_keyring_rlist srlist $keyid marker "CHECK KEY REMOVED" list_keyring $keyringid expect_keyring_rlist rlist $keyid --absent # Repeating the move should fail marker "MOVE KEY 2" move_key --fail $keyid $keyringid @s expect_error ENOENT marker "FORCE MOVE KEY 2" move_key --fail -f $keyid $keyringid @s expect_error ENOENT # Move the key back again marker "MOVE KEY 3" move_key $keyid @s $keyringid marker "MOVE KEY 4" move_key --fail -f $keyid @s $keyringid expect_error ENOENT # Create a conflicting key and try to have an unforced move displace it marker "ADD KEY 2" create_key --new=keyid2 user lizard gizzard @s marker "MOVE KEY 5" move_key --fail $keyid $keyringid @s expect_error EEXIST marker "CHECK KEY UNMOVED" list_keyring $keyringid expect_keyring_rlist rlist $keyid marker "CHECK KEY UNDISPLACED" list_keyring @s expect_keyring_rlist srlist $keyid --absent expect_keyring_rlist srlist $keyid2 # Now try a forced move marker "FORCE MOVE KEY 6" move_key -f $keyid $keyringid @s marker "CHECK KEY REMOVED" list_keyring $keyringid expect_keyring_rlist rlist $keyid --absent expect_keyring_rlist rlist $keyid2 --absent marker "CHECK KEY DISPLACED" list_keyring @s expect_keyring_rlist srlist $keyid expect_keyring_rlist srlist $keyid2 --absent # Remove the link (the key should be destroyed) marker "UNLINK KEY FROM SESSION" unlink_key --wait $keyid @s # Removing again should fail unlink_key --fail $keyid @s expect_error ENOKEY # Remove that key from the keyring should also fail marker "UNLINK KEY FROM KEYRING" unlink_key --fail $keyid $keyringid expect_error ENOKEY ############################################################################### # Create a second keyring in the first create_keyring --new=keyring2id "zebra" $keyringid # Move thrice between the session keyring and back marker "LINK 2ND KEYRING TO SESSION" move_key $keyring2id $keyringid @s move_key $keyring2id @s $keyringid move_key $keyring2id $keyringid @s # Subsequent links should displace earlier links, giving us a maximum of 1 link marker "COUNT KEYRING LINKS" list_keyring @s expect_keyring_rlist srlist nlinks=0 for i in $srlist do if [ "x$i" = "x$keyring2id" ] then nlinks=$(($nlinks + 1)) fi done if [ $nlinks != 1 ] then failed fi # Remove the keyring links, destroying it marker "UNLINK 2ND KEYRING FROM SESSION" unlink_key --wait $keyring2id @s # Removing again should fail marker "RE-UNLINK" unlink_key --fail $keyring2id @s expect_error ENOKEY marker "RE-UNLINK 2" unlink_key --fail $keyring2id $keyringid expect_error ENOKEY ############################################################################### # Create a second keyring in the session keyring create_keyring --new=keyring2id "zebra" @s # Add a key to the session keyring and link it into each keyring marker "ADD KEY 3" create_key --new=keyid user lizard gizzard @s marker "LINK KEY" link_key $keyid $keyringid marker "LINK KEY 2" link_key $keyid $keyring2id # Try to move the links from the keyrings into the session keyring marker "MOVE LINK" move_key --fail $keyid $keyringid @s expect_error EEXIST marker "CHECK LINK" list_keyring $keyringid expect_keyring_rlist rlist $keyid marker "MOVE LINK 2" move_key --fail $keyid $keyring2id @s expect_error EEXIST marker "CHECK LINK 2" list_keyring $keyring2id expect_keyring_rlist rlist $keyid marker "MOVE LINK 3" move_key $keyid @s @s marker "CHECK LINK 3" list_keyring @s expect_keyring_rlist srlist $keyid # Try to force move the links from the keyrings into the session keyring marker "FORCE MOVE LINK" move_key -f $keyid $keyringid @s marker "CHECK LINK 4" list_keyring $keyringid expect_keyring_rlist rlist $keyid --absent marker "CHECK LINK 4s" list_keyring @s expect_keyring_rlist srlist $keyid marker "FORCE MOVE LINK 2" move_key -f $keyid $keyring2id @s marker "CHECK LINK 5" list_keyring $keyring2id expect_keyring_rlist rlist $keyid --absent marker "CHECK LINK 5s" list_keyring @s expect_keyring_rlist srlist $keyid marker "FORCE MOVE LINK 3" move_key -f $keyid @s @s marker "CHECK LINK 6" list_keyring @s expect_keyring_rlist srlist $keyid # Move the key between keyrings marker "ROTATE" move_key $keyid @s $keyringid move_key $keyid $keyringid $keyring2id move_key $keyid $keyring2id @s marker "UNLINK KEY" unlink_key $keyid @s # remove the keyrings marker "UNLINK KEYRING 1" unlink_key --wait $keyringid @s marker "UNLINK KEYRING 2" unlink_key --wait $keyring2id @s echo "++++ FINISHED TEST: $result" >>$OUTPUTFILE # --- then report the results in the database --- toolbox_report_result $TEST $result keyutils-1.6.3/tests/keyctl/newring/000077500000000000000000000000001370111642500175005ustar00rootroot00000000000000keyutils-1.6.3/tests/keyctl/newring/bad-args/000077500000000000000000000000001370111642500211605ustar00rootroot00000000000000keyutils-1.6.3/tests/keyctl/newring/bad-args/runtest.sh000066400000000000000000000022771370111642500232300ustar00rootroot00000000000000#!/bin/bash . ../../../prepare.inc.sh . ../../../toolbox.inc.sh # ---- do the actual testing ---- result=PASS echo "++++ BEGINNING TEST" >$OUTPUTFILE # check that an max length key description works correctly (4096 inc NUL) if [ $PAGE_SIZE -lt $maxsquota ] then marker "CHECK MAXLEN DESC" create_keyring --new=keyid $maxdesc @s clear_keyring @s else marker "CHECK MAXLEN DESC FAILS WITH EDQUOT" create_keyring --fail $maxdesc @s expect_error EDQUOT fi # This doesn't work on MIPS earlier than 3.19 because of a kernel bug kver=`uname -r` kmch=`uname -m` if kernel_at_or_later_than 3.19 || [ "$kmch" != "mips" -a "$kmch" != "mips64" ] then # check that an overlong key description fails correctly (>4095 inc NUL) marker "CHECK OVERLONG DESC" create_keyring --fail a$maxdesc @s expect_error EINVAL fi # check that an empty keyring name fails marker "CHECK EMPTY KEYRING NAME" create_keyring --fail "" @s expect_error EINVAL # check that a bad key ID fails correctly marker "CHECK BAD KEY ID" create_keyring --fail wibble 0 expect_error EINVAL echo "++++ FINISHED TEST: $result" >>$OUTPUTFILE # --- then report the results in the database --- toolbox_report_result $TEST $result keyutils-1.6.3/tests/keyctl/newring/noargs/000077500000000000000000000000001370111642500207715ustar00rootroot00000000000000keyutils-1.6.3/tests/keyctl/newring/noargs/runtest.sh000066400000000000000000000011421370111642500230270ustar00rootroot00000000000000#!/bin/bash . ../../../prepare.inc.sh . ../../../toolbox.inc.sh # ---- do the actual testing ---- result=PASS echo "++++ BEGINNING TEST" >$OUTPUTFILE # check that no arguments fails correctly marker "ADD NO ARGS" expect_args_error keyctl newring # check that one argument fails correctly marker "ADD ONE ARG" expect_args_error keyctl newring user # check that three arguments fail correctly marker "ADD THREE ARGS" expect_args_error keyctl newring user wibble stuff echo "++++ FINISHED TEST: $result" >>$OUTPUTFILE # --- then report the results in the database --- toolbox_report_result $TEST $result keyutils-1.6.3/tests/keyctl/newring/valid/000077500000000000000000000000001370111642500205775ustar00rootroot00000000000000keyutils-1.6.3/tests/keyctl/newring/valid/runtest.sh000066400000000000000000000026171370111642500226450ustar00rootroot00000000000000#!/bin/bash . ../../../prepare.inc.sh . ../../../toolbox.inc.sh # ---- do the actual testing ---- result=PASS echo "++++ BEGINNING TEST" >$OUTPUTFILE # create a keyring and attach it to the session keyring marker "ADD KEYRING" create_keyring --new=keyringid wibble @s # check that we now have an empty keyring marker "LIST KEYRING" list_keyring $keyringid expect_keyring_rlist rlist empty # check that creating a second keyring of the same name displaces the first marker "ADD KEYRING AGAIN" create_keyring --new=keyringid2 wibble @s # should be different keyrings if [ "x$keyringid" == "x$keyringid2" ] then failed fi # the first should no longer exist in the session keyring marker "LIST SESSION KEYRING" list_keyring @s expect_keyring_rlist sessionrlist $keyringid --absent # and should no longer be accessible marker "VALIDATE NEW KEYRING" pause_till_key_destroyed $keyringid describe_key --fail $keyringid expect_error ENOKEY # list the session keyring marker "LIST SESSION KEYRING2" list_keyring @s expect_keyring_rlist sessionrlist $keyringid2 # validate the new keyring's name and type marker "VALIDATE NEW KEYRING2" describe_key $keyringid2 expect_key_rdesc rdesc 'keyring@.*@wibble' # remove the keyring we added marker "UNLINK KEY" unlink_key $keyringid2 @s echo "++++ FINISHED TEST: $result" >>$OUTPUTFILE # --- then report the results in the database --- toolbox_report_result $TEST $result keyutils-1.6.3/tests/keyctl/noargs/000077500000000000000000000000001370111642500173205ustar00rootroot00000000000000keyutils-1.6.3/tests/keyctl/noargs/runtest.sh000066400000000000000000000006411370111642500213610ustar00rootroot00000000000000#!/bin/bash . ../../prepare.inc.sh . ../../toolbox.inc.sh # ---- do the actual testing ---- result=PASS echo "++++ BEGINNING TEST" >$OUTPUTFILE marker "CHECK NO ARGS" expect_args_error keyctl if [ "`sed -n -e 3p $OUTPUTFILE | cut -d: -f1`" != "Format" ] then failed fi echo "++++ FINISHED TEST: $result" >>$OUTPUTFILE # --- then report the results in the database --- toolbox_report_result $TEST $result keyutils-1.6.3/tests/keyctl/padd/000077500000000000000000000000001370111642500167375ustar00rootroot00000000000000keyutils-1.6.3/tests/keyctl/padd/bad-args/000077500000000000000000000000001370111642500204175ustar00rootroot00000000000000keyutils-1.6.3/tests/keyctl/padd/bad-args/runtest.sh000066400000000000000000000037621370111642500224670ustar00rootroot00000000000000#!/bin/bash . ../../../prepare.inc.sh . ../../../toolbox.inc.sh # ---- do the actual testing ---- result=PASS echo "++++ BEGINNING TEST" >$OUTPUTFILE # check that an empty key type fails correctly marker "CHECK EMPTY KEY TYPE" pcreate_key --fail stuff "" wibble @p expect_error EINVAL # check that an unsupported key type fails correctly marker "CHECK UNSUPPORTED KEY TYPE" pcreate_key --fail stuff lizardsgizzards wibble @p expect_error ENODEV # check that an invalid key type fails correctly marker "CHECK INVALID KEY TYPE" pcreate_key --fail stuff .user wibble @p expect_error EPERM # check that an maximum length invalid key type fails correctly marker "CHECK MAXLEN KEY TYPE" pcreate_key --fail stuff $maxtype wibble @p expect_error ENODEV # check that an overlong key type fails correctly marker "CHECK OVERLONG KEY TYPE" pcreate_key --fail stuff a$maxtype wibble @p expect_error EINVAL # check that creation of a keyring with non-empty payload fails correctly marker "CHECK ADD KEYRING WITH PAYLOAD" pcreate_key --fail stuff keyring wibble @p expect_error EINVAL # check that an max length key description works correctly if [ $PAGE_SIZE -lt $maxsquota ] then marker "CHECK MAXLEN DESC" pcreate_key --new=keyid stuff user $maxdesc @s clear_keyring @s else marker "CHECK MAXLEN DESC FAILS WITH EDQUOT" pcreate_key --fail stuff user $maxdesc @p expect_error EDQUOT fi # This doesn't work on MIPS earlier than 3.19 because of a kernel bug kver=`uname -r` kmch=`uname -m` if kernel_at_or_later_than 3.19 || [ "$kmch" != "mips" -a "$kmch" != "mips64" ] then # check that an overlong key description fails correctly (>4095 inc NUL) marker "CHECK OVERLONG DESC" pcreate_key --fail stuff user a$maxdesc @p expect_error EINVAL fi # check that a bad key ID fails correctly marker "CHECK BAD KEY ID" pcreate_key --fail stuff user wibble 0 expect_error EINVAL echo "++++ FINISHED TEST: $result" >>$OUTPUTFILE # --- then report the results in the database --- toolbox_report_result $TEST $result keyutils-1.6.3/tests/keyctl/padd/noargs/000077500000000000000000000000001370111642500202305ustar00rootroot00000000000000keyutils-1.6.3/tests/keyctl/padd/noargs/runtest.sh000066400000000000000000000013011370111642500222630ustar00rootroot00000000000000#!/bin/bash . ../../../prepare.inc.sh . ../../../toolbox.inc.sh # ---- do the actual testing ---- result=PASS echo "++++ BEGINNING TEST" >$OUTPUTFILE # check that no arguments fails correctly marker "ADD NO ARGS" expect_args_error keyctl padd # check that one argument fails correctly marker "ADD ONE ARG" expect_args_error keyctl padd user # check that two arguments fail correctly marker "ADD TWO ARGS" expect_args_error keyctl padd user wibble # check that four arguments fail correctly marker "ADD FOUR ARGS" expect_args_error keyctl padd user wibble @s x echo "++++ FINISHED TEST: $result" >>$OUTPUTFILE # --- then report the results in the database --- toolbox_report_result $TEST $result keyutils-1.6.3/tests/keyctl/padd/useradd/000077500000000000000000000000001370111642500203665ustar00rootroot00000000000000keyutils-1.6.3/tests/keyctl/padd/useradd/runtest.sh000066400000000000000000000042511370111642500224300ustar00rootroot00000000000000#!/bin/bash . ../../../prepare.inc.sh . ../../../toolbox.inc.sh # ---- do the actual testing ---- result=PASS echo "++++ BEGINNING TEST" >$OUTPUTFILE # check that we can add a user key to the session keyring marker "ADD USER KEY" pcreate_key --new=keyid stuff user wibble @s # read back what we put in it marker "PRINT PAYLOAD" print_key $keyid expect_payload payload "stuff" # check that we can add a hex-encoded user key to the session keyring marker "ADD HEX USER KEY" pcreate_key --update=$keyid "73 7475 66 66 " -x user wibble @s # read back what we put in it marker "PRINT PAYLOAD" print_key $keyid expect_payload payload "stuff" # check that we can update a user key marker "UPDATE USER KEY" pcreate_key --update=$keyid lizard user wibble @s # read back what we changed it to marker "PRINT UPDATED PAYLOAD" print_key $keyid expect_payload payload "lizard" # remove the key we added marker "UNLINK KEY" unlink_key $keyid @s if [ $skip_root_required = 0 ] && { [ $OSDIST = RHEL ] && ! version_less_than $OSRELEASE 6.6 || keyutils_at_or_later_than 1.5.6 ; } then # add keys with huge payloads old_root_quota=`cat /proc/sys/kernel/keys/root_maxbytes` if [ $old_root_quota -lt 65536 ] then marker "INCREASE QUOTA" echo 65536 >/proc/sys/kernel/keys/root_maxbytes fi marker "ADD LARGE USER KEY" pcreate_key_by_size --new=keyid 32767 user large @s md5sum_key $keyid expect_payload payload "f128f774ede3fe931e7c6745c4292f40" if [ $have_big_key_type = 1 ] then marker "ADD SMALL BIG KEY" pcreate_key_by_size --new=keyid 128 big_key small @s md5sum_key $keyid expect_payload payload "f09f35a5637839458e462e6350ecbce4" marker "ADD HUGE BIG KEY" pcreate_key_by_size --new=keyid $((1024*1024-1)) big_key huge @s md5sum_key $keyid expect_payload payload "e57598cd670284cf7d09e16ed9d4b2ac" fi marker "CLEAR KEYRING" clear_keyring @s if [ $old_root_quota -lt 65536 ] then marker "RESET QUOTA" echo $old_root_quota >/proc/sys/kernel/keys/root_maxbytes sleep 1 fi fi echo "++++ FINISHED TEST: $result" >>$OUTPUTFILE # --- then report the results in the database --- toolbox_report_result $TEST $result keyutils-1.6.3/tests/keyctl/permitting/000077500000000000000000000000001370111642500202115ustar00rootroot00000000000000keyutils-1.6.3/tests/keyctl/permitting/bad-args/000077500000000000000000000000001370111642500216715ustar00rootroot00000000000000keyutils-1.6.3/tests/keyctl/permitting/bad-args/runtest.sh000066400000000000000000000020751370111642500237350ustar00rootroot00000000000000#!/bin/bash . ../../../prepare.inc.sh . ../../../toolbox.inc.sh # ---- do the actual testing ---- result=PASS echo "++++ BEGINNING TEST" >$OUTPUTFILE # check that a bad key ID fails correctly marker "CHECK BAD KEY ID" chown_key --fail 0 0 expect_error EINVAL chgrp_key --fail 0 0 expect_error EINVAL set_key_perm --fail 0 0 expect_error EINVAL # create a non-keyring marker "CREATE KEY" create_key --new=keyid user lizard gizzard @s # check that unsupported permissions aren't permitted marker "CHECK PERMS" set_key_perm --fail $keyid 0xffffffff expect_error EINVAL set_key_perm --fail $keyid 0x7f7f7f7f expect_error EINVAL # dispose of the key we just made marker "UNLINK KEY" unlink_key --wait $keyid @s # check that a non-existent key ID fails correctly marker "CHECK CLEAR NON-EXISTENT KEY ID" chown_key --fail $keyid 0 expect_error ENOKEY chgrp_key --fail $keyid 0 expect_error ENOKEY set_key_perm --fail $keyid 0 expect_error ENOKEY echo "++++ FINISHED TEST: $result" >>$OUTPUTFILE # --- then report the results in the database --- toolbox_report_result $TEST $result keyutils-1.6.3/tests/keyctl/permitting/noargs/000077500000000000000000000000001370111642500215025ustar00rootroot00000000000000keyutils-1.6.3/tests/keyctl/permitting/noargs/runtest.sh000066400000000000000000000012151370111642500235410ustar00rootroot00000000000000#!/bin/bash . ../../../prepare.inc.sh . ../../../toolbox.inc.sh # ---- do the actual testing ---- result=PASS echo "++++ BEGINNING TEST" >$OUTPUTFILE marker "NO ARGS" expect_args_error keyctl read expect_args_error keyctl pipe expect_args_error keyctl print marker "ONE ARG" expect_args_error keyctl chown 0 expect_args_error keyctl chgrp 0 expect_args_error keyctl setperm 0 marker "THREE ARGS" expect_args_error keyctl chown 0 0 0 expect_args_error keyctl chgrp 0 0 0 expect_args_error keyctl setperm 0 0 0 echo "++++ FINISHED TEST: $result" >>$OUTPUTFILE # --- then report the results in the database --- toolbox_report_result $TEST $result keyutils-1.6.3/tests/keyctl/permitting/valid/000077500000000000000000000000001370111642500213105ustar00rootroot00000000000000keyutils-1.6.3/tests/keyctl/permitting/valid/runtest.sh000066400000000000000000000045611370111642500233560ustar00rootroot00000000000000#!/bin/bash . ../../../prepare.inc.sh . ../../../toolbox.inc.sh # ---- do the actual testing ---- result=PASS echo "++++ BEGINNING TEST" >$OUTPUTFILE # create a keyring and attach it to the session keyring marker "ADD KEYRING" create_keyring --new=keyringid wibble @s # stick a key in the keyring marker "ADD KEY" create_key --new=keyid user lizard gizzard $keyringid # changing the key's ownership is not supported before 2.6.18-rc1 if kernel_older_than 2.6.18 then marker "CHOWN" chown_key --fail $keyid 1 expect_error EOPNOTSUPP elif [ `id -u` != 0 ] then # must be running as root for this to work marker "CHOWN" chown_key --fail $keyid 1 expect_error EACCES else marker "CHOWN" chown_key $keyid 1 marker "CHOWN BACK" chown_key $keyid 0 fi # changing the key's group ownership is supported (change to "bin" group) if [ `id -u` != 0 ] then marker "CHGRP" chgrp_key --fail $keyid 1 expect_error EACCES else marker "CHGRP" chgrp_key $keyid 1 describe_key $keyid expect_key_rdesc rdesc "user@.*@1@[0-9a-f]*@lizard" fi # check that each permission can be granted to the key marker "ITERATE PERMISSIONS" for i in \ 00210002 00210004 00210008 00210010 \ 00210200 00210400 00210800 00211000 \ 00230000 00250000 00290000 00310000 \ 02210000 04210000 08210000 10210000 do set_key_perm $keyid 0x$i describe_key $keyid expect_key_rdesc rdesc "user@.*@.*@$i@lizard" done # check that we can't use group perms instead of user perms to view the key # (our UID matches that of the key) marker "VIEW GROUP PERMISSIONS" set_key_perm $keyid 0x00201f00 describe_key --fail $keyid expect_error EACCES # check that we can't use other perms instead of user perms to view the key # (our UID matches that of the key) marker "VIEW OTHER PERMISSIONS" set_key_perm $keyid 0x0020001f describe_key --fail $keyid expect_error EACCES # check that taking away setattr permission renders the key immune to setperm marker "REMOVE SETATTR" set_key_perm $keyid 0x1f1f1f1f describe_key $keyid expect_key_rdesc rdesc "user@.*@.*@.*@lizard" marker "REINSTATE SETATTR" set_key_perm --fail $keyid 0x3f3f1f1f expect_error EACCES # remove the keyring we added marker "UNLINK KEYRING" unlink_key $keyringid @s echo "++++ FINISHED TEST: $result" >>$OUTPUTFILE # --- then report the results in the database --- toolbox_report_result $TEST $result keyutils-1.6.3/tests/keyctl/pupdate/000077500000000000000000000000001370111642500174715ustar00rootroot00000000000000keyutils-1.6.3/tests/keyctl/pupdate/bad-args/000077500000000000000000000000001370111642500211515ustar00rootroot00000000000000keyutils-1.6.3/tests/keyctl/pupdate/bad-args/runtest.sh000066400000000000000000000016021370111642500232100ustar00rootroot00000000000000#!/bin/bash . ../../../prepare.inc.sh . ../../../toolbox.inc.sh # ---- do the actual testing ---- result=PASS echo "++++ BEGINNING TEST" >$OUTPUTFILE # attempt to update the session keyring marker "CHECK UPDATE SESSION KEYRING" echo -n "a" | pupdate_key --fail @s expect_error EOPNOTSUPP # attempt to update an invalid key marker "CHECK UPDATE INVALID KEY" echo -n "a" | pupdate_key --fail 0 expect_error EINVAL # add a user key to the session keyring for us to play with marker "ADD USER KEY" create_key --new=keyid user wibble stuff @s # remove the key we just added marker "UNLINK KEY" unlink_key --wait $keyid @s # it should fail when we attempt to update it marker "UPDATE UNLINKED KEY" echo -n "a" | pupdate_key --fail $keyid expect_error ENOKEY echo "++++ FINISHED TEST: $result" >>$OUTPUTFILE # --- then report the results in the database --- toolbox_report_result $TEST $result keyutils-1.6.3/tests/keyctl/pupdate/noargs/000077500000000000000000000000001370111642500207625ustar00rootroot00000000000000keyutils-1.6.3/tests/keyctl/pupdate/noargs/runtest.sh000066400000000000000000000007671370111642500230340ustar00rootroot00000000000000#!/bin/bash . ../../../prepare.inc.sh . ../../../toolbox.inc.sh # ---- do the actual testing ---- result=PASS echo "++++ BEGINNING TEST" >$OUTPUTFILE # check that no arguments fails correctly marker "PUPDATE NO ARGS" expect_args_error keyctl pupdate # check that two arguments fail correctly marker "PUPDATE TWO ARGS" expect_args_error keyctl pupdate yyy xxxx echo "++++ FINISHED TEST: $result" >>$OUTPUTFILE # --- then report the results in the database --- toolbox_report_result $TEST $result keyutils-1.6.3/tests/keyctl/pupdate/userupdate/000077500000000000000000000000001370111642500216525ustar00rootroot00000000000000keyutils-1.6.3/tests/keyctl/pupdate/userupdate/runtest.sh000066400000000000000000000014441370111642500237150ustar00rootroot00000000000000#!/bin/bash . ../../../prepare.inc.sh . ../../../toolbox.inc.sh # ---- do the actual testing ---- result=PASS echo "++++ BEGINNING TEST" >$OUTPUTFILE # check that we can add a user key to the session keyring marker "ADD USER KEY" create_key --new=keyid user wibble stuff @s # read back what we put in it marker "PRINT PAYLOAD" print_key $keyid expect_payload payload "stuff" # check that we can update a user key marker "PUPDATE USER KEY" echo -n "lizard" | pupdate_key $keyid # read back what we changed it to marker "PRINT UPDATED PAYLOAD" print_key $keyid expect_payload payload "lizard" # remove the key we added marker "UNLINK KEY" unlink_key $keyid @s echo "++++ FINISHED TEST: $result" >>$OUTPUTFILE # --- then report the results in the database --- toolbox_report_result $TEST $result keyutils-1.6.3/tests/keyctl/reading/000077500000000000000000000000001370111642500174405ustar00rootroot00000000000000keyutils-1.6.3/tests/keyctl/reading/bad-args/000077500000000000000000000000001370111642500211205ustar00rootroot00000000000000keyutils-1.6.3/tests/keyctl/reading/bad-args/runtest.sh000066400000000000000000000015471370111642500231670ustar00rootroot00000000000000#!/bin/bash . ../../../prepare.inc.sh . ../../../toolbox.inc.sh # ---- do the actual testing ---- result=PASS echo "++++ BEGINNING TEST" >$OUTPUTFILE # check that a bad key ID fails correctly marker "CHECK BAD KEY ID" read_key --fail 0 expect_error ENOKEY print_key --fail 0 expect_error ENOKEY pipe_key --fail 0 expect_error ENOKEY # create a non-keyring marker "CREATE KEY" create_key --new=keyid user lizard gizzard @s # dispose of the key we just made marker "UNLINK KEY" unlink_key --wait $keyid @s # check that a non-existent key ID fails correctly marker "CHECK CLEAR NON-EXISTENT KEY ID" read_key --fail $keyid expect_error ENOKEY print_key --fail $keyid expect_error ENOKEY pipe_key --fail $keyid expect_error ENOKEY echo "++++ FINISHED TEST: $result" >>$OUTPUTFILE # --- then report the results in the database --- toolbox_report_result $TEST $result keyutils-1.6.3/tests/keyctl/reading/noargs/000077500000000000000000000000001370111642500207315ustar00rootroot00000000000000keyutils-1.6.3/tests/keyctl/reading/noargs/runtest.sh000066400000000000000000000010121370111642500227630ustar00rootroot00000000000000#!/bin/bash . ../../../prepare.inc.sh . ../../../toolbox.inc.sh # ---- do the actual testing ---- result=PASS echo "++++ BEGINNING TEST" >$OUTPUTFILE marker "NO ARGS" expect_args_error keyctl read expect_args_error keyctl pipe expect_args_error keyctl print marker "TWO ARGS" expect_args_error keyctl read 0 0 expect_args_error keyctl pipe 0 0 expect_args_error keyctl print 0 0 echo "++++ FINISHED TEST: $result" >>$OUTPUTFILE # --- then report the results in the database --- toolbox_report_result $TEST $result keyutils-1.6.3/tests/keyctl/reading/valid/000077500000000000000000000000001370111642500205375ustar00rootroot00000000000000keyutils-1.6.3/tests/keyctl/reading/valid/runtest.sh000066400000000000000000000044361370111642500226060ustar00rootroot00000000000000#!/bin/bash . ../../../prepare.inc.sh . ../../../toolbox.inc.sh # ---- do the actual testing ---- result=PASS echo "++++ BEGINNING TEST" >$OUTPUTFILE # create a keyring and attach it to the session keyring marker "ADD KEYRING" create_keyring --new=keyringid wibble @s # stick a key in the keyring marker "ADD KEY" create_key --new=keyid user lizard gizzard $keyringid # check that the key is in the keyring marker "LIST KEYRING" list_keyring $keyringid expect_keyring_rlist rlist $keyid # read the contents of the key marker "PRINT KEY" print_key $keyid expect_payload payload "gizzard" # pipe the contents of the key and add a LF as the key doesn't have one marker "PIPE KEY" pipe_key $keyid echo >>$OUTPUTFILE expect_payload payload "gizzard" # read the key as hex marker "READ KEY" read_key $keyid expect_payload payload "67697a7a 617264" # read the contents of the keyring as hex and match it to the key ID marker "READ KEYRING" read_key $keyringid tmp=`printf %08x $keyid` if [ "$endian" = "LE" ] then tmp=`echo $tmp | sed 's/\(..\)\(..\)\(..\)\(..\)/\4\3\2\1/'` fi expect_payload payload $tmp # remove read permission from the key and try reading it again # - we should still have read permission because it's searchable in our # keyrings marker "REMOVE READ PERM" set_key_perm $keyid 0x3d0000 print_key $keyid expect_payload payload "gizzard" # remove search permission from the key as well # - we do not have read permission because it's no longer searchable in our # keyrings marker "REMOVE SEARCH PERM" set_key_perm $keyid 0x350000 print_key --fail $keyid expect_error EACCES # check that we can read it if we have to rely on possessor perms # - we should still have read permission because it's searchable in our # keyrings marker "CHECK POSSESSOR READ" set_key_perm $keyid 0x3d000000 print_key $keyid expect_payload payload "gizzard" # put read permission back again marker "REINSTATE READ PERM" set_key_perm $keyid 0x370000 print_key $keyid expect_payload payload "gizzard" # revoke the key marker "REVOKE KEY" revoke_key $keyid print_key --fail $keyid expect_error EKEYREVOKED # remove the keyring we added marker "UNLINK KEYRING" unlink_key $keyringid @s echo "++++ FINISHED TEST: $result" >>$OUTPUTFILE # --- then report the results in the database --- toolbox_report_result $TEST $result keyutils-1.6.3/tests/keyctl/requesting/000077500000000000000000000000001370111642500202155ustar00rootroot00000000000000keyutils-1.6.3/tests/keyctl/requesting/bad-args/000077500000000000000000000000001370111642500216755ustar00rootroot00000000000000keyutils-1.6.3/tests/keyctl/requesting/bad-args/runtest.sh000066400000000000000000000076241370111642500237460ustar00rootroot00000000000000#!/bin/bash . ../../../prepare.inc.sh . ../../../toolbox.inc.sh # ---- do the actual testing ---- result=PASS if [ $skip_install_required -eq 1 ] then echo "++++ SKIPPING TEST" >$OUTPUTFILE marker "SKIP BECAUSE TEST REQUIRES FULL INSTALL (for /sbin/request-key)" toolbox_report_result $TEST PASS exit 0 else echo "++++ BEGINNING TEST" >$OUTPUTFILE fi # check that an empty key type fails correctly marker "CHECK EMPTY KEY TYPE" request_key --fail "" debug:wibble expect_error EINVAL request_key --fail "" debug:wibble @p expect_error EINVAL request_key_callout --fail "" debug:wibble stuff expect_error EINVAL request_key_callout --fail "" debug:wibble stuff @p expect_error EINVAL prequest_key_callout --fail stuff "" debug:wibble expect_error EINVAL prequest_key_callout --fail stuff "" debug:wibble @p expect_error EINVAL # check that an unsupported key type fails correctly marker "CHECK UNSUPPORTED KEY TYPE" request_key --fail "lizardsgizzards" debug:wibble expect_error ENOKEY request_key --fail "lizardsgizzards" debug:wibble @p expect_error ENOKEY request_key_callout --fail "lizardsgizzards" debug:wibble stuff expect_error ENOKEY request_key_callout --fail "lizardsgizzards" debug:wibble stuff @p expect_error ENOKEY prequest_key_callout --fail stuff "lizardsgizzards" debug:wibble expect_error ENOKEY prequest_key_callout --fail stuff "lizardsgizzards" debug:wibble @p expect_error ENOKEY # check that an invalid key type fails correctly # - key types beginning with a dot are internal use only marker "CHECK INVALID KEY TYPE" request_key --fail ".user" debug:wibble expect_error EPERM request_key --fail ".user" debug:wibble @p expect_error EPERM request_key_callout --fail ".user" debug:wibble stuff expect_error EPERM request_key_callout --fail ".user" debug:wibble stuff @p expect_error EPERM prequest_key_callout --fail stuff ".user" debug:wibble expect_error EPERM prequest_key_callout --fail stuff ".user" debug:wibble @p expect_error EPERM # check that an maximum length invalid key type fails correctly marker "CHECK MAXLEN INVALID KEY TYPE" request_key --fail $maxtype debug:wibble expect_error ENOKEY request_key --fail $maxtype debug:wibble @p expect_error ENOKEY request_key_callout --fail $maxtype debug:wibble stuff expect_error ENOKEY request_key_callout --fail $maxtype debug:wibble stuff @p expect_error ENOKEY # check that an overlong key type fails correctly marker "CHECK OVERLONG KEY TYPE" request_key --fail a$maxtype debug:wibble expect_error EINVAL request_key --fail a$maxtype debug:wibble @p expect_error EINVAL request_key_callout --fail a$maxtype debug:wibble stuff expect_error EINVAL request_key_callout --fail a$maxtype debug:wibble stuff @p expect_error EINVAL # check that an max length key description works correctly marker "CHECK MAXLEN DESC" request_key --fail user $maxdesc expect_error ENOKEY # This doesn't work on MIPS earlier than 3.19 because of a kernel bug kver=`uname -r` kmch=`uname -m` if kernel_at_or_later_than 3.19 || [ "$kmch" != "mips" -a "$kmch" != "mips64" ] then # check that an overlong key description fails correctly marker "CHECK OVERLONG DESC" request_key --fail user a$maxdesc expect_error EINVAL fi # check that a max length callout info works correctly marker "CHECK MAXLEN CALLOUT" request_key_callout --fail user wibble $maxdesc @p expect_error ENOKEY # check that an overlong callout info fails correctly marker "CHECK OVERLONG CALLOUT" request_key_callout --fail user wibble a$maxcall expect_error EINVAL # check that a max length callout info works correctly marker "CHECK MAXLEN PIPED CALLOUT" prequest_key_callout --fail $maxcall user wibble @p expect_error ENOKEY # check that an overlong callout info fails correctly marker "CHECK OVERLONG PIPED CALLOUT" prequest_key_callout --fail a$maxcall user wibble expect_error EINVAL echo "++++ FINISHED TEST: $result" >>$OUTPUTFILE # --- then report the results in the database --- toolbox_report_result $TEST $result keyutils-1.6.3/tests/keyctl/requesting/noargs/000077500000000000000000000000001370111642500215065ustar00rootroot00000000000000keyutils-1.6.3/tests/keyctl/requesting/noargs/runtest.sh000066400000000000000000000017271370111642500235550ustar00rootroot00000000000000#!/bin/bash . ../../../prepare.inc.sh . ../../../toolbox.inc.sh # ---- do the actual testing ---- result=PASS if [ $skip_install_required -eq 1 ] then echo "++++ SKIPPING TEST" >$OUTPUTFILE marker "SKIP BECAUSE TEST REQUIRES FULL INSTALL (for /sbin/request-key)" toolbox_report_result $TEST PASS exit 0 else echo "++++ BEGINNING TEST" >$OUTPUTFILE fi marker "NO ARGS" expect_args_error keyctl request expect_args_error keyctl request2 expect_args_error keyctl prequest2 marker "ONE ARG" expect_args_error keyctl request 0 expect_args_error keyctl request2 0 expect_args_error keyctl prequest2 0 marker "TWO ARGS" expect_args_error keyctl request2 0 0 marker "FOUR ARGS" expect_args_error keyctl request 0 0 0 0 expect_args_error keyctl prequest2 0 0 0 0 marker "FIVE ARGS" expect_args_error keyctl request2 0 0 0 0 0 echo "++++ FINISHED TEST: $result" >>$OUTPUTFILE # --- then report the results in the database --- toolbox_report_result $TEST $result keyutils-1.6.3/tests/keyctl/requesting/piped/000077500000000000000000000000001370111642500213165ustar00rootroot00000000000000keyutils-1.6.3/tests/keyctl/requesting/piped/runtest.sh000066400000000000000000000052151370111642500233610ustar00rootroot00000000000000#!/bin/bash . ../../../prepare.inc.sh . ../../../toolbox.inc.sh # ---- do the actual testing ---- result=PASS if [ $skip_install_required -eq 1 ] then echo "++++ SKIPPING TEST" >$OUTPUTFILE marker "SKIP BECAUSE TEST REQUIRES FULL INSTALL (for /sbin/request-key)" toolbox_report_result $TEST PASS exit 0 else echo "++++ BEGINNING TEST" >$OUTPUTFILE fi set_gc_delay 10 # create a pair of keyrings to play in marker "CREATE KEYRINGS" create_keyring --new=keyringid "sandbox" @s # check that we can't yet request a non-existent key marker "CHECK REQUEST FAILS" request_key --fail user lizard $keyringid expect_error ENOKEY # add a user key to the first keyring marker "ADD USER KEY" create_key --new=keyid user lizard gizzard $keyringid # request the key marker "REQUEST KEY" request_key --old=$keyid user lizard # remove the key from the keyring marker "DETACH KEY FROM KEYRING" unlink_key $keyid $keyringid # request a key from /sbin/request-key to the session keyring marker "PIPED CALL OUT REQUEST KEY TO SESSION" prequest_key_callout --new=keyid gizzard user debug:lizard # should have appeared in the session keyring marker "CHECK ATTACHMENT TO SESSION KEYRING" list_keyring @s expect_keyring_rlist rlist $keyid # re-requesting should pick up that key again marker "REDO PIPED CALL OUT REQUEST KEY TO SESSION" prequest_key_callout --old=$keyid gizzard user debug:lizard # remove the key from the session # - it was installed twice # - once by request_key's keyring arg # - once from the instantiation call # but it will only have one link marker "DETACH KEY FROM SESSION" unlink_key --wait $keyid @s unlink_key --fail $keyid @s expect_error ENOKEY # request a key from /sbin/request-key to the keyring we made marker "PIPED CALL OUT REQUEST KEY TO KEYRING" prequest_key_callout --new=keyid gizzard user debug:lizard $keyringid # should have appeared once each in the sandbox and session keyrings marker "CHECK ATTACHMENT TO KEYRING" list_keyring $keyringid expect_keyring_rlist rlist $keyid marker "CHECK ATTACHMENT TO SESSION" list_keyring @s expect_keyring_rlist rlist $keyid # re-requesting should pick up that key again marker "REDO PIPED CALL OUT REQUEST KEY TO KEYRING" prequest_key_callout --old=$keyid gizzard user debug:lizard $keyringid # remove the key from the session marker "DETACH KEY" unlink_key $keyid $keyringid unlink_key --wait $keyid @s unlink_key --fail $keyid @s expect_error ENOKEY # remove the keyrings we added marker "UNLINK KEYRINGS" unlink_key $keyringid @s set_gc_delay $orig_gc_delay echo "++++ FINISHED TEST: $result" >>$OUTPUTFILE # --- then report the results in the database --- toolbox_report_result $TEST $result keyutils-1.6.3/tests/keyctl/requesting/valid/000077500000000000000000000000001370111642500213145ustar00rootroot00000000000000keyutils-1.6.3/tests/keyctl/requesting/valid/runtest.sh000066400000000000000000000052321370111642500233560ustar00rootroot00000000000000#!/bin/bash . ../../../prepare.inc.sh . ../../../toolbox.inc.sh # ---- do the actual testing ---- result=PASS if [ $skip_install_required -eq 1 ] then echo "++++ SKIPPING TEST" >$OUTPUTFILE marker "SKIP BECAUSE TEST REQUIRES FULL INSTALL (for /sbin/request-key)" toolbox_report_result $TEST PASS exit 0 else echo "++++ BEGINNING TEST" >$OUTPUTFILE fi set_gc_delay 10 # create a pair of keyrings to play in marker "CREATE KEYRINGS" create_keyring --new=keyringid "sandbox" @s # check that we can't yet request a non-existent key marker "CHECK REQUEST FAILS" request_key --fail user lizard $keyringid expect_error ENOKEY # add a user key to the first keyring marker "ADD USER KEY" create_key --new=keyid user lizard gizzard $keyringid # request the key marker "REQUEST KEY" request_key --old=$keyid user lizard # remove the key from the keyring marker "DETACH KEY FROM KEYRING" unlink_key $keyid $keyringid # request a key from /sbin/request-key to the session keyring marker "CALL OUT REQUEST KEY TO SESSION" request_key_callout --new=keyid user debug:lizard gizzard # should have appeared in the session keyring marker "CHECK ATTACHMENT TO SESSION KEYRING" list_keyring @s expect_keyring_rlist rlist $keyid # re-requesting should pick up that key again marker "REDO CALL OUT REQUEST KEY TO SESSION" request_key_callout --old=$keyid user debug:lizard gizzard # remove the key from the session # - it was installed twice # - once by request_key's keyring arg # - once from the instantiation call # but it will only have one link marker "DETACH KEY FROM SESSION" unlink_key --wait $keyid @s unlink_key --fail $keyid @s expect_error ENOKEY # request a key from /sbin/request-key to the keyring we made marker "CALL OUT REQUEST KEY TO KEYRING" request_key_callout --new=keyid user debug:lizard gizzard $keyringid check_notify -2 linked $keyringid $keyid # should have appeared once each in the sandbox and session keyrings marker "CHECK ATTACHMENT TO KEYRING" list_keyring $keyringid expect_keyring_rlist rlist $keyid marker "CHECK ATTACHMENT TO SESSION" list_keyring @s expect_keyring_rlist rlist $keyid # re-requesting should pick up that key again marker "REDO CALL OUT REQUEST KEY TO KEYRING" request_key_callout --old=$keyid user debug:lizard gizzard $keyringid # remove the key from the session marker "DETACH KEY" unlink_key $keyid $keyringid unlink_key --wait $keyid @s unlink_key --fail $keyid @s expect_error ENOKEY # remove the keyrings we added marker "UNLINK KEYRINGS" unlink_key $keyringid @s set_gc_delay $orig_gc_delay echo "++++ FINISHED TEST: $result" >>$OUTPUTFILE # --- then report the results in the database --- toolbox_report_result $TEST $result keyutils-1.6.3/tests/keyctl/restrict/000077500000000000000000000000001370111642500176665ustar00rootroot00000000000000keyutils-1.6.3/tests/keyctl/restrict/bad-args/000077500000000000000000000000001370111642500213465ustar00rootroot00000000000000keyutils-1.6.3/tests/keyctl/restrict/bad-args/runtest.sh000066400000000000000000000024321370111642500234070ustar00rootroot00000000000000#!/bin/bash . ../../../prepare.inc.sh . ../../../toolbox.inc.sh # ---- do the actual testing ---- if [ $have_restrict_keyring = 0 ] then toolbox_skip_test $TEST "SKIPPING DUE TO LACK OF KEYRING RESTRICTION" exit 0 fi result=PASS echo "++++ BEGINNING TEST" >$OUTPUTFILE # create a keyring for CA keys marker "ADD CA KEYRING" create_keyring --new=cakeyringid cakeyring @s # create a keyring marker "ADD KEYRING TO RESTRICT" create_keyring --new=restrictid restrict @s # invalid payload marker "INVALID EXTRA PARAMETER 1" restrict_keyring --fail $restrictid "asymmetric" "key_or_keyring:$cakeyringid:bad_param" marker "INVALID EXTRA PARAMETER 2" restrict_keyring --fail $restrictid "asymmetric" "builtin_trusted:bad_param" marker "INVALID RESTRICT METHOD" restrict_keyring --fail $restrictid "asymmetric" "no_such_method:$cakeyringid" marker "INVALID KEY TYPE" restrict_keyring --fail $restrictid "not_a_key_type" "builtin_trusted" marker "INVALID KEY ID" restrict_keyring --fail $restrictid "asymmetric" "key_or_keyring:abcxyz" # invalid key option marker "USE KEY ID 0 FOR KEYRING" restrict_keyring --fail $restrictid "asymmetric" "key_or_keyring:0" echo "++++ FINISHED TEST: $result" >>$OUTPUTFILE # --- then report the results in the database --- toolbox_report_result $TEST $result keyutils-1.6.3/tests/keyctl/restrict/valid/000077500000000000000000000000001370111642500207655ustar00rootroot00000000000000keyutils-1.6.3/tests/keyctl/restrict/valid/runtest.sh000066400000000000000000000763751370111642500230470ustar00rootroot00000000000000#!/bin/bash . ../../../prepare.inc.sh . ../../../toolbox.inc.sh if [ $have_restrict_keyring = 0 ] then toolbox_skip_test $TEST "SKIPPING DUE TO LACK OF KEYRING RESTRICTION" exit 0 fi # ---- certs ---- # Note: 2044-03-06 expiration # Root CA 1 cacert1="\x30\x82\x03\xac\x30\x82\x02\x94\xa0\x03\x02\x01\x02\x02\x09\x00" cacert1+="\x8d\x38\x41\x1b\x39\xdd\x00\xf8\x30\x0d\x06\x09\x2a\x86\x48\x86" cacert1+="\xf7\x0d\x01\x01\x0b\x05\x00\x30\x41\x31\x0d\x30\x0b\x06\x03\x55" cacert1+="\x04\x0a\x0c\x04\x4f\x72\x67\x31\x31\x10\x30\x0e\x06\x03\x55\x04" cacert1+="\x03\x0c\x07\x49\x73\x73\x75\x65\x72\x31\x31\x1e\x30\x1c\x06\x09" cacert1+="\x2a\x86\x48\x86\xf7\x0d\x01\x09\x01\x16\x0f\x63\x61\x31\x40\x65" cacert1+="\x78\x61\x6d\x70\x6c\x65\x2e\x63\x6f\x6d\x30\x1e\x17\x0d\x31\x36" cacert1+="\x31\x30\x31\x39\x32\x32\x35\x34\x32\x35\x5a\x17\x0d\x34\x34\x30" cacert1+="\x33\x30\x36\x32\x32\x35\x34\x32\x35\x5a\x30\x41\x31\x0d\x30\x0b" cacert1+="\x06\x03\x55\x04\x0a\x0c\x04\x4f\x72\x67\x31\x31\x10\x30\x0e\x06" cacert1+="\x03\x55\x04\x03\x0c\x07\x49\x73\x73\x75\x65\x72\x31\x31\x1e\x30" cacert1+="\x1c\x06\x09\x2a\x86\x48\x86\xf7\x0d\x01\x09\x01\x16\x0f\x63\x61" cacert1+="\x31\x40\x65\x78\x61\x6d\x70\x6c\x65\x2e\x63\x6f\x6d\x30\x82\x01" cacert1+="\x22\x30\x0d\x06\x09\x2a\x86\x48\x86\xf7\x0d\x01\x01\x01\x05\x00" cacert1+="\x03\x82\x01\x0f\x00\x30\x82\x01\x0a\x02\x82\x01\x01\x00\xc4\x38" cacert1+="\x65\x78\x96\x72\x2b\x81\x11\x01\xea\xc0\x30\xe9\xfd\x8f\xa4\x34" cacert1+="\x49\x0e\x39\x94\x4c\x11\x6f\xa2\x95\xe3\x93\xb9\xdd\x8c\x7f\x8c" cacert1+="\xb5\xad\xe3\x62\x08\x4f\x8d\x52\x64\xfa\xcb\xdb\xe3\x3b\x58\xc3" cacert1+="\x71\x3d\x5e\xa3\x4f\xee\xcc\xe4\x7f\x33\xf6\xda\x76\x36\x49\x3b" cacert1+="\x96\x87\xdb\x24\x77\xf7\x03\xd0\x9b\x58\x4c\x28\x74\x86\x7e\xc2" cacert1+="\xd2\xea\x34\x67\xdc\xce\x16\x67\xef\xa6\x1e\xbf\xd5\xe1\x55\x0a" cacert1+="\xa3\x2f\x3b\xe5\x3d\xd6\xdb\x5c\xe8\x6b\xb9\x09\x16\xbe\x5e\x39" cacert1+="\xdd\xfb\xd6\x60\xfd\x41\x7b\xfa\xe5\x22\x34\x73\xcd\xcd\x71\xd0" cacert1+="\xca\xbc\xdf\x4d\x60\xb0\x16\xf2\x66\xe0\x79\x1a\xb1\x79\xed\xe2" cacert1+="\xa8\x21\xec\x7a\xc0\x65\x72\x04\xae\x03\x6a\x34\x8f\x52\x1b\x7d" cacert1+="\x13\xd6\x01\xb4\x12\x3f\xc0\x00\x9d\x7d\x47\xf2\x2b\x7a\x34\x6c" cacert1+="\xac\x70\xf0\xcc\xd7\x69\x36\x4e\x77\x8e\x7b\xdb\xa9\xeb\xc7\xfc" cacert1+="\x47\x2c\x74\xad\x4c\x03\x74\xe1\xa6\x60\x9f\xe1\xc5\xf1\xb4\xa4" cacert1+="\x65\xbf\xb9\x74\x9c\x22\x36\x8c\xd5\x9e\xef\xdd\x23\x9d\x49\x37" cacert1+="\x8d\x7a\xdb\xf1\x63\x23\x7e\x06\x8e\x96\x66\x2f\xbd\x5e\xf2\x53" cacert1+="\xb4\xc7\xb3\x0c\xb2\x85\x46\xf5\x4c\xec\x92\x38\x5d\x33\x02\x03" cacert1+="\x01\x00\x01\xa3\x81\xa6\x30\x81\xa3\x30\x0f\x06\x03\x55\x1d\x13" cacert1+="\x04\x08\x30\x06\x01\x01\xff\x02\x01\x00\x30\x1d\x06\x03\x55\x1d" cacert1+="\x0e\x04\x16\x04\x14\xa6\x90\x37\x33\x55\x73\x58\xcd\x8a\x4c\xaa" cacert1+="\xcb\x4a\xe7\x54\x0e\x00\x81\x7e\xe8\x30\x71\x06\x03\x55\x1d\x23" cacert1+="\x04\x6a\x30\x68\x80\x14\xa6\x90\x37\x33\x55\x73\x58\xcd\x8a\x4c" cacert1+="\xaa\xcb\x4a\xe7\x54\x0e\x00\x81\x7e\xe8\xa1\x45\xa4\x43\x30\x41" cacert1+="\x31\x0d\x30\x0b\x06\x03\x55\x04\x0a\x0c\x04\x4f\x72\x67\x31\x31" cacert1+="\x10\x30\x0e\x06\x03\x55\x04\x03\x0c\x07\x49\x73\x73\x75\x65\x72" cacert1+="\x31\x31\x1e\x30\x1c\x06\x09\x2a\x86\x48\x86\xf7\x0d\x01\x09\x01" cacert1+="\x16\x0f\x63\x61\x31\x40\x65\x78\x61\x6d\x70\x6c\x65\x2e\x63\x6f" cacert1+="\x6d\x82\x09\x00\x8d\x38\x41\x1b\x39\xdd\x00\xf8\x30\x0d\x06\x09" cacert1+="\x2a\x86\x48\x86\xf7\x0d\x01\x01\x0b\x05\x00\x03\x82\x01\x01\x00" cacert1+="\x85\x84\x97\x71\xd8\x1a\xb5\xc0\x90\xbb\x95\x14\x19\xd7\x76\x30" cacert1+="\xf8\x42\x02\xad\x7b\x1f\x73\xbe\xf4\x78\x9d\x87\xb1\x99\xcf\xc7" cacert1+="\x59\xb4\x2f\xf7\x8a\xda\xbb\x07\xa1\x76\x29\x30\x4e\x41\x0f\x7e" cacert1+="\x97\x9c\xba\xfd\xf4\xc5\x08\x3c\x14\xb0\x7a\x6f\xf1\x67\xb2\xf9" cacert1+="\xb1\x46\xc8\x83\xfd\xa6\x4f\xc6\x25\x76\xf2\xc1\x11\x92\xba\xfb" cacert1+="\x25\x85\xe4\x1b\xc6\x92\x79\x63\xc0\x8a\xe7\xfb\x48\x69\x4d\x83" cacert1+="\x20\xb8\x3d\x8a\x55\xfa\x6d\xe9\x7b\xd1\x96\x75\x0a\x0f\x63\x53" cacert1+="\x01\x00\xf7\xc3\x28\xa1\xd8\x9e\x41\x6e\x52\xb9\x00\x43\x09\xf2" cacert1+="\x91\xb7\x06\x5f\xd2\x0c\x42\x03\x67\xd6\x77\xb2\xce\x96\xd4\x73" cacert1+="\x58\x59\xd9\xf8\x47\xb7\xc7\x23\x96\x65\xeb\xdf\x55\x1b\x1f\xc7" cacert1+="\xa3\x7c\x7a\x2a\x1b\x95\xec\xf8\xa0\x26\xba\x81\x4b\x94\xb6\x5f" cacert1+="\xa9\x7d\xb8\x0c\x46\x11\x3a\x70\x3c\xd5\x7c\x60\xd2\x38\x42\x0f" cacert1+="\xe1\x70\x69\xdc\x4f\x5a\xf9\x65\x45\x97\xbf\x49\xe1\xd2\x59\x5c" cacert1+="\x8a\xf4\xc4\xe0\x72\xb7\x2d\x4e\xbd\xe6\x69\x9d\x68\x8c\x9c\xfe" cacert1+="\x4a\xf7\xc0\x0d\xc9\xb9\x92\x50\xff\x5c\x9b\xb9\x9a\x51\xdd\x6c" cacert1+="\x91\xc7\xa9\x88\x83\xcc\xed\x49\xe7\xcf\x41\xe1\xef\x76\x55\x62" # Root CA 2 cacert2="\x30\x82\x03\xac\x30\x82\x02\x94\xa0\x03\x02\x01\x02\x02\x09\x00" cacert2+="\xa7\x75\xd3\x8a\xe3\x8d\x8e\x3c\x30\x0d\x06\x09\x2a\x86\x48\x86" cacert2+="\xf7\x0d\x01\x01\x0b\x05\x00\x30\x41\x31\x0d\x30\x0b\x06\x03\x55" cacert2+="\x04\x0a\x0c\x04\x4f\x72\x67\x32\x31\x10\x30\x0e\x06\x03\x55\x04" cacert2+="\x03\x0c\x07\x49\x73\x73\x75\x65\x72\x32\x31\x1e\x30\x1c\x06\x09" cacert2+="\x2a\x86\x48\x86\xf7\x0d\x01\x09\x01\x16\x0f\x63\x61\x32\x40\x65" cacert2+="\x78\x61\x6d\x70\x6c\x65\x2e\x63\x6f\x6d\x30\x1e\x17\x0d\x31\x36" cacert2+="\x31\x30\x31\x39\x32\x32\x35\x34\x32\x35\x5a\x17\x0d\x34\x34\x30" cacert2+="\x33\x30\x36\x32\x32\x35\x34\x32\x35\x5a\x30\x41\x31\x0d\x30\x0b" cacert2+="\x06\x03\x55\x04\x0a\x0c\x04\x4f\x72\x67\x32\x31\x10\x30\x0e\x06" cacert2+="\x03\x55\x04\x03\x0c\x07\x49\x73\x73\x75\x65\x72\x32\x31\x1e\x30" cacert2+="\x1c\x06\x09\x2a\x86\x48\x86\xf7\x0d\x01\x09\x01\x16\x0f\x63\x61" cacert2+="\x32\x40\x65\x78\x61\x6d\x70\x6c\x65\x2e\x63\x6f\x6d\x30\x82\x01" cacert2+="\x22\x30\x0d\x06\x09\x2a\x86\x48\x86\xf7\x0d\x01\x01\x01\x05\x00" cacert2+="\x03\x82\x01\x0f\x00\x30\x82\x01\x0a\x02\x82\x01\x01\x00\xa5\xdf" cacert2+="\x33\xab\xa3\xb0\x60\xb5\x8e\x7f\xdf\x58\xfd\x71\xa0\x39\x40\x7a" cacert2+="\x4f\xf6\xc8\xec\xbe\xa7\x18\x4b\x4d\xd3\x73\x52\xca\xfa\xee\xa0" cacert2+="\x06\x21\xd8\x52\xf5\x40\x62\xc1\x4e\xd3\x6d\x9c\xc3\x12\x57\x78" cacert2+="\x15\x68\x67\x61\x4e\xfd\xfa\x71\xb6\xdc\xf9\x77\x36\x8f\x51\x1c" cacert2+="\x0a\x19\x42\x8a\x95\x6c\xf8\x2f\xd2\x1a\xe7\x39\x4c\xcd\x07\x62" cacert2+="\x12\x36\x8a\x5b\x97\x9b\x7a\x94\xce\x4c\x99\x36\x88\xc6\x17\x2c" cacert2+="\x91\xcd\x95\xa1\x48\x76\x9a\x22\xf8\x87\x84\xde\xc6\xae\x03\xa9" cacert2+="\x34\x93\xd8\xb3\x4c\x5f\xfb\x8b\x12\x0a\xc5\xad\xa4\x40\x56\xb6" cacert2+="\x44\x54\x50\xcb\x57\xe0\xb3\x77\x9d\xe2\x10\xa6\xb8\xfc\x21\x67" cacert2+="\x90\x61\x30\xbe\xfc\x84\xb3\x3a\x1f\x31\x1a\x8a\xc6\x37\x29\x3a" cacert2+="\x82\x8a\x1a\xa0\xcb\xa0\x65\x8a\x0e\x7d\xae\x03\x5c\x35\xa4\x64" cacert2+="\x5a\x79\xdd\xe1\xf7\x87\x91\xac\xe1\x67\x76\x48\x17\x05\x57\x01" cacert2+="\xa6\xf9\x36\x09\x3c\x0e\xc2\xa3\xf9\xfb\xbb\x4d\x05\xf3\x92\x42" cacert2+="\xf5\x4b\x9b\x2c\xab\xd5\xe8\x7c\x0a\x4a\xe6\x85\xba\x95\x28\xc1" cacert2+="\x04\x46\x94\x15\x1a\xe3\x61\xd5\x0b\x17\x50\xa7\x92\x98\xaa\x6a" cacert2+="\xe8\x91\x91\xae\x02\x6e\x35\x4b\x41\xcb\xbe\x02\xad\xb1\x02\x03" cacert2+="\x01\x00\x01\xa3\x81\xa6\x30\x81\xa3\x30\x0f\x06\x03\x55\x1d\x13" cacert2+="\x04\x08\x30\x06\x01\x01\xff\x02\x01\x00\x30\x1d\x06\x03\x55\x1d" cacert2+="\x0e\x04\x16\x04\x14\x44\xfb\x94\xd9\x3d\x4a\x0e\x82\x59\xc6\x90" cacert2+="\xa1\x38\xfa\x0e\x8c\xc4\x4a\x4f\x77\x30\x71\x06\x03\x55\x1d\x23" cacert2+="\x04\x6a\x30\x68\x80\x14\x44\xfb\x94\xd9\x3d\x4a\x0e\x82\x59\xc6" cacert2+="\x90\xa1\x38\xfa\x0e\x8c\xc4\x4a\x4f\x77\xa1\x45\xa4\x43\x30\x41" cacert2+="\x31\x0d\x30\x0b\x06\x03\x55\x04\x0a\x0c\x04\x4f\x72\x67\x32\x31" cacert2+="\x10\x30\x0e\x06\x03\x55\x04\x03\x0c\x07\x49\x73\x73\x75\x65\x72" cacert2+="\x32\x31\x1e\x30\x1c\x06\x09\x2a\x86\x48\x86\xf7\x0d\x01\x09\x01" cacert2+="\x16\x0f\x63\x61\x32\x40\x65\x78\x61\x6d\x70\x6c\x65\x2e\x63\x6f" cacert2+="\x6d\x82\x09\x00\xa7\x75\xd3\x8a\xe3\x8d\x8e\x3c\x30\x0d\x06\x09" cacert2+="\x2a\x86\x48\x86\xf7\x0d\x01\x01\x0b\x05\x00\x03\x82\x01\x01\x00" cacert2+="\x62\xf7\xbc\xd7\x49\x2d\xa2\x47\x8b\x28\xb3\xd4\x3e\xe6\x76\x00" cacert2+="\x12\xe6\x15\xe2\xf7\xa5\x20\x0f\xcf\xbd\xa9\x8a\x0f\x97\x38\x57" cacert2+="\xac\x69\x5f\x76\x90\xdb\x52\x0a\x55\xbe\x6a\x34\xb1\x3e\xef\x45" cacert2+="\xed\x0a\x55\xe9\x46\xdc\x2c\xe2\xd3\x24\x7e\x3b\x10\x38\x72\x38" cacert2+="\x98\xae\xda\x55\xe0\x33\x7f\x86\x56\xbb\x12\x7a\x5b\x44\x4b\x8d" cacert2+="\xf5\xd3\xfb\x83\x1b\x07\x08\xab\x0f\x95\x07\x98\x60\xa1\x6e\x6c" cacert2+="\x0f\xb8\xa2\xe1\x74\xf4\x43\xd3\x91\x8e\xa0\x40\xea\x9b\x54\x3d" cacert2+="\x71\x1f\x75\xb4\x59\x67\x47\x95\xeb\x2e\xdc\x37\x1d\xd2\xd8\xe6" cacert2+="\xe5\x3a\x86\x60\xa4\x2a\xb4\x6e\x7e\x34\x09\x2b\x42\x0e\xe7\x3b" cacert2+="\x83\x5d\xdd\xee\xc9\xa4\x6c\x65\x49\x0b\x59\x1b\x46\xf1\x46\x2e" cacert2+="\xf7\x37\x0f\x06\xa1\x85\x33\x38\xee\x11\x89\x62\x3f\xf6\x42\x5e" cacert2+="\x1b\x6c\xfd\xcd\x4b\xa0\x8a\x71\x74\x27\xef\xbb\x6e\xbe\x68\xfc" cacert2+="\xb6\xcd\x88\xfe\x0e\x92\xec\xfe\x60\xe1\x26\xce\xee\x0a\x48\x6c" cacert2+="\x93\x1f\x85\x9f\xd8\x81\xa0\xd7\xfc\x35\xe6\xad\x63\x97\xf5\x12" cacert2+="\x2f\xdb\xf6\x38\x54\x0e\x6e\x7d\xcc\x88\x64\xa9\x4f\xc1\x6d\x60" cacert2+="\x03\x5d\x4c\x72\x6a\xa3\xf1\x29\xaa\x62\xf4\xa1\x04\x38\x78\xcd" # Intermediate CA (signed by CA 2) intcert="\x30\x82\x03\xa9\x30\x82\x02\x91\xa0\x03\x02\x01\x02\x02\x09\x00" intcert+="\xfe\x1e\xe6\xa8\x4e\x42\xc4\x72\x30\x0d\x06\x09\x2a\x86\x48\x86" intcert+="\xf7\x0d\x01\x01\x0b\x05\x00\x30\x41\x31\x0d\x30\x0b\x06\x03\x55" intcert+="\x04\x0a\x0c\x04\x4f\x72\x67\x32\x31\x10\x30\x0e\x06\x03\x55\x04" intcert+="\x03\x0c\x07\x49\x73\x73\x75\x65\x72\x32\x31\x1e\x30\x1c\x06\x09" intcert+="\x2a\x86\x48\x86\xf7\x0d\x01\x09\x01\x16\x0f\x63\x61\x32\x40\x65" intcert+="\x78\x61\x6d\x70\x6c\x65\x2e\x63\x6f\x6d\x30\x1e\x17\x0d\x31\x36" intcert+="\x31\x30\x31\x39\x32\x32\x35\x34\x32\x35\x5a\x17\x0d\x34\x34\x30" intcert+="\x33\x30\x36\x32\x32\x35\x34\x32\x35\x5a\x30\x41\x31\x0d\x30\x0b" intcert+="\x06\x03\x55\x04\x0a\x0c\x04\x4f\x72\x67\x32\x31\x10\x30\x0e\x06" intcert+="\x03\x55\x04\x03\x0c\x07\x49\x73\x73\x75\x65\x72\x32\x31\x1e\x30" intcert+="\x1c\x06\x09\x2a\x86\x48\x86\xf7\x0d\x01\x09\x01\x16\x0f\x63\x61" intcert+="\x32\x40\x65\x78\x61\x6d\x70\x6c\x65\x2e\x63\x6f\x6d\x30\x82\x01" intcert+="\x22\x30\x0d\x06\x09\x2a\x86\x48\x86\xf7\x0d\x01\x01\x01\x05\x00" intcert+="\x03\x82\x01\x0f\x00\x30\x82\x01\x0a\x02\x82\x01\x01\x00\xe2\x07" intcert+="\xfb\x98\x1b\x29\xd7\x82\x9c\x64\xce\x81\xfb\x8b\x2d\xe1\x44\xa0" intcert+="\x0e\x2e\xc9\xb6\xb8\x16\x7d\x9a\xcf\xa4\xb7\x21\x2f\xdc\x4c\x79" intcert+="\xfe\xe4\x34\xc8\x94\x93\xdf\x5a\xdd\x94\x33\xf8\xda\x0d\x17\xb7" intcert+="\x0a\x4d\x82\x72\x9a\x6f\xfa\xac\x3f\x4a\x1b\x78\x1a\x99\xa3\x24" intcert+="\x66\x0b\xc4\x72\x2a\xe0\xb4\xbd\xd5\xa1\x06\xbf\xdb\xd0\xdf\x8b" intcert+="\x15\xee\xa9\x18\x50\x7a\x83\x53\x21\xf7\xbb\x4b\xce\x57\xe8\x8b" intcert+="\x02\x9d\x3a\x73\x3e\x5d\x67\xa5\x11\xde\xec\xc2\x4e\xbe\xfe\x09" intcert+="\x40\xfd\x22\xb5\x2e\xb2\x2b\xe7\x07\x81\x0c\x72\xf3\xbf\x22\x55" intcert+="\xaa\xb9\x02\xb9\x48\x8c\x89\xb6\xf3\x5d\x27\x9a\xd5\xc2\x47\xf9" intcert+="\xb9\x0c\xb5\x90\xbf\x8b\xee\xd8\x8c\x3d\x2d\xbf\xa1\xb0\xcf\xe2" intcert+="\xd9\x44\x9b\x88\x66\xb3\x6e\xec\xe6\xaa\x2c\x67\x2e\x6f\x2b\x23" intcert+="\xd6\xe2\xa1\xb1\x7a\x0d\xb1\x50\x30\xe4\x22\xec\xbf\x87\x28\xcc" intcert+="\xa0\x73\x42\x4a\xdc\x5d\x2b\x37\x7e\x43\x63\x59\x01\xaa\x9e\xc4" intcert+="\x4b\xfa\x05\x38\x4d\xc2\xde\x41\xb1\x60\xd1\x4b\xfd\x89\x9e\xe0" intcert+="\xdf\xff\x21\x91\x1c\x6f\xba\x10\xba\x15\xe3\x44\xf0\x1f\xd8\x43" intcert+="\x2e\x03\xc7\xf3\x51\xa3\x36\xfd\x25\x71\x4b\x87\x65\x5b\x02\x03" intcert+="\x01\x00\x01\xa3\x81\xa3\x30\x81\xa0\x30\x0c\x06\x03\x55\x1d\x13" intcert+="\x04\x05\x30\x03\x01\x01\xff\x30\x1d\x06\x03\x55\x1d\x0e\x04\x16" intcert+="\x04\x14\xf5\x71\x46\x2e\x96\x8c\x27\x3e\x47\xef\xba\x8a\x2c\x1c" intcert+="\xb5\x15\x88\xa7\x24\x14\x30\x71\x06\x03\x55\x1d\x23\x04\x6a\x30" intcert+="\x68\x80\x14\x44\xfb\x94\xd9\x3d\x4a\x0e\x82\x59\xc6\x90\xa1\x38" intcert+="\xfa\x0e\x8c\xc4\x4a\x4f\x77\xa1\x45\xa4\x43\x30\x41\x31\x0d\x30" intcert+="\x0b\x06\x03\x55\x04\x0a\x0c\x04\x4f\x72\x67\x32\x31\x10\x30\x0e" intcert+="\x06\x03\x55\x04\x03\x0c\x07\x49\x73\x73\x75\x65\x72\x32\x31\x1e" intcert+="\x30\x1c\x06\x09\x2a\x86\x48\x86\xf7\x0d\x01\x09\x01\x16\x0f\x63" intcert+="\x61\x32\x40\x65\x78\x61\x6d\x70\x6c\x65\x2e\x63\x6f\x6d\x82\x09" intcert+="\x00\xa7\x75\xd3\x8a\xe3\x8d\x8e\x3c\x30\x0d\x06\x09\x2a\x86\x48" intcert+="\x86\xf7\x0d\x01\x01\x0b\x05\x00\x03\x82\x01\x01\x00\x53\xb3\x9a" intcert+="\xfa\x63\xdb\x3e\x20\x7b\x8a\xa3\xc0\x8e\x31\x18\x80\x6a\x75\x8b" intcert+="\x9c\xdc\x34\xfb\xc6\xd2\x52\x4b\x60\x17\x33\x72\x62\xa4\xf8\xfd" intcert+="\x7d\x19\x52\x88\x25\x5b\xbe\x86\x46\x75\x8b\x77\x21\xe7\x47\x98" intcert+="\xf5\x8b\xbc\x09\x1a\x33\xa8\xdf\xdb\x98\x5a\x92\x40\x74\x3e\x65" intcert+="\xd8\x9e\x56\x65\xbb\x62\x26\xa7\x32\xe2\x4b\x03\xd5\x16\xbe\xb6" intcert+="\xa7\x23\xb2\xe7\x36\x4f\x11\x05\xd1\x1c\x12\x70\x35\x70\xcb\xe6" intcert+="\x99\xf8\x4b\x3a\x87\x27\xe5\xe6\x08\x5f\x06\x7e\x83\x85\x9a\x34" intcert+="\xc2\x8a\xfa\x52\x82\xf7\xbd\x71\xac\xc9\xec\x9b\x9a\x70\xa6\x6b" intcert+="\x2e\xee\x62\xa3\x0c\x07\xd2\xbd\x8a\xfc\x8a\x4b\xe9\x4a\xe9\x11" intcert+="\xdd\x6e\xbb\x94\xb8\x9b\xc7\x79\x4d\x82\xdd\x0f\x62\x1d\x84\xf7" intcert+="\x00\xec\x37\xe5\x56\x5f\x39\x18\x85\x0e\xef\x20\xdf\x3f\x97\x96" intcert+="\x03\x84\x50\x21\x9d\xe0\x00\x44\x19\x82\x58\x6b\x79\xfa\x32\x34" intcert+="\x65\x4b\xed\x36\xae\x1a\xd8\x78\xae\x59\xf0\xb8\xb7\xb0\xe3\xb4" intcert+="\x23\x71\xe7\xda\x18\xff\x6d\x6e\x3b\x8b\xc8\x13\x52\x1c\xc5\xff" intcert+="\x66\xfd\xe1\x7a\x28\xac\x3e\xe5\x0e\x80\x03\x91\xce\x30\x2b\x98" intcert+="\x3b\x71\x2f\x37\x80\xf1\x29\xbc\xdb\x42\xa1\x6e\xd0" # End entity cert (signed by CA 2) signed="\x30\x82\x03\xa3\x30\x82\x02\x8b\xa0\x03\x02\x01\x02\x02\x09\x00" signed+="\xfe\x1e\xe6\xa8\x4e\x42\xc4\x73\x30\x0d\x06\x09\x2a\x86\x48\x86" signed+="\xf7\x0d\x01\x01\x0b\x05\x00\x30\x41\x31\x0d\x30\x0b\x06\x03\x55" signed+="\x04\x0a\x0c\x04\x4f\x72\x67\x32\x31\x10\x30\x0e\x06\x03\x55\x04" signed+="\x03\x0c\x07\x49\x73\x73\x75\x65\x72\x32\x31\x1e\x30\x1c\x06\x09" signed+="\x2a\x86\x48\x86\xf7\x0d\x01\x09\x01\x16\x0f\x63\x61\x32\x40\x65" signed+="\x78\x61\x6d\x70\x6c\x65\x2e\x63\x6f\x6d\x30\x1e\x17\x0d\x31\x36" signed+="\x31\x30\x31\x39\x32\x32\x35\x34\x32\x35\x5a\x17\x0d\x34\x34\x30" signed+="\x33\x30\x36\x32\x32\x35\x34\x32\x35\x5a\x30\x3e\x31\x0c\x30\x0a" signed+="\x06\x03\x55\x04\x0a\x0c\x03\x4f\x72\x67\x31\x0f\x30\x0d\x06\x03" signed+="\x55\x04\x03\x0c\x06\x49\x73\x73\x75\x65\x72\x31\x1d\x30\x1b\x06" signed+="\x09\x2a\x86\x48\x86\xf7\x0d\x01\x09\x01\x16\x0e\x65\x65\x40\x65" signed+="\x78\x61\x6d\x70\x6c\x65\x2e\x63\x6f\x6d\x30\x82\x01\x22\x30\x0d" signed+="\x06\x09\x2a\x86\x48\x86\xf7\x0d\x01\x01\x01\x05\x00\x03\x82\x01" signed+="\x0f\x00\x30\x82\x01\x0a\x02\x82\x01\x01\x00\xa2\xc7\x25\x7d\x83" signed+="\xb3\xbb\x04\x04\xae\xc1\x53\x85\xdc\x61\x4f\xb9\x5c\x80\x03\x86" signed+="\x4c\x1b\xbe\x57\x39\xb0\x43\x09\x37\xce\x5d\x98\xcc\x74\x38\xa8" signed+="\xf6\x6f\x6a\x9e\x3d\xd6\x88\x62\x61\x35\x7f\x85\x73\x06\x48\x1e" signed+="\x65\x69\xc3\xf4\xf3\x6e\xa2\x79\xfa\x12\xd0\x80\xb4\x11\xc6\x8f" signed+="\x13\xb5\xc4\x42\xe0\x22\x54\x4a\x46\x47\xaf\x61\xcb\x35\xd2\xea" signed+="\xe9\x5e\x0d\x0e\xc1\x36\x72\x6a\xd3\xa0\x4e\xe9\xf1\x9e\xbd\xbd" signed+="\x21\xd6\x8d\x0b\x24\x7a\x8b\xc1\xcc\x52\x48\xc9\xb5\x4f\x1c\xe0" signed+="\xaf\xe3\x8b\x24\xbb\x34\x9f\x8f\x03\x13\xe8\x2e\xee\xd4\xda\x17" signed+="\x25\x3f\x2d\xf3\x7e\x33\x3f\x97\x42\xef\xaf\x4c\x35\xb8\x02\x60" signed+="\xc0\x4f\x20\xbe\x97\xb7\xd3\xc3\x38\x73\x14\x7d\x68\x2a\xab\x04" signed+="\x96\x81\xde\xe6\x5a\x03\x1e\xd6\x07\xe8\x0a\x38\xc0\xf0\x2b\x54" signed+="\xb2\x9b\xbd\x54\x72\x8e\x97\x76\x5e\x4c\x80\xb8\x19\xf8\x69\x17" signed+="\x99\x41\xd9\x61\xb5\x9d\x4c\x8d\xbb\x19\x5f\x39\x7e\xc9\x19\x8d" signed+="\xdc\xa4\x21\xf1\x32\xfe\x89\x9a\xa3\x92\xe5\x76\x73\x64\x67\x29" signed+="\x34\x4a\x31\x02\xaa\x35\xaf\x88\x06\x0b\x63\x4d\xe4\xa2\x1f\xaa" signed+="\x48\x9f\x85\xf5\xc4\xd4\x03\x52\x29\xb7\x51\x02\x03\x01\x00\x01" signed+="\xa3\x81\xa0\x30\x81\x9d\x30\x09\x06\x03\x55\x1d\x13\x04\x02\x30" signed+="\x00\x30\x1d\x06\x03\x55\x1d\x0e\x04\x16\x04\x14\xfc\x91\xdf\xb8" signed+="\x99\x8a\x5c\x07\xee\xb6\x32\xcc\x79\x0b\x31\x0a\x3a\xca\x65\x23" signed+="\x30\x71\x06\x03\x55\x1d\x23\x04\x6a\x30\x68\x80\x14\x44\xfb\x94" signed+="\xd9\x3d\x4a\x0e\x82\x59\xc6\x90\xa1\x38\xfa\x0e\x8c\xc4\x4a\x4f" signed+="\x77\xa1\x45\xa4\x43\x30\x41\x31\x0d\x30\x0b\x06\x03\x55\x04\x0a" signed+="\x0c\x04\x4f\x72\x67\x32\x31\x10\x30\x0e\x06\x03\x55\x04\x03\x0c" signed+="\x07\x49\x73\x73\x75\x65\x72\x32\x31\x1e\x30\x1c\x06\x09\x2a\x86" signed+="\x48\x86\xf7\x0d\x01\x09\x01\x16\x0f\x63\x61\x32\x40\x65\x78\x61" signed+="\x6d\x70\x6c\x65\x2e\x63\x6f\x6d\x82\x09\x00\xa7\x75\xd3\x8a\xe3" signed+="\x8d\x8e\x3c\x30\x0d\x06\x09\x2a\x86\x48\x86\xf7\x0d\x01\x01\x0b" signed+="\x05\x00\x03\x82\x01\x01\x00\x36\x04\xff\x32\x8c\x5e\x7b\x2d\x99" signed+="\x2e\x84\x2f\xae\xed\x82\x96\x99\xe1\x18\xe0\x8c\xe9\x61\x3c\x0f" signed+="\xb1\xd7\x53\x5e\x24\x84\xe7\xe9\x19\xaa\xfe\xed\x21\x82\x3b\x6c" signed+="\xf4\xaa\xe9\x0a\x84\x88\x84\x1a\x46\xc7\xc8\x00\x3f\x94\x86\x2c" signed+="\xc5\x28\xa3\xac\xbd\x8a\x6f\x53\x38\x7f\x06\x12\x51\xbc\x1b\x4d" signed+="\x2d\xcb\x63\x65\x4b\x74\x42\x4d\xc8\xd6\x56\x03\xfe\x81\x9b\x52" signed+="\x3a\xc8\xb7\xcc\xd0\x03\x85\xad\x30\x7c\x3d\x73\xd1\x06\x16\x70" signed+="\x4a\xcc\x15\xa4\x83\xcf\x54\x0f\xd7\xab\x9a\xf0\xb9\x39\x80\x06" signed+="\x7f\x75\x45\x2e\xec\x76\xb2\xbd\xb8\xfd\xe3\x38\xdb\x18\x2f\x09" signed+="\xea\xe3\x1c\xfe\xd2\x6c\xab\xae\xaa\x9c\x47\xfb\xe5\xd6\x0d\xd6" signed+="\x6f\x42\x5f\x0b\xde\xa3\xc1\xb5\xf7\xaf\x5a\xf1\xab\xe8\xc4\x7c" signed+="\xeb\xaf\x48\xe4\x5d\x61\xa1\x5b\xf1\x28\x8f\xd0\x58\x1d\x9f\x64" signed+="\x8b\xf8\xf0\x33\xa6\xeb\x0b\xb2\xc5\x62\x09\xd8\x4c\x72\x4d\xae" signed+="\x04\xc7\x45\xeb\xdc\xa6\xb2\xf0\xfb\x2b\xb0\x81\xb6\x4f\x3e\x12" signed+="\x56\x61\x42\x74\x64\x66\x90\xb5\x72\x8f\x09\x8a\x8d\x6c\xc7\x02" signed+="\x0a\xc8\x51\xe0\x11\x00\x3c\xad\xf2\x5b\x29\xeb\x60\x2f\xb4\xdd" signed+="\x73\xc0\xb7\xdb\x1f\x6d\xb1" # End entity cert (signed by intermediate CA) intsigned="\x30\x82\x03\xa4\x30\x82\x02\x8c\xa0\x03\x02\x01\x02\x02\x09\x00" intsigned+="\xe5\x03\xc2\x77\xbb\xb3\x95\x45\x30\x0d\x06\x09\x2a\x86\x48\x86" intsigned+="\xf7\x0d\x01\x01\x0b\x05\x00\x30\x41\x31\x0d\x30\x0b\x06\x03\x55" intsigned+="\x04\x0a\x0c\x04\x4f\x72\x67\x32\x31\x10\x30\x0e\x06\x03\x55\x04" intsigned+="\x03\x0c\x07\x49\x73\x73\x75\x65\x72\x32\x31\x1e\x30\x1c\x06\x09" intsigned+="\x2a\x86\x48\x86\xf7\x0d\x01\x09\x01\x16\x0f\x63\x61\x32\x40\x65" intsigned+="\x78\x61\x6d\x70\x6c\x65\x2e\x63\x6f\x6d\x30\x1e\x17\x0d\x31\x36" intsigned+="\x31\x30\x31\x39\x32\x32\x35\x34\x32\x35\x5a\x17\x0d\x34\x34\x30" intsigned+="\x33\x30\x36\x32\x32\x35\x34\x32\x35\x5a\x30\x3f\x31\x0c\x30\x0a" intsigned+="\x06\x03\x55\x04\x0a\x0c\x03\x4f\x72\x67\x31\x0f\x30\x0d\x06\x03" intsigned+="\x55\x04\x03\x0c\x06\x49\x73\x73\x75\x65\x72\x31\x1e\x30\x1c\x06" intsigned+="\x09\x2a\x86\x48\x86\xf7\x0d\x01\x09\x01\x16\x0f\x65\x65\x63\x40" intsigned+="\x65\x78\x61\x6d\x70\x6c\x65\x2e\x63\x6f\x6d\x30\x82\x01\x22\x30" intsigned+="\x0d\x06\x09\x2a\x86\x48\x86\xf7\x0d\x01\x01\x01\x05\x00\x03\x82" intsigned+="\x01\x0f\x00\x30\x82\x01\x0a\x02\x82\x01\x01\x00\x92\xfd\x9d\x2c" intsigned+="\x31\xf2\xac\x18\xb3\x73\x7c\xf3\x7c\xd1\xea\x59\x48\xb0\xde\x55" intsigned+="\xc7\xa3\xf6\xbd\xa4\xd7\x34\x86\xb3\x2d\x38\x8c\xb4\x44\xec\xd0" intsigned+="\x02\xcf\x9a\xff\xf3\xa7\x9b\x44\xd5\x83\x8a\xb5\x0c\x44\xde\x68" intsigned+="\x14\xc3\x65\xeb\x34\x64\x90\xff\x00\x7e\x1e\x2e\x97\x12\xf3\x94" intsigned+="\x24\x08\x73\xeb\x59\x2d\x54\x35\x76\x7a\x43\x97\x7c\xe4\xe8\xa0" intsigned+="\x2c\x20\x5e\x5b\xc8\xaf\xa7\xf7\x0e\x3e\xc4\x4a\x2c\xd6\xd4\x3a" intsigned+="\x0e\x20\x70\x33\x57\x46\x12\xbe\x89\xd2\x4a\x17\xde\xca\x9a\xde" intsigned+="\x7f\x40\xa9\x06\x27\x61\xe2\x4b\x3f\xda\x24\x02\x20\x06\x83\xb2" intsigned+="\x87\x7e\xa0\xf6\xc7\xfd\x4e\x91\xba\x9f\x32\x9b\x61\x32\x0a\xc0" intsigned+="\xc1\x21\xaa\xce\xfc\xae\x22\xd9\x85\xc6\xeb\x94\xca\xe3\xb3\x05" intsigned+="\xf6\x00\xa6\xe4\xc8\xf3\xfe\x3e\xb0\xc0\x4d\x1c\x13\x44\xa2\x61" intsigned+="\xb0\x3d\xaa\xda\xbe\x60\x69\xbc\x91\x24\x96\x33\x0f\x6d\x12\x51" intsigned+="\x32\x27\xb3\x5e\x04\x02\x81\x5c\x48\x6b\x50\xcb\xad\x91\xe1\xfa" intsigned+="\xb1\x00\x56\x00\x22\xd6\x1a\xb6\xad\xf0\x1c\x1a\x30\x58\x0c\x45" intsigned+="\x6e\xd8\xcc\x50\xbb\xe1\x14\x8a\x20\x6b\xc3\x0b\x32\x66\x43\x9e" intsigned+="\xf4\x49\x52\x79\x41\x59\x49\xff\x2d\xe1\xbc\x49\x02\x03\x01\x00" intsigned+="\x01\xa3\x81\xa0\x30\x81\x9d\x30\x09\x06\x03\x55\x1d\x13\x04\x02" intsigned+="\x30\x00\x30\x1d\x06\x03\x55\x1d\x0e\x04\x16\x04\x14\xf7\xde\x3c" intsigned+="\x11\x91\x03\x2f\x77\xa7\x71\x1b\xa3\xa1\x73\x36\x01\x66\x29\xcc" intsigned+="\x2b\x30\x71\x06\x03\x55\x1d\x23\x04\x6a\x30\x68\x80\x14\xf5\x71" intsigned+="\x46\x2e\x96\x8c\x27\x3e\x47\xef\xba\x8a\x2c\x1c\xb5\x15\x88\xa7" intsigned+="\x24\x14\xa1\x45\xa4\x43\x30\x41\x31\x0d\x30\x0b\x06\x03\x55\x04" intsigned+="\x0a\x0c\x04\x4f\x72\x67\x32\x31\x10\x30\x0e\x06\x03\x55\x04\x03" intsigned+="\x0c\x07\x49\x73\x73\x75\x65\x72\x32\x31\x1e\x30\x1c\x06\x09\x2a" intsigned+="\x86\x48\x86\xf7\x0d\x01\x09\x01\x16\x0f\x63\x61\x32\x40\x65\x78" intsigned+="\x61\x6d\x70\x6c\x65\x2e\x63\x6f\x6d\x82\x09\x00\xfe\x1e\xe6\xa8" intsigned+="\x4e\x42\xc4\x72\x30\x0d\x06\x09\x2a\x86\x48\x86\xf7\x0d\x01\x01" intsigned+="\x0b\x05\x00\x03\x82\x01\x01\x00\xc3\xce\xd4\x43\x63\x19\xa3\xa2" intsigned+="\x4c\x84\x26\xeb\x62\x88\xb7\xcd\xe1\x83\xff\x61\x49\x54\xcf\x2e" intsigned+="\xad\x6e\x68\x1f\xe5\x2a\xd8\xd5\x5a\x92\x1a\xa4\x7a\x23\x74\x0a" intsigned+="\x7d\x75\xf6\xc6\x3c\x79\x14\xe6\x52\xb1\xfd\xdb\x42\x04\xdb\x79" intsigned+="\xc4\xfa\x74\x4b\x26\x26\x01\xfc\x70\xc4\xa5\xfb\xd4\x89\x63\xd7" intsigned+="\xf5\x9b\xd5\xae\xf5\xd4\x8b\x3a\x3c\xc6\x51\x36\xff\xf8\xb3\x21" intsigned+="\x68\x4d\xa2\xd2\x92\xe2\x5e\x78\xc6\x4a\x10\xa5\x88\x7c\x1e\xf2" intsigned+="\x1c\x68\xdc\xe9\x8f\x58\xb1\xa6\xe5\xc6\x4d\xdb\xf7\xc9\x66\x2f" intsigned+="\xd8\xc7\x86\x83\x63\x14\xf3\x4e\x2a\x39\xf2\x2d\x50\x3a\x53\x7d" intsigned+="\xfb\x91\xe4\x54\x7d\x33\xdf\x13\x63\x6f\x21\x9d\x12\xad\x48\x5d" intsigned+="\xf9\x41\xa1\x10\x80\xcd\x28\x9a\x4c\x82\x60\xae\x66\xc4\x85\x6f" intsigned+="\x55\x1e\x5d\x97\x49\x60\x1d\xdb\x26\x31\x1e\x0f\x08\x80\x11\x30" intsigned+="\x0f\x75\xad\x32\xfd\x28\xe4\xb9\x09\x30\x26\x32\xcd\x32\x83\x0c" intsigned+="\x4b\x51\x4e\x68\x70\xfc\x5b\x52\x9f\x3f\x27\xe7\xe9\xe2\x89\xa9" intsigned+="\xc0\x45\x42\xc7\xb7\x6d\x93\xb4\x02\xf4\xdb\xfd\x1c\x32\xc9\x25" intsigned+="\x4d\x4d\xff\xab\x72\xb5\x78\xb9\xd1\xcc\xdb\x73\x39\x6f\x7c\x84" intsigned+="\x6c\xc9\xf1\xb5\xcb\x81\x53\x8c" # Self-signed cert selfsign="\x30\x82\x03\x9d\x30\x82\x02\x85\xa0\x03\x02\x01\x02\x02\x09\x00" selfsign+="\xe1\xaa\x44\xda\xac\x8f\x12\x04\x30\x0d\x06\x09\x2a\x86\x48\x86" selfsign+="\xf7\x0d\x01\x01\x0b\x05\x00\x30\x3e\x31\x0c\x30\x0a\x06\x03\x55" selfsign+="\x04\x0a\x0c\x03\x4f\x72\x67\x31\x0f\x30\x0d\x06\x03\x55\x04\x03" selfsign+="\x0c\x06\x49\x73\x73\x75\x65\x72\x31\x1d\x30\x1b\x06\x09\x2a\x86" selfsign+="\x48\x86\xf7\x0d\x01\x09\x01\x16\x0e\x73\x73\x40\x65\x78\x61\x6d" selfsign+="\x70\x6c\x65\x2e\x63\x6f\x6d\x30\x1e\x17\x0d\x31\x36\x31\x30\x31" selfsign+="\x39\x32\x32\x35\x34\x32\x35\x5a\x17\x0d\x34\x34\x30\x33\x30\x36" selfsign+="\x32\x32\x35\x34\x32\x35\x5a\x30\x3e\x31\x0c\x30\x0a\x06\x03\x55" selfsign+="\x04\x0a\x0c\x03\x4f\x72\x67\x31\x0f\x30\x0d\x06\x03\x55\x04\x03" selfsign+="\x0c\x06\x49\x73\x73\x75\x65\x72\x31\x1d\x30\x1b\x06\x09\x2a\x86" selfsign+="\x48\x86\xf7\x0d\x01\x09\x01\x16\x0e\x73\x73\x40\x65\x78\x61\x6d" selfsign+="\x70\x6c\x65\x2e\x63\x6f\x6d\x30\x82\x01\x22\x30\x0d\x06\x09\x2a" selfsign+="\x86\x48\x86\xf7\x0d\x01\x01\x01\x05\x00\x03\x82\x01\x0f\x00\x30" selfsign+="\x82\x01\x0a\x02\x82\x01\x01\x00\xba\x2e\x4e\x75\x7a\x1f\xf9\xe7" selfsign+="\x58\xda\x54\xb1\xf5\xcf\x26\xad\x1a\x5d\xd6\xa5\xf7\xf1\xe4\xef" selfsign+="\x2d\x8c\xc9\x03\x69\x39\x55\xbd\xa2\xb1\x8b\x00\xf1\x08\x21\x4b" selfsign+="\x1d\x47\xff\x88\x2c\x56\x1a\x90\x2b\xaa\x32\x88\xa0\xa7\xd8\x58" selfsign+="\x5c\x74\xde\xaa\x8a\x17\x89\xc9\x3c\x6b\x17\x97\x90\x82\x8c\xf6" selfsign+="\xa1\x1e\x1a\x6e\x30\xb3\x56\xad\x4a\xdb\x50\xb3\x0b\xe2\x70\xdd" selfsign+="\xf2\x61\xf8\xa6\x8c\xf7\xcb\x2a\xb0\xd3\xd3\x14\x3e\xe6\x80\xe3" selfsign+="\x32\xd9\x25\x5c\x8f\x40\x5e\xb4\x71\x33\xd8\xfc\x1c\x9f\xd0\x95" selfsign+="\x90\x56\xe6\x7d\x4e\x39\x6d\xc1\x3a\xd9\x28\x9f\x40\xe7\x13\x17" selfsign+="\x7c\x9d\xdd\x6b\xd0\xf7\xe9\x68\xfa\xc2\x28\xb3\x45\x12\x5b\xfe" selfsign+="\x57\x72\x6c\x86\x9f\x18\xd6\xb6\x6b\xc8\x7c\x12\xca\x4e\x2f\xc7" selfsign+="\x25\x88\x92\x4e\x9f\xdd\x02\x6d\x37\x82\xf1\x8b\xd3\xf5\x6f\xf1" selfsign+="\x4c\xfa\xd8\x80\xe2\x23\xc6\xb7\x8f\x1e\x76\x45\x91\xc5\xf6\x30" selfsign+="\x48\x9f\xdb\x56\x31\x24\xed\xc8\xfd\x85\x21\x53\x79\xb0\x96\x51" selfsign+="\x5a\x1e\x82\x21\x95\x5a\x7f\xf1\x32\x25\x7a\x3c\xb4\x16\x6f\x6e" selfsign+="\xb8\xf2\xf2\xed\x75\xe9\x8b\x7a\xdb\xee\x5c\xf2\x63\x92\x47\xb7" selfsign+="\x7f\x07\x53\x8e\x14\x5c\x9e\xb3\x02\x03\x01\x00\x01\xa3\x81\x9d" selfsign+="\x30\x81\x9a\x30\x09\x06\x03\x55\x1d\x13\x04\x02\x30\x00\x30\x1d" selfsign+="\x06\x03\x55\x1d\x0e\x04\x16\x04\x14\x6a\x1d\x32\xc2\x5a\x0e\x9d" selfsign+="\xef\xb3\x59\x2e\x0e\xcf\x2e\x99\x4e\x30\x8d\x61\x1a\x30\x6e\x06" selfsign+="\x03\x55\x1d\x23\x04\x67\x30\x65\x80\x14\x6a\x1d\x32\xc2\x5a\x0e" selfsign+="\x9d\xef\xb3\x59\x2e\x0e\xcf\x2e\x99\x4e\x30\x8d\x61\x1a\xa1\x42" selfsign+="\xa4\x40\x30\x3e\x31\x0c\x30\x0a\x06\x03\x55\x04\x0a\x0c\x03\x4f" selfsign+="\x72\x67\x31\x0f\x30\x0d\x06\x03\x55\x04\x03\x0c\x06\x49\x73\x73" selfsign+="\x75\x65\x72\x31\x1d\x30\x1b\x06\x09\x2a\x86\x48\x86\xf7\x0d\x01" selfsign+="\x09\x01\x16\x0e\x73\x73\x40\x65\x78\x61\x6d\x70\x6c\x65\x2e\x63" selfsign+="\x6f\x6d\x82\x09\x00\xe1\xaa\x44\xda\xac\x8f\x12\x04\x30\x0d\x06" selfsign+="\x09\x2a\x86\x48\x86\xf7\x0d\x01\x01\x0b\x05\x00\x03\x82\x01\x01" selfsign+="\x00\xb6\x43\x7f\xb0\x66\xfd\x00\x99\x0e\x23\x9c\x17\x5e\x11\xe5" selfsign+="\x1f\x24\x85\xee\x5e\x12\x9b\xa0\xb0\x4f\x24\x8f\xf1\xaf\x78\x01" selfsign+="\x64\xc4\x32\x0c\x97\xb0\x10\x88\xac\x2c\xf1\xe4\x2c\x51\x0f\x16" selfsign+="\x6b\xd8\x66\xca\x8e\x63\xda\x41\x36\xec\x75\x3d\x99\xe3\x54\x27" selfsign+="\xd4\x91\xc7\xcf\x6b\x41\xa8\xa6\xd0\x42\x5e\xe0\x93\xb8\x77\xd2" selfsign+="\x83\x09\xf7\x56\x1e\x03\xb3\x12\x8f\x22\xa6\x50\xfd\x59\x6e\x22" selfsign+="\x3f\xc5\xe3\x0b\x76\xb7\x8a\x06\x90\x3a\x91\xdd\x74\x02\x42\x00" selfsign+="\x21\xb6\x1b\x92\xb9\x34\x84\x36\x89\x2c\xba\xf5\x1c\xa1\xfa\x39" selfsign+="\x95\x44\x5b\xdc\x44\xaf\x53\x79\x5f\x34\x43\xcc\x91\x01\xce\x8d" selfsign+="\x6b\x33\xbe\xe3\x25\xaf\xb7\xc6\xa7\x46\x3a\xb5\x94\x37\xcc\xd9" selfsign+="\xdb\x40\x56\x49\x2f\x4d\x5e\xfb\x7d\xab\x09\xf1\x66\xde\xb6\x67" selfsign+="\x9f\x80\xc7\xa0\xce\x46\x5a\x10\xb4\xf3\x42\x21\x14\x69\x0c\x4e" selfsign+="\x25\x6f\xd1\x0a\xc1\x33\x27\xcf\x09\x0e\x10\x83\xb9\x3d\x4f\x0c" selfsign+="\x2f\x29\x2c\xb3\x19\x37\x3d\x57\x0e\xe3\xbe\x53\x8d\x54\x96\xcd" selfsign+="\x8f\x6f\x1d\x15\x2b\x28\xfa\x4f\x5c\x0c\x4e\x1d\x9d\xf9\x38\x7a" selfsign+="\x9d\x44\x3d\x85\x89\xee\x70\xb4\xe6\x73\xe7\x36\x33\x21\xa5\x84" selfsign+="\x18" # ---- do the actual testing ---- result=PASS echo "++++ BEGINNING TEST" >$OUTPUTFILE # create a keyring for CA keys marker "ADD CA KEYRING" create_keyring --new=cakeyring ca @s # create a keyring using the keys in user CA for validation marker "ADD RESTRICTED USER KEYRING (parent keyring)" create_keyring --new=restricted_by_keyring rbkr @s restrict_keyring $restricted_by_keyring "asymmetric" "key_or_keyring:$cakeyring" # verify cycle detection marker "REJECT RESTRICTION CYCLE" restrict_keyring --fail $cakeyring "asymmetric" "key_or_keyring:$restricted_by_keyring" # confirm that a restricted keyring cannot be restricted again marker "REJECT REPEATED RESTRICTION" restrict_keyring --fail $restricted_by_keyring "asymmetric" "builtin_trusted" # create a keyring using the keys in builtin CA for validation marker "ADD RESTRICTED BUILTIN KEYRING" create_keyring --new=restricted_by_builtin rbb @s restrict_keyring $restricted_by_builtin "asymmetric" "builtin_trusted" # add CA certificate to CA keyring marker "ADD USER SIGNED CERT" pcreate_key --new=cacert1id "-e $cacert1" asymmetric "" $cakeyring # attempt validation of signed key marker "REJECT KEY SIGNED BY UNKNOWN CA" pcreate_key --fail "-e $signed" asymmetric "" $restricted_by_keyring # attempt validation of signed key marker "REJECT KEY NOT SIGNED BY BUILTIN" pcreate_key --fail "-e $signed" asymmetric "" $restricted_by_builtin # add another CA certificate to CA keyring marker "ADD SECOND CA KEY" pcreate_key --new=cacert2id "-e $cacert2" asymmetric "" $cakeyring # create a keyring restricted on a single key marker "ADD RESTRICTED USER KEYRING (parent key)" create_keyring --new=restricted_by_key rbk @s restrict_keyring $restricted_by_key "asymmetric" "key_or_keyring:$cacert2id" # attempt validation of signed key marker "ADD KEY SIGNED BY KNOWN CA" pcreate_key --new=signedid "-e $signed" asymmetric "" $restricted_by_keyring link_key $signedid $restricted_by_key # confirm that self-signed key cannot be added marker "REJECT SELF-SIGNED KEY" pcreate_key --fail "-e $selfsign" asymmetric "" $restricted_by_keyring pcreate_key --fail "-e $selfsign" asymmetric "" $restricted_by_key # confirm that the keyring restriction cannot be changed marker "REJECT RESTRICTION CHANGE" restrict_keyring --fail $restricted_by_key "asymmetric" "builtin_trusted" # create two self-restricted keyrings marker "ADD USER KEYRINGS (self)" create_keyring --new=restricted_by_self1 rbs1 @s create_keyring --new=restricted_by_self2 rbs2 @s # add first certificate (treated as root cert) to self-restricted keyrings marker "ADD FIRST CERT TO SELF-RESTRICTED KEYRINGS" link_key $signedid $restricted_by_self1 link_key $cacert2id $restricted_by_self2 # apply restrictions marker "RESTRICT USER KEYRINGS" restrict_keyring $restricted_by_self1 "asymmetric" "key_or_keyring:0:chain" restrict_keyring $restricted_by_self2 "asymmetric" "key_or_keyring:0:chain" # reject certificate addition to self-restricted keyring marker "REJECT CERTS FOR SELF-RESTRICTED KEYRING" link_key --fail $cacert2id $restricted_by_self1 pcreate_key --fail "-e $selfsign" asymmetric "" $restricted_by_self1 pcreate_key --fail "-e $selfsign" asymmetric "" $restricted_by_self2 # add certificate to self-restricted keyring marker "ADD CERT TO SELF-RESTRICTED KEYRING" link_key $signedid $restricted_by_self2 # check certificate signed using an intermediate CA marker "ADD INTERMEDIATE SIGNED CERT TO SELF-RESTRICTED KEYRING" pcreate_key --new=intcertid "-e $intcert" asymmetric "" $restricted_by_self2 pcreate_key --new=intsignedid "-e $intsigned" asymmetric "" $restricted_by_self2 # check intermediate CA with a parent keyring when CA is missing marker "REJECT INTERMEDIATE SIGNED CERT WITHOUT INTERMEDIATE CA" create_keyring --new=restricted_by_int restricted_by_int @s restrict_keyring $restricted_by_int "asymmetric" "key_or_keyring:$cakeyring:chain" link_key --fail $intsignedid $restricted_by_int # check intermediate CA with a parent keyring and valid CA marker "ADD INTERMEDIATE SIGNED CERT WITH INTERMEDIATE CA" link_key $intcertid $restricted_by_int link_key $intsignedid $restricted_by_int # create a fully-restricted keyring (no links allowed) marker "ADD FULLY-RESTRICTED KEYRING" create_keyring --new=fully_restricted fr @s link_key $cacert2id $fully_restricted restrict_keyring $fully_restricted # reject certificate addition to fully-restricted keyring marker "REJECT CERTS FOR FULLY-RESTRICTED KEYRING" link_key --fail $cacert2id $fully_restricted pcreate_key --fail "-e $selfsign" asymmetric "" $fully_restricted echo "++++ FINISHED TEST: $result" >>$OUTPUTFILE # --- then report the results in the database --- toolbox_report_result $TEST $result keyutils-1.6.3/tests/keyctl/revoke/000077500000000000000000000000001370111642500173225ustar00rootroot00000000000000keyutils-1.6.3/tests/keyctl/revoke/bad-args/000077500000000000000000000000001370111642500210025ustar00rootroot00000000000000keyutils-1.6.3/tests/keyctl/revoke/bad-args/runtest.sh000066400000000000000000000010201370111642500230330ustar00rootroot00000000000000#!/bin/bash . ../../../prepare.inc.sh . ../../../toolbox.inc.sh # ---- do the actual testing ---- result=PASS echo "++++ BEGINNING TEST" >$OUTPUTFILE # check that a bad key ID fails correctly marker "CHECK BAD KEY ID" revoke_key --fail 0 expect_error EINVAL # check that a non-existent key ID fails correctly marker "CHECK NON-EXISTENT KEY ID" revoke_key --fail @t expect_error ENOKEY echo "++++ FINISHED TEST: $result" >>$OUTPUTFILE # --- then report the results in the database --- toolbox_report_result $TEST $result keyutils-1.6.3/tests/keyctl/revoke/noargs/000077500000000000000000000000001370111642500206135ustar00rootroot00000000000000keyutils-1.6.3/tests/keyctl/revoke/noargs/runtest.sh000066400000000000000000000007471370111642500226630ustar00rootroot00000000000000#!/bin/bash . ../../../prepare.inc.sh . ../../../toolbox.inc.sh # ---- do the actual testing ---- result=PASS echo "++++ BEGINNING TEST" >$OUTPUTFILE # check that no arguments fails correctly marker "ADD NO ARGS" expect_args_error keyctl revoke # check that two arguments fail correctly marker "ADD TWO ARGS" expect_args_error keyctl revoke 0 0 echo "++++ FINISHED TEST: $result" >>$OUTPUTFILE # --- then report the results in the database --- toolbox_report_result $TEST $result keyutils-1.6.3/tests/keyctl/revoke/valid/000077500000000000000000000000001370111642500204215ustar00rootroot00000000000000keyutils-1.6.3/tests/keyctl/revoke/valid/runtest.sh000066400000000000000000000033041370111642500224610ustar00rootroot00000000000000#!/bin/bash . ../../../prepare.inc.sh . ../../../toolbox.inc.sh # ---- do the actual testing ---- result=PASS echo "++++ BEGINNING TEST" >$OUTPUTFILE # create a keyring and attach it to the session keyring marker "ADD KEYRING" create_keyring --new=keyringid wibble @s # create a key and attach it to the new keyring marker "ADD KEY" create_key --new=keyid user lizard gizzard $keyringid # check that we can list the keyring marker "LIST KEYRING" list_keyring $keyringid expect_keyring_rlist ringlist $keyid # check we can read the key description marker "CHECK VALIDATE KEY" describe_key $keyid expect_key_rdesc kdesc 'user@.*@lizard' # check we can read the key's payload marker "CHECK READ PAYLOAD" print_key $keyid expect_payload kpayload "gizzard" # revoke the key marker "REVOKE KEY" revoke_key $keyid # check we can no longer read the key description marker "CHECK NO VALIDATE KEY" describe_key --fail $keyid expect_error EKEYREVOKED # check we can no longer read the key's payload marker "CHECK NO READ PAYLOAD" print_key --fail $keyid expect_error EKEYREVOKED # remove the key we added marker "UNLINK KEY" unlink_key $keyid $keyringid # revoke the keyring marker "REVOKE KEYRING" revoke_key $keyringid # listing the session keyring should fail marker "CHECK NO LIST SESSION KEYRING" list_keyring --fail $keyringid expect_error EKEYREVOKED # validating the new keyring's name and type should also fail marker "CHECK NO VALIDATE KEYRING" describe_key --fail $keyringid expect_error EKEYREVOKED # remove the keyring we added marker "UNLINK KEYRING" unlink_key $keyringid @s echo "++++ FINISHED TEST: $result" >>$OUTPUTFILE # --- then report the results in the database --- toolbox_report_result $TEST $result keyutils-1.6.3/tests/keyctl/search/000077500000000000000000000000001370111642500172745ustar00rootroot00000000000000keyutils-1.6.3/tests/keyctl/search/bad-args/000077500000000000000000000000001370111642500207545ustar00rootroot00000000000000keyutils-1.6.3/tests/keyctl/search/bad-args/runtest.sh000066400000000000000000000042431370111642500230170ustar00rootroot00000000000000#!/bin/bash . ../../../prepare.inc.sh . ../../../toolbox.inc.sh # ---- do the actual testing ---- result=PASS echo "++++ BEGINNING TEST" >$OUTPUTFILE # check that an empty key type fails correctly marker "CHECK EMPTY KEY TYPE" search_for_key --fail @s "" wibble expect_error EINVAL search_for_key --fail @s "" wibble @p expect_error EINVAL # check that an unsupported key type fails correctly marker "CHECK UNSUPPORTED KEY TYPE" search_for_key --fail @s lizardsgizzards wibble expect_error ENOKEY search_for_key --fail @s lizardsgizzards wibble @p expect_error ENOKEY # check that an invalid key type fails correctly marker "CHECK INVALID KEY TYPE" search_for_key --fail @s .user wibble expect_error EPERM search_for_key --fail @s .user wibble @p expect_error EPERM # check that an overlong key type fails correctly marker "CHECK OVERLONG KEY TYPE" search_for_key --fail @s $maxtype wibble expect_error ENOKEY search_for_key --fail @s a$maxtype wibble @p expect_error EINVAL # check that an max length key description works correctly (4095 inc NUL) marker "CHECK MAXLEN DESC" search_for_key --fail @s user $maxdesc expect_error ENOKEY search_for_key --fail @s user $maxdesc @p expect_error ENOKEY # This doesn't work on MIPS earlier than 3.19 because of a kernel bug kver=`uname -r` kmch=`uname -m` if kernel_at_or_later_than 3.19 || [ "$kmch" != "mips" -a "$kmch" != "mips64" ] then # check that an overlong key description fails correctly (>4095 inc NUL) marker "CHECK OVERLONG DESC" search_for_key --fail @s user a$maxdesc expect_error EINVAL fi search_for_key --fail @s user a$maxdesc @p expect_error EINVAL # check that a bad key ID fails correctly marker "CHECK BAD KEY ID" search_for_key --fail @s user wibble -2000 expect_error EINVAL # create a non-keyring key marker "CREATE KEY" create_key --new=keyid user a a @s # search the non-keyring key marker "SEARCH KEY" search_for_key --fail $keyid user a expect_error ENOTDIR search_for_key --fail $keyid user a @p expect_error ENOTDIR # dispose of the key marker "UNLINK KEY" unlink_key $keyid @s echo "++++ FINISHED TEST: $result" >>$OUTPUTFILE # --- then report the results in the database --- toolbox_report_result $TEST $result keyutils-1.6.3/tests/keyctl/search/noargs/000077500000000000000000000000001370111642500205655ustar00rootroot00000000000000keyutils-1.6.3/tests/keyctl/search/noargs/runtest.sh000066400000000000000000000012521370111642500226250ustar00rootroot00000000000000#!/bin/bash . ../../../prepare.inc.sh . ../../../toolbox.inc.sh # ---- do the actual testing ---- result=PASS echo "++++ BEGINNING TEST" >$OUTPUTFILE # check that no arguments fails correctly marker "NO ARGS" expect_args_error keyctl search # check that one argument fails correctly marker "ONE ARGS" expect_args_error keyctl search 0 # check that two arguments fails correctly marker "TWO ARGS" expect_args_error keyctl search 0 0 # check that five arguments fails correctly marker "FIVE ARGS" expect_args_error keyctl search 0 0 0 0 0 echo "++++ FINISHED TEST: $result" >>$OUTPUTFILE # --- then report the results in the database --- toolbox_report_result $TEST $result keyutils-1.6.3/tests/keyctl/search/valid/000077500000000000000000000000001370111642500203735ustar00rootroot00000000000000keyutils-1.6.3/tests/keyctl/search/valid/runtest.sh000066400000000000000000000135201370111642500224340ustar00rootroot00000000000000#!/bin/bash . ../../../prepare.inc.sh . ../../../toolbox.inc.sh # ---- do the actual testing ---- result=PASS echo "++++ BEGINNING TEST" >$OUTPUTFILE # create a pair of keyrings and attach them to the session keyring marker "ADD KEYRING" create_keyring --new=keyringid wibble @s create_keyring --new=keyring2id wibble2 @s # stick a key in the keyring marker "ADD KEY" create_key --new=keyid user lizard gizzard $keyringid # check that we can list it marker "LIST KEYRING WITH ONE" list_keyring $keyringid expect_keyring_rlist rlist $keyid # search the session keyring for a non-existent key marker "SEARCH SESSION FOR NON-EXISTENT KEY" search_for_key --fail @s user snake expect_error ENOKEY # search the session keyring for the key marker "SEARCH SESSION" search_for_key --expect=$keyid @s user lizard # search the session keyring for the key using the wrong type marker "SEARCH SESSION USING WRONG TYPE" search_for_key --fail @s keyring lizard $keyring2id expect_error ENOKEY # search the session keyring for the key and attach to second keyring marker "SEARCH SESSION AND ATTACH" search_for_key --expect=$keyid @s user lizard $keyring2id # check it's attached to the second keyring marker "CHECK ATTACHED" list_keyring $keyring2id expect_keyring_rlist rlist $keyid # check the key contains what we expect marker "CHECK PAYLOAD" print_key $keyid expect_payload payload "gizzard" # detach the attachment just made marker "DETACH KEY" unlink_key $keyid $keyring2id # create an overlapping key in the second keyring create_key --new=keyid2 user lizard skin $keyring2id # check the two keys contain what we expect marker "CHECK PAYLOADS" print_key $keyid expect_payload payload "gizzard" print_key $keyid2 expect_payload payload "skin" # a search from the session keyring should find the first key marker "SEARCH SESSION AGAIN" search_for_key --expect=$keyid @s user lizard # a search from the first keyring should find the first key marker "SEARCH FIRST KEYRING" search_for_key --expect=$keyid $keyringid user lizard # a search from the second keyring should find the second key marker "SEARCH SECOND KEYRING" search_for_key --expect=$keyid2 $keyring2id user lizard # link the second keyring to the first marker "LINK FIRST KEYRING TO SECOND" link_key $keyring2id $keyringid # a search from the first keyring should again find the first key marker "SEARCH FIRST KEYRING AGAIN" search_for_key --expect=$keyid $keyringid user lizard # revoking the first key should cause the second key to be available revoke_key $keyid search_for_key --expect=$keyid2 $keyringid user lizard # get rid of the dead key marker "UNLINK FIRST KEY" unlink_key $keyid $keyringid # a search from the first keyring should now find the second key marker "SEARCH FIRST KEYRING AGAIN 2" search_for_key --expect=$keyid2 $keyringid user lizard # a search from the session keyring should now find the second key marker "SEARCH SESSION KEYRING AGAIN 2" search_for_key --expect=$keyid2 @s user lizard # unlink the second keyring from the first marker "UNLINK SECOND KEYRING FROM FIRST" unlink_key $keyring2id $keyringid # a search from the first keyring should now fail marker "SEARCH FIRST KEYRING FOR FAIL" search_for_key --fail $keyringid user lizard expect_error ENOKEY # a search from the session keyring should still find the second key marker "SEARCH SESSION KEYRING AGAIN 3" search_for_key --expect=$keyid2 @s user lizard # move the second keyring into the first marker "MOVE SECOND KEYRING INTO FIRST" link_key $keyring2id $keyringid unlink_key $keyring2id @s # a search from the first keyring should now find the second key once again marker "SEARCH FIRST KEYRING AGAIN 4" search_for_key --expect=$keyid2 $keyringid user lizard # Removing search permission on the first keyring should hide the key # - This fails with EACCES as we don't have permission to initiate a search. marker "SEARCH WITH NO-SEARCH KEYRING" set_key_perm $keyringid 0x370000 search_for_key --fail $keyringid user lizard expect_error EACCES # But if we start at the session keyring, we just can't find the key search_for_key --fail @s user lizard expect_error ENOKEY # putting search permission on the first keyring back again should make it # available again set_key_perm $keyringid 0x3f0000 search_for_key --expect=$keyid2 $keyringid user lizard # Removing search permission on the second key should hide the key # - This fails with ENOKEY because we're allowed to start the search, but then # don't find the key because there's an unsearchable keyring in the path. marker "SEARCH WITH NO-SEARCH KEYRING2" set_key_perm $keyring2id 0x370000 search_for_key --fail $keyringid user lizard expect_error ENOKEY search_for_key --fail @s user lizard expect_error ENOKEY # putting search permission on the second key back again should make it # available again set_key_perm $keyring2id 0x3f0000 search_for_key --expect=$keyid2 $keyringid user lizard # Removing search permission on the second key should hide the key # - This fails with EACCES because we found the key, but we're not allowed to # find it. marker "SEARCH WITH NO-SEARCH KEY2" set_key_perm $keyid2 0x370000 search_for_key --fail $keyringid user lizard expect_error EACCES search_for_key --fail @s user lizard expect_error EACCES # putting search permission on the second key back again should make it # available again set_key_perm $keyid2 0x3f0000 search_for_key --expect=$keyid2 $keyringid user lizard # revoking the key should make the key unavailable revoke_key $keyid2 search_for_key --fail $keyringid user lizard kver=`uname -r` case $kver in *.el7*) expect_error EKEYREVOKED ;; *) if kernel_older_than 3.13 then expect_error ENOKEY else expect_error EKEYREVOKED fi ;; esac # remove the keyrings we added marker "UNLINK KEYRING" unlink_key $keyringid @s echo "++++ FINISHED TEST: $result" >>$OUTPUTFILE # --- then report the results in the database --- toolbox_report_result $TEST $result keyutils-1.6.3/tests/keyctl/session/000077500000000000000000000000001370111642500175125ustar00rootroot00000000000000keyutils-1.6.3/tests/keyctl/session/bad-args/000077500000000000000000000000001370111642500211725ustar00rootroot00000000000000keyutils-1.6.3/tests/keyctl/session/bad-args/runtest.sh000066400000000000000000000014011370111642500232260ustar00rootroot00000000000000#!/bin/bash . ../../../prepare.inc.sh . ../../../toolbox.inc.sh # ---- do the actual testing ---- result=PASS echo "++++ BEGINNING TEST" >$OUTPUTFILE # check that an empty keyring name fails correctly marker "SESSION WITH EMPTY KEYRING NAME" new_session --fail "" expect_error EINVAL # This doesn't work on MIPS earlier than 3.19 because of a kernel bug kver=`uname -r` kmch=`uname -m` if kernel_at_or_later_than 3.19 || [ "$kmch" != "mips" -a "$kmch" != "mips64" ] then # check that an overlong keyring name fails correctly marker "SESSION WITH OVERLONG KEYRING NAME" new_session --fail a$maxdesc expect_error EINVAL fi echo "++++ FINISHED TEST: $result" >>$OUTPUTFILE # --- then report the results in the database --- toolbox_report_result $TEST $result keyutils-1.6.3/tests/keyctl/session/valid/000077500000000000000000000000001370111642500206115ustar00rootroot00000000000000keyutils-1.6.3/tests/keyctl/session/valid/runtest.sh000066400000000000000000000020621370111642500226510ustar00rootroot00000000000000#!/bin/bash . ../../../prepare.inc.sh . ../../../toolbox.inc.sh # ---- do the actual testing ---- result=PASS echo "++++ BEGINNING TEST" >$OUTPUTFILE # describe the keyring created for an anonymous session if [ $OSDIST = RHEL ] && version_less_than $OSRELEASE 6 then marker "ANON SESSION" new_session - keyctl rdescribe @s "@" expect_key_rdesc rdesc "keyring@.*@.*@.*@_ses[^@]*\$" # check the session keyring ID is shown seskeyring="`tail -2 $OUTPUTFILE | head -1`" if ! expr "$seskeyring" : "Joined session keyring: [0-9]*" >&/dev/null then failed fi fi # describe the keyring created for a named session marker "NAMED SESSION" new_session qwerty keyctl rdescribe @s "@" expect_key_rdesc rdesc "keyring@.*@.*@.*@qwerty" # check the session keyring ID is shown seskeyring="`tail -2 $OUTPUTFILE | head -1`" if ! expr "$seskeyring" : "Joined session keyring: [0-9]*" >&/dev/null then failed fi echo "++++ FINISHED TEST: $result" >>$OUTPUTFILE # --- then report the results in the database --- toolbox_report_result $TEST $result keyutils-1.6.3/tests/keyctl/session/valid2/000077500000000000000000000000001370111642500206735ustar00rootroot00000000000000keyutils-1.6.3/tests/keyctl/session/valid2/runtest.sh000066400000000000000000000015001370111642500227270ustar00rootroot00000000000000#!/bin/bash . ../../../prepare.inc.sh . ../../../toolbox.inc.sh # ---- do the actual testing ---- result=PASS echo "++++ BEGINNING TEST" >$OUTPUTFILE # Replace the script's session keyring with an anonymous keyring marker "ANON SESSION TO PARENT" id_key --to=ses1 @s new_session_to_parent id_key --to=ses2 @s if [ $ses2 = $ses1 ] then failed fi describe_key @s "@" expect_key_rdesc rdesc "keyring@.*@.*@.*@_ses" # Replace the script's session keyring with a named keyring marker "NAMED SESSION TO PARENT" new_session_to_parent lizard id_key --to=ses3 @s if [ $ses3 = $ses2 -o $ses3 = $ses1 ] then failed fi describe_key @s "@" expect_key_rdesc rdesc "keyring@.*@.*@.*@lizard" echo "++++ FINISHED TEST: $result" >>$OUTPUTFILE # --- then report the results in the database --- toolbox_report_result $TEST $result keyutils-1.6.3/tests/keyctl/show/000077500000000000000000000000001370111642500170075ustar00rootroot00000000000000keyutils-1.6.3/tests/keyctl/show/noargs/000077500000000000000000000000001370111642500203005ustar00rootroot00000000000000keyutils-1.6.3/tests/keyctl/show/noargs/runtest.sh000066400000000000000000000021101370111642500223320ustar00rootroot00000000000000#!/bin/bash . ../../../prepare.inc.sh . ../../../toolbox.inc.sh # ---- do the actual testing ---- result=PASS echo "++++ BEGINNING TEST" >$OUTPUTFILE # check that show shows us our session keyring marker "SHOW SESSION KEYRING" keyctl show >>$OUTPUTFILE 2>&1 if [ $? != 0 ] then failed fi # must be at least two lines in the output (plus the test banner lines) nlines=`wc -l $OUTPUTFILE | cut -d\ -f1` if [ "$nlines" -lt 4 ] then failed fi # there must be a session keyring section on the third line if [ "`sed -n -e 3p $OUTPUTFILE`" != "Session Keyring" ] then failed fi # the first key listed (line 2) should be a keying (the session keyring) ... keyring1="`grep -n keyring $OUTPUTFILE | cut -d: -f1 | head -1`" if [ "$keyring1" != "4" ] then failed fi # ... and it should be the session keyring keyring1name="`sed -n -e 4p $OUTPUTFILE | awk '{print $6}'`" if ! expr "$keyring1name" : "^RHTS/keyctl" >&/dev/null then failed fi echo "++++ FINISHED TEST: $result" >>$OUTPUTFILE # --- then report the results in the database --- toolbox_report_result $TEST $result keyutils-1.6.3/tests/keyctl/show/valid/000077500000000000000000000000001370111642500201065ustar00rootroot00000000000000keyutils-1.6.3/tests/keyctl/show/valid/runtest.sh000066400000000000000000000032641370111642500221530ustar00rootroot00000000000000#!/bin/bash . ../../../prepare.inc.sh . ../../../toolbox.inc.sh # ---- do the actual testing ---- result=PASS echo "++++ BEGINNING TEST" >$OUTPUTFILE # add some keyrings, nested one inside the other nr_keyrings=7 keyrings= parent=@s for ((i=1; i<=$nr_keyrings; i++)) do marker "ADD KEYRING $i" create_keyring --new=keyringid wibble$i $parent parent=$keyringid keyrings="$keyrings $keyringid" done # check that show works marker "SHOW SESSION KEYRING" keyctl show >>$OUTPUTFILE 2>&1 if [ $? != 0 ] then failed fi if [ $OSDIST = RHEL ] && ! version_less_than $OSRELEASE 6.6 || keyutils_at_or_later_than 1.5.6 then # should be eight lines in the output (banner + session + 6 keyrings) marker "COUNT LINES" nlines=`keyctl show | wc -l` if [ "$nlines" -ne $(($nr_keyrings + 2)) ] then failed fi # check the key ID list marker "CHECK KEY ID LIST" keyids=`keyctl show | tail -n +3 | cut -c1-11` # we need to fix up the whitespace keyids=`echo $keyids` keyrings=`echo $keyrings` echo "Compare '$keyids'" >>$OUTPUTFILE echo "And '$keyrings'" >>$OUTPUTFILE if [ "$keyids" != "$keyrings" ] then failed fi fi # check that shows of specified keyrings also work if keyutils_at_or_later_than 1.5.4 then declare -i j j=$nr_keyrings for i in $keyrings do marker "CHECK SHOW OTHERS $j" echo --- $i >>$OUTPUTFILE if ! keyctl show $i >>$OUTPUTFILE then failed fi k=`keyctl show $i | wc -l` if [ $(($j + 1)) != $k ] then failed fi j=$(($j - 1)) done fi echo "++++ FINISHED TEST: $result" >>$OUTPUTFILE # --- then report the results in the database --- toolbox_report_result $TEST $result keyutils-1.6.3/tests/keyctl/supports/000077500000000000000000000000001370111642500177265ustar00rootroot00000000000000keyutils-1.6.3/tests/keyctl/supports/bad-args/000077500000000000000000000000001370111642500214065ustar00rootroot00000000000000keyutils-1.6.3/tests/keyctl/supports/bad-args/runtest.sh000066400000000000000000000007571370111642500234570ustar00rootroot00000000000000#!/bin/bash . ../../../prepare.inc.sh . ../../../toolbox.inc.sh # ---- do the actual testing ---- result=PASS echo "++++ BEGINNING TEST" >$OUTPUTFILE # check that two arguments fails correctly marker "TWO ARGS" expect_args_error keyctl support 0 0 # check that three arguments fails correctly marker "THREE ARGS" expect_args_error keyctl support 0 0 0 echo "++++ FINISHED TEST: $result" >>$OUTPUTFILE # --- then report the results in the database --- toolbox_report_result $TEST $result keyutils-1.6.3/tests/keyctl/supports/valid/000077500000000000000000000000001370111642500210255ustar00rootroot00000000000000keyutils-1.6.3/tests/keyctl/supports/valid/runtest.sh000066400000000000000000000006621370111642500230710ustar00rootroot00000000000000#!/bin/bash . ../../../prepare.inc.sh . ../../../toolbox.inc.sh # ---- do the actual testing ---- result=PASS echo "++++ BEGINNING TEST" >$OUTPUTFILE # Check that listing caps works marker "LIST CAPS" supports # check that querying a cap works marker "QUERY CAP" supports --unrecognised xxx echo "++++ FINISHED TEST: $result" >>$OUTPUTFILE # --- then report the results in the database --- toolbox_report_result $TEST $result keyutils-1.6.3/tests/keyctl/timeout/000077500000000000000000000000001370111642500175155ustar00rootroot00000000000000keyutils-1.6.3/tests/keyctl/timeout/bad-args/000077500000000000000000000000001370111642500211755ustar00rootroot00000000000000keyutils-1.6.3/tests/keyctl/timeout/bad-args/runtest.sh000066400000000000000000000012771370111642500232440ustar00rootroot00000000000000#!/bin/bash . ../../../prepare.inc.sh . ../../../toolbox.inc.sh # ---- do the actual testing ---- result=PASS echo "++++ BEGINNING TEST" >$OUTPUTFILE # check that a bad key ID fails correctly marker "CHECK BAD KEY ID" timeout_key --fail 0 10 expect_error EINVAL # get a key marker "CREATE KEY" create_key --new=keyid user a a @s # dispose of the key so we can use its ID marker "DESTROY KEY ID" unlink_key --wait $keyid @s # check that a non-existent key ID fails correctly marker "CHECK NON-EXISTENT KEY ID" timeout_key --fail $keyid 10 expect_error ENOKEY echo "++++ FINISHED TEST: $result" >>$OUTPUTFILE # --- then report the results in the database --- toolbox_report_result $TEST $result keyutils-1.6.3/tests/keyctl/timeout/noargs/000077500000000000000000000000001370111642500210065ustar00rootroot00000000000000keyutils-1.6.3/tests/keyctl/timeout/noargs/runtest.sh000066400000000000000000000011221370111642500230420ustar00rootroot00000000000000#!/bin/bash . ../../../prepare.inc.sh . ../../../toolbox.inc.sh # ---- do the actual testing ---- result=PASS echo "++++ BEGINNING TEST" >$OUTPUTFILE # check that no arguments fails correctly marker "ADD NO ARGS" expect_args_error keyctl timeout # check that one argument fails correctly marker "ADD ONE ARG" expect_args_error keyctl timeout 0 # check that three arguments fail correctly marker "ADD THREE ARGS" expect_args_error keyctl timeout 0 0 0 echo "++++ FINISHED TEST: $result" >>$OUTPUTFILE # --- then report the results in the database --- toolbox_report_result $TEST $result keyutils-1.6.3/tests/keyctl/timeout/valid/000077500000000000000000000000001370111642500206145ustar00rootroot00000000000000keyutils-1.6.3/tests/keyctl/timeout/valid/runtest.sh000066400000000000000000000066011370111642500226570ustar00rootroot00000000000000#!/bin/bash . ../../../prepare.inc.sh . ../../../toolbox.inc.sh # ---- do the actual testing ---- result=PASS echo "++++ BEGINNING TEST" >$OUTPUTFILE # create a keyring and attach it to the session keyring marker "ADD KEYRING" create_keyring --new=keyringid wibble @s # create a key and attach it to the new keyring marker "ADD KEY" create_key --new=keyid user lizard gizzard $keyringid # check that we can list the keyring marker "LIST KEYRING" list_keyring $keyringid expect_keyring_rlist ringlist $keyid # check we can read the key description marker "CHECK VALIDATE KEY" describe_key $keyid expect_key_rdesc kdesc 'user@.*@lizard' # check we can read the key's payload marker "CHECK READ PAYLOAD" print_key $keyid expect_payload kpayload "gizzard" # set a silly timeout on the key marker "SET BIG TIMEOUT" timeout_key $keyid 10000000 # check we can still read the key's payload marker "CHECK READ PAYLOAD 2" print_key $keyid expect_payload kpayload "gizzard" # set a small timeout on the key marker "SET SMALL TIMEOUT" timeout_key $keyid 2 marker "WAIT FOR TIMEOUT" sleep_at_least 2 # check the key has expired marker "CHECK NO READ PAYLOAD" print_key --fail $keyid if kernel_at_or_later_than 3.8 && kernel_older_than 3.13 && ! rhel7_kernel_at_or_later_than 3.10.0-42.el7 then expect_error ENOKEY else expect_error EKEYEXPIRED fi # check revocation doesn't work marker "CHECK NO REVOKE KEY" revoke_key --fail $keyid expect_error EKEYEXPIRED # check timeout setting doesn't work marker "CHECK NO TIMEOUT KEY" timeout_key --fail $keyid 20 expect_error EKEYEXPIRED # remove the key we added marker "UNLINK KEY" unlink_key $keyid $keyringid ############################################################################### # create a key and attach it to the new keyring marker "ADD KEY" create_key --new=keyid user lizard gizzard $keyringid # set a silly timeout on the key marker "SET BIG TIMEOUT" timeout_key $keyid 10000000 # revoke the key marker "REVOKE KEY" revoke_key $keyid # check we can no longer set the key's timeout marker "CHECK NO SET KEY TIMEOUT" timeout_key --fail $keyid 20 expect_error EKEYREVOKED # remove the key we added marker "UNLINK KEY" unlink_key $keyid $keyringid # revoke the keyring marker "TIMEOUT KEYRING" timeout_key $keyringid 1 marker "WAIT FOR KEYRING TIMEOUT" sleep_at_least 1 # listing the session keyring should fail marker "CHECK NO LIST SESSION KEYRING" list_keyring --fail $keyringid if kernel_at_or_later_than 3.8 && kernel_older_than 3.13 && ! rhel7_kernel_at_or_later_than 3.10.0-42.el7 then expect_error ENOKEY else expect_error EKEYEXPIRED fi # validating the new keyring's name and type should also fail marker "CHECK NO VALIDATE KEYRING" describe_key --fail $keyringid expect_error EKEYEXPIRED # validating the new keyring's name and type should also fail marker "CHECK NO SET KEYRING TIMEOUT" timeout_key --fail $keyringid 20 expect_error EKEYEXPIRED # validating the new keyring's name and type should also fail marker "CHECK NO INVALIDATE KEYRING" invalidate_key --fail $keyringid expect_error EKEYEXPIRED # validating the new keyring's name and type should also fail marker "CHECK NO REVOKE KEYRING" revoke_key --fail $keyringid expect_error EKEYEXPIRED # remove the keyring we added marker "UNLINK KEYRING" unlink_key $keyringid @s echo "++++ FINISHED TEST: $result" >>$OUTPUTFILE # --- then report the results in the database --- toolbox_report_result $TEST $result keyutils-1.6.3/tests/keyctl/unlink/000077500000000000000000000000001370111642500173275ustar00rootroot00000000000000keyutils-1.6.3/tests/keyctl/unlink/all/000077500000000000000000000000001370111642500200775ustar00rootroot00000000000000keyutils-1.6.3/tests/keyctl/unlink/all/runtest.sh000066400000000000000000000046001370111642500221370ustar00rootroot00000000000000#!/bin/bash . ../../../prepare.inc.sh . ../../../toolbox.inc.sh # ---- do the actual testing ---- result=PASS if keyutils_at_or_later_than 1.5 then echo "++++ BEGINNING TEST" >$OUTPUTFILE # create a keyring and attach it to the session keyring marker "ADD KEYRING" create_keyring --new=keyringid wibble @s # stick a key in the keyring marker "ADD KEY" create_key --new=keyid user lizard gizzard $keyringid # check that we can list it marker "LIST KEYRING WITH ONE" list_keyring $keyringid expect_keyring_rlist rlist $keyid # dispose of the key and make sure it gets destroyed marker "UNLINK KEY FROM KEYRING" unlink_key --wait $keyid $keyringid # trying a tree-wide unlink should succeed with no links removed marker "CHECK NO UNLINK KEY FROM TREE" unlink_key $keyid expect_unlink_count n_unlinked 0 # check that the keyring is now empty marker "LIST KEYRING" list_keyring $keyringid expect_keyring_rlist rlist empty # create a key to be massively linked marker "ADD MULTI KEY" create_key --new=keyid user lizard gizzard $keyringid # stick twenty keyrings in the keyring with twenty links marker "ADD TWENTY KEYRINGS WITH LINKS" subrings= for ((i=0; i<20; i++)) do create_keyring --new=x ring$i $keyringid keys="$keys $x" subrings="$subrings $x" list_keyring $keyringid expect_keyring_rlist rlist $x link_key $keyid $x list_keyring $x expect_keyring_rlist rlist $keyid done marker "SHOW" if ! keyctl show >>$OUTPUTFILE 2>&1 then failed fi # delete all the keys from the keyring tree marker "REMOVE ALL LINKS TO KEY" unlink_key $keyid expect_unlink_count n_unlinked 21 # there should not now be any left unlink_key $keyid expect_unlink_count n_unlinked 0 # check that the key is no longer in the main keyring marker "CHECK GONE" list_keyring $keyringid expect_keyring_rlist rlist $keyid --absent for i in $subrings do list_keyring $i expect_keyring_rlist rlist $keyid --absent done # remove the keyring we added marker "UNLINK KEY" unlink_key $keyringid @s echo "++++ FINISHED TEST: $result" >>$OUTPUTFILE else toolbox_skip_test $TEST "SKIPPING TEST DUE TO LACK OF UNLINK-ALL" exit 0 fi # --- then report the results in the database --- toolbox_report_result $TEST $result keyutils-1.6.3/tests/keyctl/unlink/bad-args/000077500000000000000000000000001370111642500210075ustar00rootroot00000000000000keyutils-1.6.3/tests/keyctl/unlink/bad-args/runtest.sh000066400000000000000000000020421370111642500230450ustar00rootroot00000000000000#!/bin/bash . ../../../prepare.inc.sh . ../../../toolbox.inc.sh # ---- do the actual testing ---- result=PASS echo "++++ BEGINNING TEST" >$OUTPUTFILE # check that a bad key ID fails correctly marker "CHECK UNLINK BAD KEY ID" unlink_key --fail 0 @s expect_error EINVAL marker "CHECK UNLINK FROM BAD KEY ID" unlink_key --fail @s 0 expect_error EINVAL # create a non-keyring marker "CREATE KEY" create_key --new=keyid user lizard gizzard @s # check that unlinking from a non-keyring ID fails correctly marker "CHECK UNLINK FROM NON-KEYRING KEY" unlink_key --fail @s $keyid expect_error ENOTDIR # dispose of the key we were using marker "UNLINK KEY" unlink_key --wait $keyid @s # check that a non-existent key ID fails correctly marker "CHECK UNLINK FROM NON-EXISTENT KEY ID" unlink_key --fail @s $keyid expect_error ENOKEY marker "CHECK UNLINK NON-EXISTENT KEY ID" unlink_key --fail $keyid @s expect_error ENOKEY echo "++++ FINISHED TEST: $result" >>$OUTPUTFILE # --- then report the results in the database --- toolbox_report_result $TEST $result keyutils-1.6.3/tests/keyctl/unlink/noargs/000077500000000000000000000000001370111642500206205ustar00rootroot00000000000000keyutils-1.6.3/tests/keyctl/unlink/noargs/runtest.sh000066400000000000000000000011651370111642500226630ustar00rootroot00000000000000#!/bin/bash . ../../../prepare.inc.sh . ../../../toolbox.inc.sh # ---- do the actual testing ---- result=PASS echo "++++ BEGINNING TEST" >$OUTPUTFILE # check that no arguments fails correctly marker "NO ARGS" expect_args_error keyctl unlink if keyutils_older_than 1.5 then # check that one argument fails correctly marker "ONE ARGS" expect_args_error keyctl unlink 0 fi # check that three arguments fails correctly marker "THREE ARGS" expect_args_error keyctl unlink 0 0 0 echo "++++ FINISHED TEST: $result" >>$OUTPUTFILE # --- then report the results in the database --- toolbox_report_result $TEST $result keyutils-1.6.3/tests/keyctl/unlink/valid/000077500000000000000000000000001370111642500204265ustar00rootroot00000000000000keyutils-1.6.3/tests/keyctl/unlink/valid/runtest.sh000066400000000000000000000037241370111642500224740ustar00rootroot00000000000000#!/bin/bash . ../../../prepare.inc.sh . ../../../toolbox.inc.sh # ---- do the actual testing ---- result=PASS echo "++++ BEGINNING TEST" >$OUTPUTFILE # create a keyring and attach it to the session keyring marker "ADD KEYRING" create_keyring --new=keyringid wibble @s # stick a key in the keyring marker "ADD KEY" create_key --new=keyid user lizard gizzard $keyringid # check that we can list it marker "LIST KEYRING WITH ONE" list_keyring $keyringid expect_keyring_rlist rlist $keyid # dispose of the key and make sure it gets destroyed marker "UNLINK KEY FROM KEYRING" unlink_key --wait $keyid $keyringid # trying again should fail marker "CHECK NO UNLINK KEY FROM KEYRING" unlink_key --fail $keyid $keyringid expect_error ENOKEY # check that the keyring is now empty marker "LIST KEYRING" list_keyring $keyringid expect_keyring_rlist rlist empty # stick twenty keys and twenty keyrings in the keyring marker "ADD TWENTY KEYS" keys="" for ((i=0; i<20; i++)) do create_key --new=x user lizard$i gizzard$i $keyringid keys="$keys $x" list_keyring $keyringid expect_keyring_rlist rlist $x done marker "ADD TWENTY KEYRINGS" for ((i=0; i<20; i++)) do create_keyring --new=x ring$i $keyringid keys="$keys $x" list_keyring $keyringid expect_keyring_rlist rlist $x done marker "CHECK KEYRING CONTENTS" list_keyring $keyringid for i in $keys do expect_keyring_rlist rlist $i done marker "SHOW" if ! keyctl show >>$OUTPUTFILE 2>&1 then failed fi # delete all the keys from the keyring marker "DELETE CONTENTS OF KEYRING" for i in $keys do unlink_key --wait $i $keyringid unlink_key --fail $i $keyringid expect_error ENOKEY done keyctl show # check that it's now empty marker "LIST KEYRING" list_keyring $keyringid expect_keyring_rlist rlist empty # remove the keyring we added marker "UNLINK KEY" unlink_key $keyringid @s echo "++++ FINISHED TEST: $result" >>$OUTPUTFILE # --- then report the results in the database --- toolbox_report_result $TEST $result keyutils-1.6.3/tests/keyctl/update/000077500000000000000000000000001370111642500173115ustar00rootroot00000000000000keyutils-1.6.3/tests/keyctl/update/bad-args/000077500000000000000000000000001370111642500207715ustar00rootroot00000000000000keyutils-1.6.3/tests/keyctl/update/bad-args/runtest.sh000066400000000000000000000015341370111642500230340ustar00rootroot00000000000000#!/bin/bash . ../../../prepare.inc.sh . ../../../toolbox.inc.sh # ---- do the actual testing ---- result=PASS echo "++++ BEGINNING TEST" >$OUTPUTFILE # attempt to update the session keyring marker "CHECK UPDATE SESSION KEYRING" update_key --fail @s a expect_error EOPNOTSUPP # attempt to update an invalid key marker "CHECK UPDATE INVALID KEY" update_key --fail 0 a expect_error EINVAL # add a user key to the session keyring for us to play with marker "ADD USER KEY" create_key --new=keyid user wibble stuff @s # remove the key we just added marker "UNLINK KEY" unlink_key --wait $keyid @s # it should fail when we attempt to update it marker "UPDATE UNLINKED KEY" update_key --fail $keyid @s expect_error ENOKEY echo "++++ FINISHED TEST: $result" >>$OUTPUTFILE # --- then report the results in the database --- toolbox_report_result $TEST $result keyutils-1.6.3/tests/keyctl/update/noargs/000077500000000000000000000000001370111642500206025ustar00rootroot00000000000000keyutils-1.6.3/tests/keyctl/update/noargs/runtest.sh000066400000000000000000000011371370111642500226440ustar00rootroot00000000000000#!/bin/bash . ../../../prepare.inc.sh . ../../../toolbox.inc.sh # ---- do the actual testing ---- result=PASS echo "++++ BEGINNING TEST" >$OUTPUTFILE # check that no arguments fails correctly marker "ADD NO ARGS" expect_args_error keyctl update # check that one argument fails correctly marker "ADD ONE ARG" expect_args_error keyctl update user # check that three arguments fail correctly marker "ADD THREE ARGS" expect_args_error keyctl update user wibble stuff echo "++++ FINISHED TEST: $result" >>$OUTPUTFILE # --- then report the results in the database --- toolbox_report_result $TEST $result keyutils-1.6.3/tests/keyctl/update/userupdate/000077500000000000000000000000001370111642500214725ustar00rootroot00000000000000keyutils-1.6.3/tests/keyctl/update/userupdate/runtest.sh000066400000000000000000000020261370111642500235320ustar00rootroot00000000000000#!/bin/bash . ../../../prepare.inc.sh . ../../../toolbox.inc.sh # ---- do the actual testing ---- result=PASS echo "++++ BEGINNING TEST" >$OUTPUTFILE # check that we can add a user key to the session keyring marker "ADD USER KEY" create_key --new=keyid user wibble stuff @s # read back what we put in it marker "PRINT PAYLOAD" print_key $keyid expect_payload payload "stuff" # check that we can update a user key marker "UPDATE USER KEY" update_key $keyid "lizard" # read back what we changed it to marker "PRINT UPDATED PAYLOAD" print_key $keyid expect_payload payload "lizard" # check that we can update a user key with hex-encoded data marker "UPDATE USER KEY HEX" update_key -x $keyid " 6c 697a 6172 64 78 " # read back what we changed it to marker "PRINT UPDATED PAYLOAD" print_key $keyid expect_payload payload "lizardx" # remove the key we added marker "UNLINK KEY" unlink_key $keyid @s echo "++++ FINISHED TEST: $result" >>$OUTPUTFILE # --- then report the results in the database --- toolbox_report_result $TEST $result keyutils-1.6.3/tests/keyctl/watch/000077500000000000000000000000001370111642500171355ustar00rootroot00000000000000keyutils-1.6.3/tests/keyctl/watch/bad-args/000077500000000000000000000000001370111642500206155ustar00rootroot00000000000000keyutils-1.6.3/tests/keyctl/watch/bad-args/runtest.sh000066400000000000000000000017301370111642500226560ustar00rootroot00000000000000#!/bin/bash . ../../../prepare.inc.sh . ../../../toolbox.inc.sh # ---- do the actual testing ---- if [ $have_notify = 0 ] then toolbox_skip_test $TEST "SKIPPING DUE TO LACK OF NOTIFICATION SUPPORT" exit 0 fi result=PASS echo "++++ BEGINNING TEST" >$OUTPUTFILE # Attempt to watch an invalid key marker "CHECK WATCH INVALID KEY" watch_key --fail 0 expect_error EINVAL # Add a user key to the session keyring for us to play with marker "ADD USER KEY" create_key --new=keyid user wibble stuff @s # Remove the key we just added marker "UNLINK KEY" unlink_key --wait $keyid @s # It should fail when we attempt to watch it marker "UPDATE UNLINKED KEY" watch_key --fail $keyid expect_error ENOKEY # Try a number of dodgy filters marker "CHECK DODGY FILTERS" watch_key --fail2 -fZ @s watch_key --fail2 -fZ -fQ @s watch_key --fail2 -f: @s echo "++++ FINISHED TEST: $result" >>$OUTPUTFILE # --- then report the results in the database --- toolbox_report_result $TEST $result keyutils-1.6.3/tests/keyctl/watch/noargs/000077500000000000000000000000001370111642500204265ustar00rootroot00000000000000keyutils-1.6.3/tests/keyctl/watch/noargs/runtest.sh000066400000000000000000000011041370111642500224620ustar00rootroot00000000000000#!/bin/bash . ../../../prepare.inc.sh . ../../../toolbox.inc.sh # ---- do the actual testing ---- result=PASS echo "++++ BEGINNING TEST" >$OUTPUTFILE # check that no arguments fails correctly marker "WATCH NO ARGS" expect_args_error keyctl watch # check that two arguments fail correctly marker "WATCH TWO ARGS" expect_args_error keyctl watch @s @s # Try a dodgy filter marker "CHECK BAD FILTER" expect_args_error keyctl watch_key -f 0 echo "++++ FINISHED TEST: $result" >>$OUTPUTFILE # --- then report the results in the database --- toolbox_report_result $TEST $result keyutils-1.6.3/tests/prepare.inc.sh000066400000000000000000000066701370111642500173070ustar00rootroot00000000000000# preparation script for running keyring tests # Find the relative path from pwd to the directory holding this file includes=${BASH_SOURCE[0]} includes=${includes%/*}/ # --- need to run in own session keyring watch_fd=0 if [ "$1" != "--inside-test-session" ] then session_name=RHTS/keyctl/$$ if keyctl supports notify >&/dev/null then # Create a session keyring and set up a watcher on it. The watch queue # is exposed on fd 9 inside the child process. echo "Running with watched session keyring $session_name" export watch_log=$PWD/watch.out export gc_log=$PWD/gc.out watch_fd=9 echo "starting" >$watch_log echo "starting" >$gc_log exec keyctl watch_session -n $session_name $watch_log $gc_log $watch_fd \ bash $0 --inside-test-session $@ || exit 8 else echo "Running with session keyring $session_name" exec keyctl session $session_name bash $0 --inside-test-session $@ || exit 8 fi else shift if [ "$KEYCTL_WATCH_FD" != "" ] then watch_fd=$KEYCTL_WATCH_FD fi fi # Set up for the Red Hat Test System RUNNING_UNDER_RHTS=0 if [ -x /usr/bin/rhts_environment.sh ] then PACKAGE=$(rpm -q --qf "%{name}" --whatprovides /bin/keyctl) . /usr/bin/rhts_environment.sh RUNNING_UNDER_RHTS=1 elif [ -z "$OUTPUTFILE" ] then OUTPUTFILE=$PWD/test.out echo -n >$OUTPUTFILE fi case `lsb_release -i -s` in Fedora*) OSDIST=Fedora;; RedHatEnterprise*) OSDIST=RHEL;; *) OSDIST=Unknown;; esac OSRELEASE=`lsb_release -r -s` KEYUTILSVER=`keyctl --version 2>/dev/null` if [ -n "$KEYUTILSVER" ] then : elif [ -x /bin/rpm ] then KEYUTILSVER=`rpm -q keyutils` else echo "Can't determine keyutils version" >&2 exit 9 fi echo "keyutils version: $KEYUTILSVER" KEYUTILSVER=`expr "$KEYUTILSVER" : '.*keyutils-\([0-9.]*\).*'` . $includes/version.inc.sh KERNELVER=`uname -r` # # Make sure the TEST envvar is set. # if [ -z "$TEST" ] then p=`pwd` case $p in */keyctl/*) TEST=keyctl/${p#*/keyctl/} ;; */bugzillas/*) TEST=bugzillas/${p#*/bugzillas/} ;; *) TEST=unknown ;; esac fi have_key_invalidate=0 have_big_key_type=0 have_dh_compute=0 have_restrict_keyring=0 have_notify=0 if keyctl supports capabilities >&/dev/null then eval `keyctl supports` else # # Work out whether key invalidation is supported by the kernel # if keyutils_at_or_later_than 1.5.6 && kernel_at_or_later_than 3.5-rc1 then have_key_invalidate=1 fi # # Work out whether the big_key type is supported by the kernel. # if [ $OSDIST = RHEL ] && ! version_less_than $OSRELEASE 7 then # big_key is backported to 3.10 for RHEL-7 have_big_key_type=1 elif kernel_at_or_later_than 3.13-rc1 then have_big_key_type=1 fi # # Work out whether Diffie-Hellman is supported by the kernel # if [ $OSDIST = RHEL ] then : elif keyutils_at_or_later_than 1.5.10 && kernel_at_or_later_than 4.7-rc1 then have_dh_compute=1 fi # # Work out whether keyring restrictions are supported by the kernel # if keyutils_at_or_later_than 1.6 && kernel_at_or_later_than 4.12-rc1 then have_restrict_keyring=1 fi fi # # Check if skipping of tests requiring root was requested # skip_root_required=0 if [ "$SKIPROOTREQ" = "yes" ] then skip_root_required=1 fi # # Check if skipping of tests requiring installation was requested # skip_install_required=0 if [ "$SKIPINSTALLREQ" = "yes" ] then skip_install_required=1 fi keyutils-1.6.3/tests/runtest.sh000066400000000000000000000015611370111642500165770ustar00rootroot00000000000000#!/bin/bash # set the $AUTOMATED environment variable to non-zero for automated mode # automated mode will run all the tests to completion # non-automated mode (default) stops running the test suite on the first error AUTOMATED=${AUTOMATED:-0} TESTS=$* PARENTTEST=${TEST} if [ `id -u` != 0 ] then echo "#### Some tests require root privileges." >&2 echo "#### It is recommended that this be run as root." >&2 fi for i in ${TESTS}; do export TEST=$i pushd $i >/dev/null echo "### RUNNING TEST $i" if [[ $AUTOMATED != 0 ]] ; then bash ./runtest.sh else bash ./runtest.sh || exit 1 fi popd >/dev/null done if [ `id -u` != 0 ] then echo "#### Some tests required root privileges." >&2 echo "#### They have been tested for the appropriate failure." >&2 echo "#### It is recommended that this be run as root." >&2 fi keyutils-1.6.3/tests/toolbox.inc.sh000066400000000000000000001200571370111642500173330ustar00rootroot00000000000000############################################################################### # # Copyright (C) 2005 Red Hat, Inc. All Rights Reserved. # Written by David Howells (dhowells@redhat.com) # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License # as published by the Free Software Foundation; either version # 2 of the License, or (at your option) any later version. # ############################################################################### echo === $OUTPUTFILE === endian=`file -L /proc/$$/exe` if expr "$endian" : '.* MSB \+\(pie executable\|executable\|shared object\).*' >&/dev/null then endian=BE elif expr "$endian" : '.* LSB \+\(pie executable\|executable\|shared object\).*' >&/dev/null then endian=LE else echo -e "+++ \e[31;1mCan't Determine Endianness\e[0m" echo "+++ Can't Determine Endianness" >>$OUTPUTFILE exit 2 fi maxtypelen=31 maxtype=`for ((i=0; i<$((maxtypelen)); i++)); do echo -n a; done` PAGE_SIZE=`getconf PAGESIZE` pagelen=$((PAGE_SIZE - 1)) fullpage=`for ((i=0; i<$((pagelen)); i++)); do echo -n a; done` string4095=`for ((i=0; i<4095; i++)); do echo -n a; done` if kernel_at_or_later_than 3.18 then maxdesc=$string4095 elif rhel6_kernel_at_or_later_than 2.6.32-589.el6 then maxdesc=$string4095 else maxdesc=$fullpage fi maxcall=$fullpage maxsquota=`grep '^ *0': /proc/key-users | sed s@.*/@@` key_gc_delay_file="/proc/sys/kernel/keys/gc_delay" if [ -f $key_gc_delay_file ]; then orig_gc_delay=`cat $key_gc_delay_file` else orig_gc_delay=300 fi function marker () { echo -e "+++ \e[33m$*\e[0m" echo +++ $* >>$OUTPUTFILE if [ "$watch_log" != "" ] then echo +++ $* >>$watch_log fi } function failed() { echo -e "\e[31;1mFAILED\e[0m" echo === FAILED === >>$OUTPUTFILE keyctl show >>$OUTPUTFILE echo ============== >>$OUTPUTFILE result=FAIL } function expect_args_error () { "$@" >>$OUTPUTFILE 2>&1 if [ $? != 2 ] then failed fi } function toolbox_report_result() { if [ $RUNNING_UNDER_RHTS = 1 ] then report_result $1 $2 fi if [ $2 = FAIL ] then exit 1 fi } function toolbox_skip_test() { echo "++++ SKIPPING TEST" >>$OUTPUTFILE marker "$2" toolbox_report_result $1 PASS } ############################################################################### # # Return true if the command is found in $PATH. If not, log that the test is # being skipped, report the result as PASS, and exit. # ############################################################################### function require_command () { which "$1" >&/dev/null if [ $? != 0 ] then toolbox_skip_test "SKIP DUE TO MISSING COMMAND: $1" exit 0 fi } function require_selinux () { if ! grep -q selinuxfs /proc/mounts; then toolbox_skip_test $TEST "SKIP DUE TO DISABLED SELINUX" exit 0 fi } ############################################################################### # # extract an error message from the log file and check it # ############################################################################### function expect_error () { my_varname=$1 my_errmsg="`tail -1 $OUTPUTFILE`" eval $my_varname="\"$my_errmsg\"" if [ $# != 1 ] then echo "Format: expect_error " >>$OUTPUTFILE failed fi case $1 in EPERM) my_err="Operation not permitted";; EAGAIN) my_err="Resource temporarily unavailable";; ENOENT) my_err="No such file or directory";; EEXIST) my_err="File exists";; ENOTDIR) my_err="Not a directory";; EACCES) my_err="Permission denied";; EINVAL) my_err="Invalid argument";; ENODEV) my_err="No such device";; ELOOP) my_err="Too many levels of symbolic links";; EOPNOTSUPP) my_err="Operation not supported";; EDEADLK) my_err="Resource deadlock avoided";; EDQUOT) my_err="Disk quota exceeded";; ENOKEY) my_err="Required key not available" old_err="Requested key not available" alt_err="Unknown error 126" ;; EKEYEXPIRED) my_err="Key has expired" alt_err="Unknown error 127" ;; EKEYREVOKED) my_err="Key has been revoked" alt_err="Unknown error 128" ;; EKEYREJECTED) my_err="Key has been rejected" alt_err="Unknown error 129" ;; *) echo "Unknown error message $1" >>$OUTPUTFILE failed ;; esac if expr "$my_errmsg" : ".*: $my_err" >&/dev/null then : elif [ "x$alt_err" != "x" ] && expr "$my_errmsg" : ".*: $alt_err" >&/dev/null then : elif [ "x$old_err" != "x" ] && expr "$my_errmsg" : ".*: $old_err" >&/dev/null then : else failed fi } ############################################################################### # # Watch a key for notifications. # ############################################################################### function watch_add_key () { my_keyid=$1 if [ $watch_fd = 0 ]; then return; fi keyctl watch_add $watch_fd $my_keyid || failed } ############################################################################### # # Check for a notification on the last or last-but-one lines of the # notification log. # ############################################################################### function check_notify () { if [ $watch_fd = 0 ]; then return; fi keyctl watch_sync $watch_fd || failed if [ "$1" = "-2" ] then shift my_logline="`tail -2 $watch_log | head -1`" else my_logline="`tail -1 $watch_log`" fi my_subtype=$1 case $my_subtype in revoked) my_key1=$2 ;; invalidated) my_key1=$2 ;; *) case $2 in @*) my_key1=`keyctl id $2` ;; *) my_key1=$2 esac ;; esac my_key2=$3 case $my_subtype in instantiated) exp="$my_key1 inst" ;; updated) exp="$my_key1 upd" ;; linked) exp="$my_key1 link $my_key2" ;; unlinked) exp="$my_key1 unlk $my_key2" ;; cleared) exp="$my_key1 clr" ;; revoked) exp="$my_key1 rev" ;; invalidated) exp="$my_key1 inv" ;; setattr) exp="$my_key1 attr" ;; *) echo "INCORRECT check_notify SUBTYPE" >&2 failed ;; esac if [ "$exp" != "$my_logline" ] then echo "\"$exp\"" != "\"$my_logline\"" echo "check_notify: \"$exp\"" != "\"$my_logline\"" >>$OUTPUTFILE echo "^^^ failed ^^^" >>$watch_log failed fi } ############################################################################### # # wait for a key to be destroyed (get removed from /proc/keys) # ############################################################################### function pause_till_key_destroyed () { echo "+++ WAITING FOR KEY TO BE DESTROYED" >>$OUTPUTFILE hexkeyid=`printf %08x $1` while grep $hexkeyid /proc/keys do sleep 1 done } ############################################################################### # # wait for a key to be unlinked # ############################################################################### function pause_till_key_unlinked () { echo "+++ WAITING FOR KEY TO BE UNLINKED" >>$OUTPUTFILE while true do echo keyctl unlink $1 $2 >>$OUTPUTFILE keyctl unlink $1 $2 >>$OUTPUTFILE 2>&1 if [ $? != 1 ] then failed fi my_errmsg="`tail -1 $OUTPUTFILE`" if ! expr "$my_errmsg" : ".*: No such file or directory" >&/dev/null then break fi sleep 1 done } ############################################################################### # # Get the ID of a key or keyring. # ############################################################################### function id_key () { my_exitval=0 case "x$1" in x--to=*) my_exitval=0 my_varname=${1#--to=} my_keyid=v ;; x--fail) my_exitval=1 my_keyid=x ;; x--fail2) my_exitval=2 my_keyid=x ;; *) echo "BAD id_key ARGUMENT" >&2 failed return ;; esac shift echo keyctl id "$@" >>$OUTPUTFILE keyctl id "$@" >>$OUTPUTFILE 2>&1 e=$? if [ $e == $my_exitval ] then if [ $e = 0 ] then got_keyid="`tail -1 $OUTPUTFILE`" if expr "$got_keyid" : '[1-9][0-9]*' >&/dev/null then if [ $my_keyid == v ] then eval $my_varname=$got_keyid fi else echo "CAN'T EXTRACT KEY ID FROM create_key OUTPUT" >&2 eval $my_varname=no result=FAIL fi fi else failed fi } ############################################################################### # # request a key and attach it to the new keyring # ############################################################################### function request_key () { my_exitval=0 case "x$1" in x--new=*) my_exitval=0 my_varname=${1#--new=} my_keyid=v ;; x--old=*) my_exitval=0 my_keyid=${1#--old=} ;; x--fail) my_exitval=1 my_keyid=x ;; *) echo "BAD request_key ARGUMENT" >&2 failed return ;; esac shift my_keyring=$3 echo keyctl request "$@" >>$OUTPUTFILE keyctl request "$@" >>$OUTPUTFILE 2>&1 e=$? if [ $e == $my_exitval ] then if [ $e = 0 ] then got_keyid="`tail -1 $OUTPUTFILE`" if expr "$got_keyid" : '[1-9][0-9]*' >&/dev/null then if [ $my_keyid == v ] then eval $my_varname=$got_keyid watch_add_key $got_keyid fi if [ $# = 3 ] then check_notify linked $my_keyring $got_keyid fi else echo "CAN'T EXTRACT KEY ID FROM create_key OUTPUT" >&2 eval $my_varname=no result=FAIL fi fi else failed fi } ############################################################################### # # request a key and attach it to the new keyring, calling out if necessary # ############################################################################### function request_key_callout () { my_exitval=0 case "x$1" in x--new=*) my_exitval=0 my_varname=${1#--new=} my_keyid=v ;; x--old=*) my_exitval=0 my_keyid=${1#--old=} ;; x--fail) my_exitval=1 my_keyid=x ;; *) echo "BAD request_key_callout ARGUMENT" >&2 failed return ;; esac shift my_keyring=$4 echo keyctl request2 "$@" >>$OUTPUTFILE keyctl request2 "$@" >>$OUTPUTFILE 2>&1 e=$? if [ $e == $my_exitval ] then if [ $e = 0 ] then got_keyid="`tail -1 $OUTPUTFILE`" if expr "$got_keyid" : '[1-9][0-9]*' >&/dev/null then if [ $my_keyid == v ] then eval $my_varname=$got_keyid watch_add_key $got_keyid if [ $# = 4 ] then check_notify -2 linked $my_keyring $got_keyid fi else if [ $# = 4 ] then check_notify linked $my_keyring $got_keyid fi fi else echo "CAN'T EXTRACT KEY ID FROM create_key OUTPUT" >&2 eval $my_varname=no result=FAIL fi fi else failed fi } ############################################################################### # # request a key and attach it to the new keyring, calling out if necessary and # passing the callout data in on stdin # ############################################################################### function prequest_key_callout () { my_exitval=0 case "x$1" in x--new=*) my_exitval=0 my_varname=${1#--new=} my_keyid=v ;; x--old=*) my_exitval=0 my_keyid=${1#--old=} ;; x--fail) my_exitval=1 my_keyid=x ;; *) echo "BAD prequest_key_callout ARGUMENT" >&2 failed return ;; esac shift data="$1" shift my_keyring=$3 echo echo -n $data \| keyctl prequest2 "$@" >>$OUTPUTFILE echo -n $data | keyctl prequest2 "$@" >>$OUTPUTFILE 2>&1 e=$? if [ $e == $my_exitval ] then if [ $e = 0 ] then got_keyid="`tail -1 $OUTPUTFILE`" if expr "$got_keyid" : '[1-9][0-9]*' >&/dev/null then if [ $my_keyid == v ] then eval $my_varname=$got_keyid watch_add_key $got_keyid if [ $# = 4 ] then check_notify -2 linked $my_keyring $got_keyid fi else if [ $# = 3 ] then check_notify linked $my_keyring $got_keyid fi fi else echo "CAN'T EXTRACT KEY ID FROM create_key OUTPUT" >&2 eval $my_varname=no result=FAIL fi fi else failed fi } ############################################################################### # # create a key and attach it to the new keyring # ############################################################################### function create_key () { my_exitval=0 case "x$1" in x--new=*) my_exitval=0 my_varname=${1#--new=} my_keyid=v ;; x--update=*) my_exitval=0 my_keyid=${1#--update=} ;; x--fail) my_exitval=1 my_keyid=x ;; *) echo "BAD create_key ARGUMENT" >&2 failed return ;; esac shift if [ "$1" = "-x" ] then my_keyring=$5 else my_keyring=$4 fi echo keyctl add "$@" >>$OUTPUTFILE keyctl add "$@" >>$OUTPUTFILE 2>&1 e=$? if [ $e == $my_exitval ] then if [ $e = 0 ] then got_keyid="`tail -1 $OUTPUTFILE`" if expr "$got_keyid" : '[1-9][0-9]*' >&/dev/null then if [ $my_keyid == v ] then eval $my_varname=$got_keyid watch_add_key $got_keyid check_notify linked $my_keyring $got_keyid else check_notify updated $got_keyid fi else echo "CAN'T EXTRACT KEY ID FROM create_key OUTPUT" >&2 eval $my_varname=no result=FAIL fi fi else failed fi } ############################################################################### # # create a key and attach it to the new keyring, piping in the data # ############################################################################### function pcreate_key () { my_exitval=0 case "x$1" in x--new=*) my_exitval=0 my_varname=${1#--new=} my_keyid=v ;; x--update=*) my_exitval=0 my_keyid=${1#--update=} ;; x--fail) my_exitval=1 my_keyid=x ;; *) echo "BAD pcreate_key ARGUMENT" >&2 failed return ;; esac shift data="$1" shift if [ "$1" = "-x" ] then my_keyring=$4 else my_keyring=$3 fi echo echo -n $data \| keyctl padd "$@" >>$OUTPUTFILE echo -n $data | keyctl padd "$@" >>$OUTPUTFILE 2>&1 e=$? if [ $e == $my_exitval ] then if [ $e = 0 ] then got_keyid="`tail -1 $OUTPUTFILE`" if expr "$got_keyid" : '[1-9][0-9]*' >&/dev/null then if [ $my_keyid == v ] then eval $my_varname=$got_keyid watch_add_key $got_keyid check_notify linked $my_keyring $got_keyid else check_notify updated $got_keyid fi else echo "CAN'T EXTRACT KEY ID FROM pcreate_key OUTPUT" >&2 eval $my_varname=no result=FAIL fi fi else failed fi } ############################################################################### # # create a key and attach it to the new keyring, piping in the data # ############################################################################### function pcreate_key_by_size () { my_exitval=0 case "x$1" in x--new=*) my_exitval=0 my_varname=${1#--new=} my_keyid=v ;; x--update=*) my_exitval=0 my_keyid=${1#--update=} ;; x--fail) my_exitval=1 my_keyid=x ;; *) echo "BAD pcreate_key_by_size ARGUMENT" >&2 failed return ;; esac shift data="$1" shift my_keyring=$3 echo dd if=/dev/zero count=1 bs=$data \| keyctl padd "$@" >>$OUTPUTFILE dd if=/dev/zero count=1 bs=$data 2>/dev/null | keyctl padd "$@" >>$OUTPUTFILE 2>&1 e=$? if [ $e == $my_exitval ] then if [ $e = 0 ] then got_keyid="`tail -1 $OUTPUTFILE`" if expr "$got_keyid" : '[1-9][0-9]*' >&/dev/null then if [ $my_keyid == v ] then eval $my_varname=$got_keyid watch_add_key $got_keyid check_notify linked $my_keyring $got_keyid else check_notify updated $got_keyid fi else echo "CAN'T EXTRACT KEY ID FROM pcreate_key_by_size OUTPUT" >&2 eval $my_varname=no result=FAIL fi fi else failed fi } ############################################################################### # # create a key and attach it to the new keyring # ############################################################################### function create_keyring () { my_exitval=0 case "x$1" in x--new=*) my_exitval=0 my_varname=${1#--new=} my_keyid=v ;; x--fail) my_exitval=1 my_keyid=x ;; *) echo "BAD create_keyring ARGUMENT" >&2 failed return ;; esac shift my_keyring=$2 echo keyctl newring "$@" >>$OUTPUTFILE keyctl newring "$@" >>$OUTPUTFILE 2>&1 e=$? if [ $e == $my_exitval ] then if [ $e = 0 ] then got_keyid="`tail -1 $OUTPUTFILE`" if expr "$got_keyid" : '[1-9][0-9]*' >&/dev/null then eval $my_varname=$got_keyid watch_add_key $got_keyid check_notify linked $my_keyring $got_keyid else echo "CAN'T EXTRACT KEY ID FROM create_keyring OUTPUT" >&2 eval $my_varname=no result=FAIL fi fi else failed fi } ############################################################################### # # prettily list a keyring # ############################################################################### function pretty_list_keyring () { my_exitval=0 if [ "x$1" = "x--fail" ] then my_exitval=1 shift fi echo keyctl list $1 >>$OUTPUTFILE keyctl list $1 >>$OUTPUTFILE 2>&1 if [ $? != $my_exitval ] then failed fi } ############################################################################### # # list a keyring # ############################################################################### function list_keyring () { my_exitval=0 if [ "x$1" = "x--fail" ] then my_exitval=1 shift fi echo keyctl rlist $1 >>$OUTPUTFILE keyctl rlist $1 >>$OUTPUTFILE 2>&1 if [ $? != $my_exitval ] then failed fi } ############################################################################### # # extract a keyring listing from the log file and see if a key ID is contained # therein # ############################################################################### function expect_keyring_rlist () { my_varname=$1 my_rlist="`tail -1 $OUTPUTFILE`" eval $my_varname="\"$my_rlist\"" if [ $# = 2 -o $# = 3 ] then if [ "$2" = "empty" ] then if [ "x$my_rlist" != "x" ] then failed fi else my_keyid=$2 my_found=0 my_expected=1 if [ $# = 3 -a "x$3" = "x--absent" ]; then my_expected=0; fi for k in $my_rlist do if [ $k = $my_keyid ] then my_found=1 break; fi done if [ $my_found != $my_expected ] then failed fi fi fi } ############################################################################### # # prettily describe a key # ############################################################################### function pretty_describe_key () { my_exitval=0 if [ "x$1" = "x--fail" ] then my_exitval=1 shift fi echo keyctl describe $1 >>$OUTPUTFILE keyctl describe $1 >>$OUTPUTFILE 2>&1 if [ $? != $my_exitval ] then failed fi } ############################################################################### # # describe a key # ############################################################################### function describe_key () { my_exitval=0 if [ "x$1" = "x--fail" ] then my_exitval=1 shift fi echo keyctl rdescribe $1 "@" >>$OUTPUTFILE keyctl rdescribe $1 "@" >>$OUTPUTFILE 2>&1 if [ $? != $my_exitval ] then failed fi } ############################################################################### # # extract a raw key description from the log file and check it # ############################################################################### function expect_key_rdesc () { my_varname=$1 my_rdesc="`tail -1 $OUTPUTFILE`" eval $my_varname="\"$my_rdesc\"" if ! expr "$my_rdesc" : "$2" >&/dev/null then failed fi } ############################################################################### # # read a key's payload as a hex dump # ############################################################################### function read_key () { my_exitval=0 if [ "x$1" = "x--fail" ] then my_exitval=1 shift fi echo keyctl read $1 >>$OUTPUTFILE keyctl read $1 >>$OUTPUTFILE 2>&1 if [ $? != $my_exitval ] then failed fi } ############################################################################### # # read a key's payload as a printable string # ############################################################################### function print_key () { my_exitval=0 if [ "x$1" = "x--fail" ] then my_exitval=1 shift fi echo keyctl print $1 >>$OUTPUTFILE keyctl print $1 >>$OUTPUTFILE 2>&1 if [ $? != $my_exitval ] then failed fi } ############################################################################### # # pipe a key's raw payload to stdout # ############################################################################### function pipe_key () { my_exitval=0 if [ "x$1" = "x--fail" ] then my_exitval=1 shift fi echo keyctl pipe $1 >>$OUTPUTFILE keyctl pipe $1 >>$OUTPUTFILE 2>&1 if [ $? != $my_exitval ] then failed fi } ############################################################################### # # pipe a key's raw payload through md5sum # ############################################################################### function md5sum_key () { my_exitval=0 if [ "x$1" = "x--fail" ] then my_exitval=1 shift fi echo keyctl pipe $1 \| md5sum \| cut -c1-32 >>$OUTPUTFILE keyctl pipe $1 | md5sum | cut -c1-32 >>$OUTPUTFILE 2>&1 if [ $? != $my_exitval ] then failed fi } ############################################################################### # # extract a printed payload from the log file # ############################################################################### function expect_payload () { my_varname=$1 my_payload="`tail -1 $OUTPUTFILE`" eval $my_varname="\"$my_payload\"" if [ $# == 2 -a "x$my_payload" != "x$2" ] then failed fi } ############################################################################### # # extract multiline output from the log file # ############################################################################### function expect_multiline () { my_varname=$1 my_linecount="`echo \"$2\" | wc -l`" my_payload=$(tail -$my_linecount $OUTPUTFILE) eval $my_varname="\"$my_payload\"" if [ $# != 2 -o "x$my_payload" != "x$2" ] then failed fi } ############################################################################### # # revoke a key # ############################################################################### function revoke_key () { my_exitval=0 if [ "x$1" = "x--fail" ] then my_exitval=1 shift fi echo keyctl revoke $1 >>$OUTPUTFILE keyctl revoke $1 >>$OUTPUTFILE 2>&1 e=$? if [ $e == $my_exitval ] then if [ $e = 0 ] then check_notify revoked $1 fi else failed fi } ############################################################################### # # unlink a key from a keyring # ############################################################################### function unlink_key () { my_exitval=0 if [ "x$1" = "x--fail" ] then my_exitval=1 shift fi my_wait=0 if [ "x$1" = "x--wait" ] then my_wait=1 shift fi echo keyctl unlink $1 $2 >>$OUTPUTFILE keyctl unlink $1 $2 >>$OUTPUTFILE 2>&1 e=$? if [ $e = $my_exitval ] then if [ $e == 0 -a $# = 2 ] then check_notify unlinked $2 $1 fi else failed fi # keys are destroyed lazily if [ $my_wait = 1 ] then pause_till_key_unlinked $1 $2 fi } ############################################################################### # # extract a message about the number of keys unlinked # ############################################################################### function expect_unlink_count () { my_varname=$1 my_nunlinks="`tail -1 $OUTPUTFILE`" if ! expr "$my_nunlinks" : '^[0-9][0-9]* links removed$' then failed fi my_nunlinks=`echo $my_nunlinks | awk '{printf $1}'` eval $my_varname="\"$my_nunlinks\"" if [ $# == 2 -a $my_nunlinks != $2 ] then failed fi } ############################################################################### # # update a key from a keyring # ############################################################################### function update_key () { my_exitval=0 if [ "x$1" = "x--fail" ] then my_exitval=1 shift fi echo keyctl update "$@" >>$OUTPUTFILE keyctl update "$@" >>$OUTPUTFILE 2>&1 e=$? if [ $e == $my_exitval ] then if [ $e = 0 ] then if [ "$1" = "-x" ] then shift fi check_notify updated $1 fi else failed fi } ############################################################################### # # update a key from a keyring, piping the data in over stdin # ############################################################################### function pupdate_key () { my_exitval=0 if [ "x$1" = "x--fail" ] then my_exitval=1 shift fi echo keyctl pupdate "$@" >>$OUTPUTFILE keyctl pupdate "$@" >>$OUTPUTFILE 2>&1 e=$? if [ $e == $my_exitval ] then if [ $e = 0 ] then check_notify updated $1 fi else failed fi } ############################################################################### # # clear a keyring # ############################################################################### function clear_keyring () { my_exitval=0 if [ "x$1" = "x--fail" ] then my_exitval=1 shift fi echo keyctl clear $1 >>$OUTPUTFILE keyctl clear $1 >>$OUTPUTFILE 2>&1 e=$? if [ $e == $my_exitval ] then if [ $e = 0 ] then check_notify cleared $1 fi else failed fi } ############################################################################### # # restrict a keyring # ############################################################################### function restrict_keyring () { my_exitval=0 if [ "x$1" = "x--fail" ] then my_exitval=1 shift fi echo keyctl restrict_keyring $1 $2 $3 >>$OUTPUTFILE keyctl restrict_keyring $1 $2 $3 >>$OUTPUTFILE 2>&1 if [ $? != $my_exitval ] then failed fi } ############################################################################### # # link a key to a keyring # ############################################################################### function link_key () { my_exitval=0 if [ "x$1" = "x--fail" ] then my_exitval=1 shift fi echo keyctl link $1 $2 >>$OUTPUTFILE keyctl link $1 $2 >>$OUTPUTFILE 2>&1 e=$? if [ $e == $my_exitval ] then if [ $e == 0 ] then check_notify linked $2 $1 fi else failed fi } ############################################################################### # # search for a key in a keyring # ############################################################################### function search_for_key () { my_exitval=0 case "x$1" in x--expect=*) my_exitval=0 my_keyid=${1#--expect=} ;; x--fail) my_exitval=1 my_keyid=x ;; *) echo "BAD search_for_key ARGUMENT" >&2 failed return ;; esac shift echo keyctl search "$@" >>$OUTPUTFILE keyctl search "$@" >>$OUTPUTFILE 2>&1 e=$? if [ $e == $my_exitval ] then if [ $e = 0 ] then got_keyid="`tail -1 $OUTPUTFILE`" if expr "$got_keyid" : '[1-9][0-9]*' >&/dev/null then if [ $got_keyid = $my_keyid ] then if [ $e == 0 -a $# == 4 ] then check_notify linked $4 $got_keyid fi else echo "KEY MISMATCH $got_keyid != $my_keyid" >&2 failed fi else echo "CAN'T EXTRACT KEY ID FROM search_for_key OUTPUT" >&2 eval $my_varname=no result=FAIL fi fi else failed fi } ############################################################################### # # set the permissions mask on a key # ############################################################################### function set_key_perm () { my_exitval=0 if [ "x$1" = "x--fail" ] then my_exitval=1 shift fi echo keyctl setperm "$@" >>$OUTPUTFILE keyctl setperm "$@" >>$OUTPUTFILE 2>&1 e=$? if [ $e == $my_exitval ] then if [ $e = 0 ] then check_notify setattr $1 fi else failed fi } ############################################################################### # # set the ownership of a key # ############################################################################### function chown_key () { my_exitval=0 if [ "x$1" = "x--fail" ] then my_exitval=1 shift fi echo keyctl chown "$@" >>$OUTPUTFILE keyctl chown "$@" >>$OUTPUTFILE 2>&1 e=$? if [ $e == $my_exitval ] then if [ $e = 0 ] then check_notify setattr $1 fi else failed fi } ############################################################################### # # set the group ownership of a key # ############################################################################### function chgrp_key () { my_exitval=0 if [ "x$1" = "x--fail" ] then my_exitval=1 shift fi echo keyctl chgrp "$@" >>$OUTPUTFILE keyctl chgrp "$@" >>$OUTPUTFILE 2>&1 e=$? if [ $e == $my_exitval ] then if [ $e = 0 ] then check_notify setattr $1 fi else failed fi } ############################################################################### # # run as a new session # ############################################################################### function new_session () { my_exitval=0 if [ "x$1" = "x--fail" ] then my_exitval=1 shift fi echo keyctl session "$@" >>$OUTPUTFILE keyctl session "$@" >>$OUTPUTFILE 2>&1 if [ $? != $my_exitval ] then failed fi } ############################################################################### # # Create a new session and attach to the parent process (ie. the script) # ############################################################################### function new_session_to_parent () { my_exitval=0 if [ "x$1" = "x--fail" ] then my_exitval=1 shift fi echo keyctl new_session "$@" >>$OUTPUTFILE keyctl new_session "$@" >>$OUTPUTFILE 2>&1 if [ $? != $my_exitval ] then failed fi } ############################################################################### # # instantiate a key # ############################################################################### function instantiate_key () { my_exitval=0 if [ "x$1" = "x--fail" ] then my_exitval=1 shift fi echo keyctl instantiate "$@" >>$OUTPUTFILE keyctl instantiate "$@" >>$OUTPUTFILE 2>&1 if [ $? != $my_exitval ] then failed fi } ############################################################################### # # instantiate a key, piping the data in over stdin # ############################################################################### function pinstantiate_key () { my_exitval=0 if [ "x$1" = "x--fail" ] then my_exitval=1 shift fi data="$1" shift echo echo -n $data \| keyctl pinstantiate "$@" >>$OUTPUTFILE echo -n $data | keyctl pinstantiate "$@" >>$OUTPUTFILE 2>&1 if [ $? != $my_exitval ] then failed fi } ############################################################################### # # reject a key # ############################################################################### function reject_key () { my_exitval=0 if [ "x$1" = "x--fail" ] then my_exitval=1 shift fi echo keyctl reject "$@" >>$OUTPUTFILE keyctl reject "$@" >>$OUTPUTFILE 2>&1 if [ $? != $my_exitval ] then failed fi } ############################################################################### # # negate a key # ############################################################################### function negate_key () { my_exitval=0 if [ "x$1" = "x--fail" ] then my_exitval=1 shift fi echo keyctl negate "$@" >>$OUTPUTFILE keyctl negate "$@" >>$OUTPUTFILE 2>&1 if [ $? != $my_exitval ] then failed fi } ############################################################################### # # set a key's expiry time # ############################################################################### function timeout_key () { my_exitval=0 if [ "x$1" = "x--fail" ] then my_exitval=1 shift fi echo keyctl timeout $1 $2 >>$OUTPUTFILE keyctl timeout $1 $2 >>$OUTPUTFILE 2>&1 e=$? if [ $e == $my_exitval ] then if [ $e = 0 ] then check_notify setattr $1 fi else failed fi } ############################################################################### # # Invalidate a key # ############################################################################### function invalidate_key () { my_exitval=0 if [ "x$1" = "x--fail" ] then my_exitval=1 shift fi echo keyctl invalidate $1 >>$OUTPUTFILE keyctl invalidate $1 >>$OUTPUTFILE 2>&1 e=$? if [ $e == $my_exitval ] then if [ $e = 0 ] then check_notify invalidated $1 fi else failed fi } ############################################################################### # # Do a DH computation # ############################################################################### function dh_compute () { my_exitval=0 if [ "x$1" = "x--fail" ] then my_exitval=1 shift fi echo keyctl dh_compute $@ >>$OUTPUTFILE keyctl dh_compute $@ >>$OUTPUTFILE 2>&1 if [ $? != $my_exitval ] then failed fi } ############################################################################### # # Do a DH computation post-processed by a KDF # ############################################################################### function dh_compute_kdf () { my_exitval=0 if [ "x$1" = "x--fail" ] then my_exitval=1 shift fi echo keyctl dh_compute_kdf $@ >>$OUTPUTFILE keyctl dh_compute_kdf $@ >>$OUTPUTFILE 2>&1 if [ $? != $my_exitval ] then failed fi } ############################################################################### # # Do a DH computation post-processed by a KDF with other information # ############################################################################### function dh_compute_kdf_oi () { my_exitval=0 if [ "x$1" = "x--fail" ] then my_exitval=1 shift fi echo keyctl dh_compute_kdf_oi $@ >>$OUTPUTFILE keyctl dh_compute_kdf_oi $@ >>$OUTPUTFILE 2>&1 if [ $? != $my_exitval ] then failed fi } ############################################################################### # # Move a key between keyrings # ############################################################################### function move_key () { my_exitval=0 if [ "x$1" = "x--fail" ] then my_exitval=1 shift fi echo keyctl move $* >>$OUTPUTFILE keyctl move $* >>$OUTPUTFILE 2>&1 e=$? if [ $e = $my_exitval ] then if [ "x$1" = "x-f" ]; then shift; fi if [ $e = 0 -a $2 != $3 ] then check_notify -2 unlinked $2 $1 check_notify linked $3 $1 fi else failed fi } ############################################################################### # # Query supported features # ############################################################################### function supports () { my_exitval=0 if [ "x$1" = "x--fail" ] then my_exitval=1 shift elif [ "x$1" = "x--unrecognised" ] then my_exitval=3 shift fi echo keyctl supports $* >>$OUTPUTFILE keyctl supports $* >>$OUTPUTFILE 2>&1 err=$? if [ $err != $my_exitval ] then echo exitcode=$err >>$OUTPUTFILE failed fi } ############################################################################### # # Make sure we sleep at least N seconds # ############################################################################### function sleep_at_least () { my_now=`date +%s` my_done_at=$(($my_now+$1+1)) sleep $1 while [ `date +%s` -lt $my_done_at ] do # Sleep in 1/50th of a second bursts till the time catches up sleep .02 done } ############################################################################### # # set gc delay time, return original value # ############################################################################### function set_gc_delay() { delay=$1 if [ -f $key_gc_delay_file ]; then echo $delay > $key_gc_delay_file echo "Set $key_gc_delay_file to $delay, orig: $orig_gc_delay" fi } ############################################################################### # # watch a key # ############################################################################### function watch_key () { my_exitval=0 if [ "x$1" = "x--fail" ] then my_exitval=1 shift elif [ "x$1" = "x--fail2" ] then my_exitval=2 shift fi echo keyctl watch "$@" >>$OUTPUTFILE nice --adjustment=-3 keyctl watch "$@" >>$PWD/notify.log 2>>$OUTPUTFILE if [ $? != $my_exitval ] then failed fi } ############################################################################### # # Check for a notification # # expect_notification [--filter=[i|p|l|n|c|r|v|s]] [] # ############################################################################### function expect_notification () { local want local filter="" case "x$1" in x--filter*) case $1 in --filter=) filter=;; --filter=i) filter=inst;; --filter=p) filter=upd;; --filter=l) filter=link;; --filter=n) filter=unlk;; --filter=c) filter=clr;; --filter=r) filter=rev;; --filter=v) filter=inv;; --filter=s) filter=attr;; *) echo "Unknown param $1 to expect_notification()" >&2 exit 2 ;; esac shift ;; esac if [ $# = 2 ] then want="$1 $2" op=$2 elif [ $# = 3 ] then want="$1 $2 $3" op=$2 else echo "Wrong parameters to expect_notification" >&2 exit 2 fi if tail -3 $PWD/notify.log | grep "^${want}\$" >/dev/null then echo "Found notification '$*'" >>$OUTPUTFILE if [ "$filter" != "" -a $op != "$filter" ] then echo "Notification '$want' should be filtered" >&2 failed fi else echo "Notification '$*' not present" >>$OUTPUTFILE if [ "$filter" = "" ] then echo "Missing notification '$want'" >&2 failed elif [ $op = "$filter" ] then echo "Notification unexpectedly filtered '$want' $filter" >&2 failed fi fi } ############################################################################### # # Note the creation of a new key # # expect_new_key [] # ############################################################################### function xxx_expect_new_key () { my_varname=$1 my_keyring=$2 my_keyid="`tail -1 $OUTPUTFILE`" if expr "$my_keyid" : '[1-9][0-9]*' >&/dev/null then eval $my_varname=$my_keyid if [ $# = 3 -a "x$my_keyid" != "x$2" ] then failed fi watch_add_key $my_keyid check_notify linked $my_keyring $my_keyid else eval $my_varname=no result=FAIL fi } ############################################################################### # # Note implicit update of a key # # implicit_update # ############################################################################### function xxx_implicit_update () { my_keyid=$1 got_keyid="`tail -1 $OUTPUTFILE`" if expr "$got_keyid" : '[1-9][0-9]*' >&/dev/null then if [ "x$got_keyid" == "x$my_keyid" ] then check_notify updated $my_keyid else failed fi else result=FAIL fi } ############################################################################### # # Note the explicit update of new key # ############################################################################### function xxx_key_updated () { my_keyid=$1 check_notify updated $my_keyid } ############################################################################### # # extract a key ID from the log file # ############################################################################### function xxx_expect_found_key () { my_keyid="`tail -1 $OUTPUTFILE`" if expr "$my_keyid" : '[1-9][0-9]*' >&/dev/null then if [ "x$my_keyid" != "x$1" ] then failed fi else eval $my_varname=no result=FAIL fi } keyutils-1.6.3/tests/vercmp.sh000066400000000000000000000014431370111642500163660ustar00rootroot00000000000000# Commandline-driver tester for version comparison shell functions # ############################################################################### # # Copyright (C) 2013 Red Hat, Inc. All Rights Reserved. # Written by David Howells (dhowells@redhat.com) # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License # as published by the Free Software Foundation; either version # 2 of the License, or (at your option) any later version. # ############################################################################### . ./version.inc.sh # # Compare versions # if [ "$1" = "" -o "$2" = "" ] then echo "Missing version parameters" >&2 exit 2 fi if version_less_than $1 $2 then echo "$1 < $2" else echo "$1 >= $2" fi keyutils-1.6.3/tests/version.inc.sh000066400000000000000000000113671370111642500173350ustar00rootroot00000000000000# Version comparison shell functions # ############################################################################### # # Copyright (C) 2005, 2013 Red Hat, Inc. All Rights Reserved. # Written by David Howells (dhowells@redhat.com) # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License # as published by the Free Software Foundation; either version # 2 of the License, or (at your option) any later version. # ############################################################################### ############################################################################### # # compare version numbers to see if the first is less (older) than the second # ############################################################################### function version_less_than () { a=$1 b=$2 if [ "$a" = "$b" ] then return 1 fi # grab the leaders a_version=${a%%-*} a_release=${a#*-} b_version=${b%%-*} b_release=${b#*-} if [ "$a_version" = "$b_version" ] then case "$a_release" in rc[0-9]*) case "$b_release" in rc[0-9]*) __version_less_than_dot "${a_release#rc}" "${b_release#rc}" return $? ;; *) return 0; ;; esac ;; esac case "$b_release" in rc[0-9]*) return 1; ;; esac if [ "$a_version" = "$a" -o "$b_version" = "$b" ] then if [ "$a_version" = "$b_version" ] then [ "$a_version" = "$a" ] else __version_less_than_dot "$a_version" "$b_version" fi fi __version_less_than_dot "$a_release" "$b_release" else __version_less_than_dot "$a_version" "$b_version" fi } function __version_less_than_dot () { a=$1 b=$2 if [ "$a" = "$b" ] then return 1 fi # grab the leaders x=${a%%.*} y=${b%%.*} if [ "$x" = "$a" -o "$y" = "$b" ] then if [ "$x" = "$y" ] then [ "$x" = "$a" ] else expr "$x" \< "$y" >/dev/null fi elif [ "$x" = "$y" ] then __version_less_than_dot "${a#*.}" "${b#*.}" else expr "$x" \< "$y" >/dev/null fi } ############################################################################### # # Return true if the keyutils package being tested is older than the given # version. # ############################################################################### function keyutils_older_than () { version_less_than $KEYUTILSVER $1 } ############################################################################### # # Return true if the keyutils package being tested is at or later than the # given version. # ############################################################################### function keyutils_at_or_later_than () { ! keyutils_older_than $1 } ############################################################################### # # Return true if the keyutils package being tested is newer than the given # version. # ############################################################################### function keyutils_newer_than () { version_less_than $1 $KEYUTILSVER } ############################################################################### # # Return true if the keyutils package being tested is at or older than the # given version. # ############################################################################### function keyutils_at_or_older_than () { ! keyutils_newer_than $1 } ############################################################################### # # Return true if the kernel being tested is older than the given version. # ############################################################################### function kernel_older_than () { version_less_than $KERNELVER $1 } ############################################################################### # # Return true if the kernel being tested is at or later than the given version. # ############################################################################### function kernel_at_or_later_than () { ! kernel_older_than $1 } ############################################################################### # # Return true if the kernel being tested is a RHEL-6 kernel and is at or later # than the given version. # ############################################################################### function rhel6_kernel_at_or_later_than () { case $OSDIST-$OSRELEASE in RHEL-6.*) ! kernel_older_than $1 ;; *) false ;; esac } ############################################################################### # # Return true if the kernel being tested is a RHEL-7 kernel and is at or later # than the given version. # ############################################################################### function rhel7_kernel_at_or_later_than () { case $OSDIST-$OSRELEASE in RHEL-7.*) ! kernel_older_than $1 ;; *) false ;; esac } keyutils-1.6.3/version.lds000066400000000000000000000033111370111642500155610ustar00rootroot00000000000000KEYUTILS_0.3 { /* primary syscalls; may be overridden by glibc */ add_key; request_key; keyctl; /* management functions */ keyctl_chown; keyctl_clear; keyctl_describe; keyctl_describe_alloc; keyctl_get_keyring_ID; keyctl_instantiate; keyctl_join_session_keyring; keyctl_link; keyctl_negate; keyctl_read; keyctl_read_alloc; keyctl_revoke; keyctl_search; keyctl_setperm; keyctl_set_reqkey_keyring; keyctl_unlink; keyctl_update; }; KEYUTILS_1.0 { /* management functions */ keyctl_assume_authority; keyctl_set_timeout; } KEYUTILS_0.3; KEYUTILS_1.3 { /* management functions */ keyctl_get_security; keyctl_get_security_alloc; keyctl_session_to_parent; } KEYUTILS_1.0; KEYUTILS_1.4 { /* management functions */ keyctl_reject; keyctl_instantiate_iov; keyctl_invalidate; /* utility functions */ recursive_key_scan; recursive_session_key_scan; } KEYUTILS_1.3; KEYUTILS_1.5 { /* management functions */ keyctl_get_persistent; /* utility functions */ find_key_by_type_and_desc; } KEYUTILS_1.4; KEYUTILS_1.6 { /* management functions */ keyctl_dh_compute; keyctl_dh_compute_alloc; keyctl_pkey_query; keyctl_pkey_encrypt; keyctl_pkey_decrypt; keyctl_pkey_sign; keyctl_pkey_verify; } KEYUTILS_1.5; KEYUTILS_1.7 { /* management functions */ keyctl_restrict; keyctl_dh_compute_kdf; keyctl_dh_compute_kdf_alloc; } KEYUTILS_1.6; KEYUTILS_1.8 { /* Public key cryptography functions */ keyctl_pkey_query; keyctl_pkey_encrypt; keyctl_pkey_decrypt; keyctl_pkey_sign; keyctl_pkey_verify; } KEYUTILS_1.7; KEYUTILS_1.9 { /* Management functions */ keyctl_move; keyctl_capabilities; } KEYUTILS_1.8; KEYUTILS_1.10 { /* Management functions */ keyctl_watch_key; } KEYUTILS_1.9; keyutils-1.6.3/watch_queue.h000066400000000000000000000072511370111642500160620ustar00rootroot00000000000000/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #ifndef _KEYUTILS_LINUX_WATCH_QUEUE_H #define _KEYUTILS_LINUX_WATCH_QUEUE_H #include #include #define O_NOTIFICATION_PIPE O_EXCL /* Parameter to pipe2() selecting notification pipe */ #define IOC_WATCH_QUEUE_SET_SIZE _IO('W', 0x60) /* Set the size in pages */ #define IOC_WATCH_QUEUE_SET_FILTER _IO('W', 0x61) /* Set the filter */ #define PIPE_IOC_SYNC _IO('W', 0x62) /* Wait for data in pipe to be read */ enum watch_notification_type { WATCH_TYPE_META = 0, /* Special record */ WATCH_TYPE_KEY_NOTIFY = 1, /* Key change event notification */ WATCH_TYPE_BLOCK_NOTIFY = 2, /* Block layer event notification */ WATCH_TYPE_USB_NOTIFY = 3, /* USB subsystem event notification */ WATCH_TYPE___NR = 4 }; enum watch_meta_notification_subtype { WATCH_META_REMOVAL_NOTIFICATION = 0, /* Watched object was removed */ WATCH_META_LOSS_NOTIFICATION = 1, /* Data loss occurred */ }; /* * Notification record header. This is aligned to 64-bits so that subclasses * can contain __u64 fields. */ struct watch_notification { __u32 type:24; /* enum watch_notification_type */ __u32 subtype:8; /* Type-specific subtype (filterable) */ __u32 info; #define WATCH_INFO_LENGTH 0x0000007f /* Length of record / sizeof(watch_notification) */ #define WATCH_INFO_LENGTH__SHIFT 0 #define WATCH_INFO_ID 0x0000ff00 /* ID of watchpoint, if type-appropriate */ #define WATCH_INFO_ID__SHIFT 8 #define WATCH_INFO_TYPE_INFO 0xffff0000 /* Type-specific info */ #define WATCH_INFO_TYPE_INFO__SHIFT 16 #define WATCH_INFO_FLAG_0 0x00010000 /* Type-specific info, flag bit 0 */ #define WATCH_INFO_FLAG_1 0x00020000 /* ... */ #define WATCH_INFO_FLAG_2 0x00040000 #define WATCH_INFO_FLAG_3 0x00080000 #define WATCH_INFO_FLAG_4 0x00100000 #define WATCH_INFO_FLAG_5 0x00200000 #define WATCH_INFO_FLAG_6 0x00400000 #define WATCH_INFO_FLAG_7 0x00800000 }; /* * Notification filtering rules (IOC_WATCH_QUEUE_SET_FILTER). */ struct watch_notification_type_filter { __u32 type; /* Type to apply filter to */ __u32 info_filter; /* Filter on watch_notification::info */ __u32 info_mask; /* Mask of relevant bits in info_filter */ __u32 subtype_filter[8]; /* Bitmask of subtypes to filter on */ }; struct watch_notification_filter { __u32 nr_filters; /* Number of filters */ __u32 __reserved; /* Must be 0 */ struct watch_notification_type_filter filters[]; }; /* * Extended watch removal notification. This is used optionally if the type * wants to indicate an identifier for the object being watched, if there is * such. This can be distinguished by the length. * * type -> WATCH_TYPE_META * subtype -> WATCH_META_REMOVAL_NOTIFICATION */ struct watch_notification_removal { struct watch_notification watch; __u64 id; /* Type-dependent identifier */ }; /* * Type of key/keyring change notification. */ enum key_notification_subtype { NOTIFY_KEY_INSTANTIATED = 0, /* Key was instantiated (aux is error code) */ NOTIFY_KEY_UPDATED = 1, /* Key was updated */ NOTIFY_KEY_LINKED = 2, /* Key (aux) was added to watched keyring */ NOTIFY_KEY_UNLINKED = 3, /* Key (aux) was removed from watched keyring */ NOTIFY_KEY_CLEARED = 4, /* Keyring was cleared */ NOTIFY_KEY_REVOKED = 5, /* Key was revoked */ NOTIFY_KEY_INVALIDATED = 6, /* Key was invalidated */ NOTIFY_KEY_SETATTR = 7, /* Key's attributes got changed */ }; /* * Key/keyring notification record. * - watch.type = WATCH_TYPE_KEY_NOTIFY * - watch.subtype = enum key_notification_type */ struct key_notification { struct watch_notification watch; __u32 key_id; /* The key/keyring affected */ __u32 aux; /* Per-type auxiliary data */ }; #endif /* _KEYUTILS_LINUX_WATCH_QUEUE_H */