pax_global_header00006660000000000000000000000064141342746730014525gustar00rootroot0000000000000052 comment=7f600c40bc18d8180993edcd54daf45124736776 mcstrans-3.3/000077500000000000000000000000001413427467300132245ustar00rootroot00000000000000mcstrans-3.3/COPYING000066400000000000000000000431101413427467300142560ustar00rootroot00000000000000 GNU GENERAL PUBLIC LICENSE Version 2, June 1991 Copyright (C) 1989, 1991 Free Software Foundation, Inc. 59 Temple Place, Suite 330, Boston, MA 02111-1307 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 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) 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 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) year 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. mcstrans-3.3/Makefile000066400000000000000000000003521413427467300146640ustar00rootroot00000000000000all: $(MAKE) -C src $(MAKE) -C utils install: $(MAKE) -C src install # $(MAKE) -C utils install $(MAKE) -C man install clean: rm -f *~ \#* $(MAKE) -C src clean $(MAKE) -C utils clean $(MAKE) -C man clean relabel: test: mcstrans-3.3/TODO000066400000000000000000000007711413427467300137210ustar00rootroot00000000000000TODO List for mcstrans: In compute_raw_from_trans look for conflicting bit patterns and report errors. In emit_whitespace look at whitespace characters for any regex special character and escape them. Make prefixes and suffixes optional (ex. SECRET REL AUS == SECRET AUS). compute_trans_from_raw is an expensive operation that needs to be sped up or threaded so that mcstrans can respond to other requests more quickly. Reevaluate the means of determining whether inverse bits are used in a domain. mcstrans-3.3/VERSION000066400000000000000000000000041413427467300142660ustar00rootroot000000000000003.3 mcstrans-3.3/man/000077500000000000000000000000001413427467300137775ustar00rootroot00000000000000mcstrans-3.3/man/Makefile000066400000000000000000000015241413427467300154410ustar00rootroot00000000000000# Installation directories. LINGUAS ?= ru PREFIX ?= /usr MANDIR ?= $(PREFIX)/share/man MAN5SUBDIR ?= man5 MAN5DIR ?= $(MANDIR)/$(MAN5SUBDIR) MAN8SUBDIR ?= man8 MAN8DIR ?= $(MANDIR)/$(MAN8SUBDIR) all: install: all mkdir -p $(DESTDIR)$(MAN5DIR) mkdir -p $(DESTDIR)$(MAN8DIR) install -m 644 man5/*.5 $(DESTDIR)$(MAN5DIR) install -m 644 man8/*.8 $(DESTDIR)$(MAN8DIR) for lang in $(LINGUAS) ; do \ if [ -e $${lang}/man5 ] ; then \ mkdir -p $(DESTDIR)$(MANDIR)/$${lang}/$(MAN5SUBDIR) ; \ install -m 644 $${lang}/man5/*.5 $(DESTDIR)$(MANDIR)/$${lang}/$(MAN5SUBDIR) ; \ fi ; \ if [ -e $${lang}/man8 ] ; then \ mkdir -p $(DESTDIR)$(MANDIR)/$${lang}/$(MAN8SUBDIR) ; \ install -m 644 $${lang}/man8/*.8 $(DESTDIR)$(MANDIR)/$${lang}/$(MAN8SUBDIR) ; \ fi ; \ done clean: -rm -f *~ \#* -rm -f man5/*~ man5/\#* -rm -f man8/*~ man8/\#* mcstrans-3.3/man/man5/000077500000000000000000000000001413427467300146375ustar00rootroot00000000000000mcstrans-3.3/man/man5/setrans.conf.5000066400000000000000000000064271413427467300173410ustar00rootroot00000000000000.TH "setrans.conf" "5" "13 July 2010" "txtoth@gmail.com" "setrans.conf documentation" .SH "NAME" setrans.conf \- translation configuration file for MCS/MLS SELinux systems .SH "DESCRIPTION" The .I /etc/selinux/{SELINUXTYPE}/setrans.conf configuration file specifies the way that SELinux MCS/MLS labels are translated into human readable form by the mcstransd daemon. The default policies support 16 sensitivity levels (s0 through s15) and 1024 categories (c0 through c1023). Multiple categories can be separated with commas (c0,c1,c3,c5) and a range of categories can be shortened using dot notation (c0.c3,c5). .SS "Keywords" .TP Base\fR once a base is declared, subsequent sensitivity label definitions will have all modifiers applied to them during translation. Sensitivity labels defined before the base declaration are immediately cached and no modifiers will be applied these are used as direct translations. .TP Default\fR defines the category bit range that will be used for inverse bits. .TP Domain\fR creates a new domain with the supplied name. .TP Include\fR read and process the contents of the specified configuration file. .TP Join\fR defines a character used to separate members of a modifier group when more than one is specified (ex. USA/AUS). .TP ModifierGroup\fR a means of grouping category bit definitions by how they modify the sensitivity label. .TP Prefix\fR word(s) that may proceed member(s) of a modifier group (ex. REL USA). .TP Suffix\fR word(s) that may follow member(s) of a modifier group (ex. USA EYES ONLY). .TP Whitespace\fR defines the set of acceptable white space characters that may be used in label being translated. .SS "Sensitivity Level Definition Examples" .TP s0=SystemLow\fR defines a translation of s0 (the lowest sensitivity level) with no categories to SystemLow. .TP s15:c0.c1023=SystemHigh\fR defines a translation of s15:c0.c1023 to SystemHigh. c0.c1023 is shorthand for all categories. A colon separates the sensitivity level and categories. .TP s0\-s15:c0.c1023=SystemLow\-SystemHigh\fR defines a range translation of s0\-s15:c0.c1023 to SystemLow\-SystemHigh. The two range components are separated by a dash. .TP s0:c0=PatientRecord\fR defines a translation of sensitivity s0 with category c0 to PatientRecord. .TP s0:c1=Accounting\fR defines a translation of sensitivity s0 with category c1 to Accounting. .TP s2:c1,c2,c3=Confidential3Categories .TP s2:c1.c3=Confidential3Categories\fR both define a translation of sensitivity s2 with categories c1, c2 and c3 to Confidential3Categories. .TP s5=TopSecret\fR defines a translation of sensitivity s5 with no categories to TopSecret. .SS "Constraint Examples" .TP c0!c1 if category bits 0 and 1 are both set, the constraint will fail and the original context will be returned. .TP c5.c9>c1 if category bits 5 through 9 are set, bit 1 must also be set or the constraint will fail and the original context will be returned. .TP s1!c5,c9 if category bits 5 and 9 are set and the sensitivity level is s1, the constraint will fail and the original context will be returned. .SH "AUTHOR" Written by Joe Nall . Updated by Ted X. Toth . .SH "SEE ALSO" selinux(8), mcs(8), mls(8), chcon(1) .SH "FILES" /etc/selinux/{SELINUXTYPE}/setrans.conf .br /usr/share/mcstrans/examples mcstrans-3.3/man/man8/000077500000000000000000000000001413427467300146425ustar00rootroot00000000000000mcstrans-3.3/man/man8/mcs.8000066400000000000000000000023511413427467300155160ustar00rootroot00000000000000.TH "mcs" "8" "8 Sep 2005" "dwalsh@redhat.com" "mcs documentation" .SH "NAME" mcs \- Multi-Category System .SH "DESCRIPTION" MCS (Multiple Category System) allows users to label files on their system within administrator defined categories. It then uses SELinux Mandatory Access Control to protect those files. MCS is a discretionary model to allow users to mark their data with additional tags that further restrict access. The only mandatory aspect is authorizing users for categories by defining their clearance in policy. However, MCS is similar to MLS and exercises the same code paths and share the same support infrastructure. They just differ in their specific configuration. The .I /etc/selinux/{SELINUXTYPE}/setrans.conf configuration file translates the labels on disk to human readable form. Administrators can define any labels they want in this file. Certain applications like printing and auditing will use these labels to identify the files. By setting a category on a file you will prevent other applications/services from having access to the files. .P Examples of file labels would be PatientRecord, CompanyConfidential etc. .SH "SEE ALSO" selinux(8), chcon(1) .SH FILES /etc/selinux/{SELINUXTYPE}/setrans.conf mcstrans-3.3/man/man8/mcstransd.8000066400000000000000000000016211413427467300167310ustar00rootroot00000000000000.TH "mcstransd" "8" "16 Oct 2009" "dwalsh@redhat.com" "mcs documentation" .SH "NAME" mcstransd \- MCS (Multiple Category System) daemon. Translates SELinux MCS/MLS labels to human readable form. .SH "SYNOPSIS" .B mcstransd [-f] [-h] .P .SH "DESCRIPTION" This manual page describes the .BR mcstransd program. .P This daemon reads /etc/selinux/{SELINUXTYPE}/setrans.conf configuration file, and communicates with libselinux via a socket in /var/run/setrans. .SH "OPTIONS" .TP \-f Run mcstransd in the foreground. Do not run as a daemon. .TP \-h Output a short summary of available command line options\&. .SH "AUTHOR" This man page was written by Dan Walsh . The program was originally written by Dan Walsh . The program was enhanced/rewritten by Joe Nall . .SH "FILES" /etc/selinux/{SELINUXTYPE}/setrans.conf .SH "SEE ALSO" .BR setrans.conf (5), mcs (8) mcstrans-3.3/man/ru/000077500000000000000000000000001413427467300144255ustar00rootroot00000000000000mcstrans-3.3/man/ru/man5/000077500000000000000000000000001413427467300152655ustar00rootroot00000000000000mcstrans-3.3/man/ru/man5/setrans.conf.5000066400000000000000000000135531413427467300177650ustar00rootroot00000000000000.TH "setrans.conf" "5" "13 июля 2010" "txtoth@gmail.com" "Документация по setrans.conf" .SH "ИМЯ" setrans.conf \- файл конфигурации преобразования для систем MCS/MLS SELinux .SH "ОПИСАНИЕ" Файл конфигурации .I /etc/selinux/{SELINUXTYPE}/setrans.conf определяет способ, которым метки SELinux MCS/MLS преобразовываются в удобную для прочтения человеком форму с помощью внутренней службы mcstransd. Политики по умолчанию поддерживают 16 уровней конфиденциальности (от s0 до s15) и 1024 категории (от c0 до c1023). Если категорий несколько, их можно разделить запятыми (c0,c1,c3,c5), а диапазон категорий - сократить с помощью указания через точку (c0.c3,c5). .SS "Ключевые слова" .TP Base\fR когда объявляется база, ко всем последующим определениям меток конфиденциальности будут при преобразовании применяться модификаторы. Метки конфиденциальности, которые были определены до объявления базы, незамедлительно кэшируются, и к ним не применяются модификаторы; они используются в качестве прямого преобразования. .TP Default\fR определяет битовый диапазон категорий, который будет использоваться для обратных битов. .TP Domain\fR создаёт новый домен с указанным именем. .TP Include\fR прочитать и обработать содержимое указанного файла конфигурации. .TP Join\fR определяет символ, который используется для разделения участников группы модификаторов, когда указано более одного (например, USA/AUS). .TP ModifierGroup\fR средство группировки битовых определений категорий по тому, как они изменяют метку конфиденциальности. .TP Prefix\fR слова (слова), которое может предшествовать участнику (участникам) группы модификаторов (например, REL USA). .TP Suffix\fR слово (слова), которое может следовать за участником (участниками) группы модификаторов (например, USA EYES ONLY). .TP Whitespace\fR определяет набор допустимых пробельных символов, которые могут использоваться в преобразовываемой метке. .SS "Примеры определения уровня конфиденциальности" .TP s0=SystemLow\fR определяет преобразование s0 (минимального уровня конфиденциальности) без категорий в SystemLow. .TP s15:c0.c1023=SystemHigh\fR определяет преобразование s15:c0.c1023 в SystemHigh. c0.c1023 - сокращённое обозначение всех категорий. Уровень конфиденциальности и категории разделены двоеточием. .TP s0\-s15:c0.c1023=SystemLow\-SystemHigh\fR определяет преобразование диапазона s0\-s15:c0.c1023 в SystemLow\-SystemHigh. Два компонента диапазона разделены дефисом. .TP s0:c0=PatientRecord\fR определяет преобразование уровня конфиденциальности s0 с категорией c0 в PatientRecord. .TP s0:c1=Accounting\fR определяет преобразование уровня конфиденциальности s0 с категорией c1 в Accounting. .TP s2:c1,c2,c3=Confidential3Categories .TP s2:c1.c3=Confidential3Categories\fR и то, и другое определяет преобразование уровня конфиденциальности s2 с категориями c1, c2 и c3 в Confidential3Categories. .TP s5=TopSecret\fR определяет преобразование уровня конфиденциальности s5 без категорий в TopSecret. .SS "Примеры ограничения" .TP c0!c1 если одновременно заданы биты категорий 0 и 1, ограничение не сработает и будет возвращён исходный контекст. .TP c5.c9>c1 если заданы биты категорий с 5 по 9, бит 1 также необходимо установить - иначе ограничение не сработает и будет возвращён исходный контекст. .TP s1!c5,c9 если заданы биты категорий с 5 по 9 и уровень конфиденциальности равен s1, ограничение не сработает и будет возвращён исходный контекст. .SH "ФАЙЛЫ" /etc/selinux/{SELINUXTYPE}/setrans.conf .br /usr/share/mcstrans/examples .SH "СМОТРИТЕ ТАКЖЕ" selinux(8), mcs(8), mls(8), chcon(1) .SH "АВТОРЫ" Написано Joe Nall . Обновлено Ted X. Toth . Перевод на русский язык выполнила Герасименко Олеся . mcstrans-3.3/man/ru/man8/000077500000000000000000000000001413427467300152705ustar00rootroot00000000000000mcstrans-3.3/man/ru/man8/mcs.8000066400000000000000000000047051413427467300161510ustar00rootroot00000000000000.TH "mcs" "8" "8 сентября 2005" "dwalsh@redhat.com" "Документация по MCS" .SH "ИМЯ" mcs \- мультикатегорийная система .SH "ОПИСАНИЕ" MCS (мультикатегорийная система) позволяет пользователям проставлять в своей системе метки для файлов внутри определённых администратором категорий. Затем эта система использует принудительное управление доступом SELinux, чтобы защитить эти файлы. MCS - дискреционная модель, которая позволяет пользователям отмечать свои данные дополнительными тегами, накладывая дальнейшие ограничения доступа. Обязательным является только один аспект - авторизовывать пользователей для категорий, определяя их уровень допуска в политике. MCS похожа на MLS, выполняет те же самые пути кода и использует ту же самую инфраструктуру поддержки. Они отличаются между собой только спецификой настройки. Файл конфигурации .I /etc/selinux/{SELINUXTYPE}/setrans.conf преобразовывает метки на диске в удобную для прочтения человеком форму. В этом файле администраторы могут определить любые необходимые метки. Некоторые приложения, такие как вывод на экран и аудит, будут использовать эти метки для идентификации файлов. Если для файла будет задана категория, другие приложения/службы не получат к нему доступ. .P Примеры меток файлов: PatientRecord, CompanyConfidential и так далее. .SH "СМОТРИТЕ ТАКЖЕ" selinux(8), chcon(1) .SH ФАЙЛЫ /etc/selinux/{SELINUXTYPE}/setrans.conf .SH АВТОРЫ Перевод на русский язык выполнила Герасименко Олеся mcstrans-3.3/man/ru/man8/mcstransd.8000066400000000000000000000030421413427467300173560ustar00rootroot00000000000000.TH "mcstransd" "8" "16 октября 2009" "dwalsh@redhat.com" "Документация по MCS" .SH "ИМЯ" mcstransd \- внутренняя служба MCS (мультикатегорийная система). Переводит метки MCS/MLS SELinux в удобную для прочтения человеком форму. .SH "ОБЗОР" .B mcstransd [-f] [-h] .P .SH "ОПИСАНИЕ" Эта страница руководства содержит описание программы .BR mcstransd. .P Эта внутренняя служба выполняет чтение файла конфигурации /etc/selinux/{SELINUXTYPE}/setrans.conf и связывается с libselinux через сокет в /var/run/setrans. .SH "ПАРАМЕТРЫ" .TP \-f Запустить mcstransd на переднем плане. Не запускать как внутреннюю службу. .TP \-h Вывести краткое описание доступных параметров командной строки\&. .SH "ФАЙЛЫ" /etc/selinux/{SELINUXTYPE}/setrans.conf .SH "СМОТРИТЕ ТАКЖЕ" .BR setrans.conf (5), mcs (8) .SH "АВТОРЫ" Эта man-страница написана Dan Walsh . Исходная версия программы написана Dan Walsh . Программа улучшена/переписана Joe Nall . Перевод на русский язык выполнила Герасименко Олеся . mcstrans-3.3/share/000077500000000000000000000000001413427467300143265ustar00rootroot00000000000000mcstrans-3.3/share/examples/000077500000000000000000000000001413427467300161445ustar00rootroot00000000000000mcstrans-3.3/share/examples/default/000077500000000000000000000000001413427467300175705ustar00rootroot00000000000000mcstrans-3.3/share/examples/default/README000066400000000000000000000002701413427467300204470ustar00rootroot00000000000000Original RHEL 5 setrans.conf To use: cp setrans.conf /etc/selinux/mls/setrans.conf run_init /etc/init.d/mcstrans restart To test: /usr/share/mcstrans/util/mlstrans-test default.test mcstrans-3.3/share/examples/default/default.test000066400000000000000000000013601413427467300221150ustar00rootroot00000000000000SystemLow==s0 SystemHigh==s15:c0.c1023 SystemLow-SystemHigh==s0-s15:c0.c1023 Unclassified==s1 Secret==s2 A==s2:c0 B==s2:c1 SystemLow-Unclassified==s0-s1 Unclassified-Secret==s1-s2 Unclassified-SystemHigh==s1-s15:c0.c1023 SystemLow-Secret==s0-s2 SystemLow-Secret:A==s0-s2:c0 SystemLow-Secret:B==s0-s2:c1 SystemLow-Secret:AB==s0-s2:c0,c1 Unclassified-Secret:A==s1-s2:c0 Unclassified-Secret:B==s1-s2:c1 Unclassified-Secret:AB==s1-s2:c0,c1 Secret-Secret:A==s2-s2:c0 Secret-Secret:B==s2-s2:c1 Secret-Secret:AB==s2-s2:c0,c1 Secret-SystemHigh==s2-s15:c0.c1023 Secret:A-Secret:AB==s2:c0-s2:c0,c1 Secret:A-SystemHigh==s2:c0-s15:c0.c1023 Secret:B-Secret:AB==s2:c1-s2:c0,c1 Secret:B-SystemHigh==s2:c1-s15:c0.c1023 Secret:AB-SystemHigh==s2:c0,c1-s15:c0.c1023 mcstrans-3.3/share/examples/default/setrans.conf000066400000000000000000000025341413427467300221220ustar00rootroot00000000000000# # Multi-Level Security translation table for SELinux # # Uncomment the following to disable translation library # disable=1 # # Objects can be labeled with one of 16 levels and be categorized with 0-1023 # categories defined by the admin. # Objects can be in more than one category at a time. # Users can modify this table to translate the MLS labels for different purpose. # # Assumptions: using below MLS labels. # SystemLow # SystemHigh # Unclassified # Secret with compartments A and B. # # SystemLow and SystemHigh s0=SystemLow s15:c0.c1023=SystemHigh s0-s15:c0.c1023=SystemLow-SystemHigh # Unclassified level s1=Unclassified # Secret level with compartments s2=Secret s2:c0=A s2:c1=B # ranges for Unclassified s0-s1=SystemLow-Unclassified s1-s2=Unclassified-Secret s1-s15:c0.c1023=Unclassified-SystemHigh # ranges for Secret with compartments s0-s2=SystemLow-Secret s0-s2:c0=SystemLow-Secret:A s0-s2:c1=SystemLow-Secret:B s0-s2:c0,c1=SystemLow-Secret:AB s1-s2:c0=Unclassified-Secret:A s1-s2:c1=Unclassified-Secret:B s1-s2:c0,c1=Unclassified-Secret:AB s2-s2:c0=Secret-Secret:A s2-s2:c1=Secret-Secret:B s2-s2:c0,c1=Secret-Secret:AB s2-s15:c0.c1023=Secret-SystemHigh s2:c0-s2:c0,c1=Secret:A-Secret:AB s2:c0-s15:c0.c1023=Secret:A-SystemHigh s2:c1-s2:c0,c1=Secret:B-Secret:AB s2:c1-s15:c0.c1023=Secret:B-SystemHigh s2:c0,c1-s15:c0.c1023=Secret:AB-SystemHigh mcstrans-3.3/share/examples/include/000077500000000000000000000000001413427467300175675ustar00rootroot00000000000000mcstrans-3.3/share/examples/include/README000066400000000000000000000004111413427467300204430ustar00rootroot00000000000000Original RHEL 5 setrans.conf pushed into setrans.d as include file To use: cp setrans.conf /etc/selinux/mls/setrans.conf cp setrans.d/* /etc/selinux/mls/setrans.d run_init /etc/init.d/mcstrans restart To test: /usr/share/mcstrans/util/mlstrans-test include.test mcstrans-3.3/share/examples/include/default.test000066400000000000000000000013601413427467300221140ustar00rootroot00000000000000SystemLow==s0 SystemHigh==s15:c0.c1023 SystemLow-SystemHigh==s0-s15:c0.c1023 Unclassified==s1 Secret==s2 A==s2:c0 B==s2:c1 SystemLow-Unclassified==s0-s1 Unclassified-Secret==s1-s2 Unclassified-SystemHigh==s1-s15:c0.c1023 SystemLow-Secret==s0-s2 SystemLow-Secret:A==s0-s2:c0 SystemLow-Secret:B==s0-s2:c1 SystemLow-Secret:AB==s0-s2:c0,c1 Unclassified-Secret:A==s1-s2:c0 Unclassified-Secret:B==s1-s2:c1 Unclassified-Secret:AB==s1-s2:c0,c1 Secret-Secret:A==s2-s2:c0 Secret-Secret:B==s2-s2:c1 Secret-Secret:AB==s2-s2:c0,c1 Secret-SystemHigh==s2-s15:c0.c1023 Secret:A-Secret:AB==s2:c0-s2:c0,c1 Secret:A-SystemHigh==s2:c0-s15:c0.c1023 Secret:B-Secret:AB==s2:c1-s2:c0,c1 Secret:B-SystemHigh==s2:c1-s15:c0.c1023 Secret:AB-SystemHigh==s2:c0,c1-s15:c0.c1023 mcstrans-3.3/share/examples/include/setrans.conf000066400000000000000000000007571413427467300221260ustar00rootroot00000000000000# # Multi-Level Security translation table for SELinux # # Uncomment the following to disable translation library # disable=1 # # Objects can be labeled with one of 16 levels and be categorized with 0-1023 # categories defined by the admin. # Objects can be in more than one category at a time. # Users can modify this table to translate the MLS labels for different purpose. # # Demonstrate Include by moving everything to an include file # Include=/etc/selinux/mls/setrans.d/include-example mcstrans-3.3/share/examples/include/setrans.d/000077500000000000000000000000001413427467300214705ustar00rootroot00000000000000mcstrans-3.3/share/examples/include/setrans.d/include-example000066400000000000000000000025341413427467300244730ustar00rootroot00000000000000# # Multi-Level Security translation table for SELinux # # Uncomment the following to disable translation library # disable=1 # # Objects can be labeled with one of 16 levels and be categorized with 0-1023 # categories defined by the admin. # Objects can be in more than one category at a time. # Users can modify this table to translate the MLS labels for different purpose. # # Assumptions: using below MLS labels. # SystemLow # SystemHigh # Unclassified # Secret with compartments A and B. # # SystemLow and SystemHigh s0=SystemLow s15:c0.c1023=SystemHigh s0-s15:c0.c1023=SystemLow-SystemHigh # Unclassified level s1=Unclassified # Secret level with compartments s2=Secret s2:c0=A s2:c1=B # ranges for Unclassified s0-s1=SystemLow-Unclassified s1-s2=Unclassified-Secret s1-s15:c0.c1023=Unclassified-SystemHigh # ranges for Secret with compartments s0-s2=SystemLow-Secret s0-s2:c0=SystemLow-Secret:A s0-s2:c1=SystemLow-Secret:B s0-s2:c0,c1=SystemLow-Secret:AB s1-s2:c0=Unclassified-Secret:A s1-s2:c1=Unclassified-Secret:B s1-s2:c0,c1=Unclassified-Secret:AB s2-s2:c0=Secret-Secret:A s2-s2:c1=Secret-Secret:B s2-s2:c0,c1=Secret-Secret:AB s2-s15:c0.c1023=Secret-SystemHigh s2:c0-s2:c0,c1=Secret:A-Secret:AB s2:c0-s15:c0.c1023=Secret:A-SystemHigh s2:c1-s2:c0,c1=Secret:B-Secret:AB s2:c1-s15:c0.c1023=Secret:B-SystemHigh s2:c0,c1-s15:c0.c1023=Secret:AB-SystemHigh mcstrans-3.3/share/examples/nato/000077500000000000000000000000001413427467300171055ustar00rootroot00000000000000mcstrans-3.3/share/examples/nato/README000066400000000000000000000005441413427467300177700ustar00rootroot00000000000000NATO example test setrans.conf To use: mkdir /etc/selinux/mls/mcstrand.d cp rel.conf /etc/selinux/mls/mcstrand.d cp eyes-only.conf /etc/selinux/mls/mcstrand.d cp constraints.conf /etc/selinux/mls/mcstrand.d cp setrans.conf /etc/selinux/mls/setrans.conf sudo run_init /etc/init.d/mcstrans restart To test: /usr/share/mcstrans/util/mlstrans-test nato.test mcstrans-3.3/share/examples/nato/nato.test000066400000000000000000000016131413427467300207500ustar00rootroot00000000000000NATO CONFIDENTIAL==s4:c1,c200.c511 CONFIDENTIAL-NATO SECRET!=s4:c0,c2,c11,c200.c511-s5:c1,c200.c511 NATO SECRET REL NATO==s5:c1,c201.c204,c206.c218,c220.c222,c224.c238,c240.c256,c259,c260,c262.c267,c270.c273,c275.c277,c279.c287,c289.c297,c299,c301.c307,c309,c311.c330,c334.c364,c367.c377,c379,c380,c382.c386,c388.c405,c408.c422,c424.c429,c431.c511 NATO CONFIDENTIAL NATO EYES ONLY==s4:c1,c200.c204,c206.c218,c220.c222,c224.c238,c240.c256,c259,c260,c262.c267,c270.c273,c275.c277,c279.c287,c289.c297,c299,c301.c307,c309,c311.c330,c334.c364,c367.c377,c379,c380,c382.c386,c388.c405,c408.c422,c424.c429,c431.c511 NATO CONFIDENTIAL-NATO SECRET==s4:c1,c200.c511-s5:c1,c200.c511 NATO CONFIDENTIAL REL AUS/US-NATO SECRET REL AUS/US==s4:c1,c201.c214,c216.c429,c431.c511-s5:c1,c201.c214,c216.c429,c431.c511 NATO CONFIDENTIAL DEU EYES ONLY-NATO SECRET DEU EYES ONLY==s4:c1,c200.c257,c259.c511-s5:c1,c200.c257,c259.c511 mcstrans-3.3/share/examples/nato/setrans.conf000066400000000000000000000010241413427467300214300ustar00rootroot00000000000000# UNCLASSIFIED Domain=NATOEXAMPLE s0=SystemLow s15:c0.c1023=SystemHigh s0-s15:c0.c1023=SystemLow-SystemHigh Base=Sensitivity Levels s1=UNCLASSIFIED s3:c0,c2,c11,c200.c511=RESTRICTED s4:c0,c2,c11,c200.c511=CONFIDENTIAL s5:c0,c2,c11,c200.c511=SECRET s1:c1=NATO UNCLASSIFIED s3:c1,c200.c511=NATO RESTRICTED s4:c1,c200.c511=NATO CONFIDENTIAL s5:c1,c200.c511=NATO SECRET Include=/etc/selinux/mls/setrans.d/rel.conf Include=/etc/selinux/mls/setrans.d/eyes-only.conf Include=/etc/selinux/mls/setrans.d/constraints.conf # UNCLASSIFIED mcstrans-3.3/share/examples/nato/setrans.d/000077500000000000000000000000001413427467300210065ustar00rootroot00000000000000mcstrans-3.3/share/examples/nato/setrans.d/constraints.conf000066400000000000000000000002471413427467300242270ustar00rootroot00000000000000# UNCLASSIFIED # These constraints apply to computed translations, # not cached or preset translations. # # nato and non-nato are incompatible c0!c1 #UNCLASSIFIED mcstrans-3.3/share/examples/nato/setrans.d/eyes-only.conf000066400000000000000000000410771413427467300236120ustar00rootroot00000000000000#UNCLASSIFIED ModifierGroup=Eyes Only Whitespace=- ,/ Join=/ Suffix=EYES ONLY Default=c200.c511 ~c205,~c219,~c223,~c239,~c257,~c258,~c261,~c268,~c269,~c274,~c278,~c288,~c298,~c300,~c308,~c310,~c331,~c332,~c333,~c365,~c366,~c378,~c381,~c387,~c406,~c407,~c423,~c430=NATO # Aruba - bit 201 ~c201=AA # Aruba ~c201=ABW # Aruba # Antigua and Barbuda - bit 214 ~c214=AC # Antigua and Barbuda ~c214=ATG # Antigua and Barbuda # United Arab Emirates - bit 208 #~c208=AE # United Arab Emirates ~c208=ARE # United Arab Emirates # Afghanistan - bit 202 ~c202=AF # Afghanistan ~c202=AFG # Afghanistan # Algeria - bit 263 ~c263=AG # Algeria ~c263=DZA # Algeria # Azerbaijan - bit 217 ~c217=AJ # Azerbaijan ~c217=AZE # Azerbaijan # Albania - bit 205 ~c205=AL # Albania ~c205=ALB # Albania # Armenia - bit 210 ~c210=AM # Armenia ~c210=ARM # Armenia # Andorra - bit 206 ~c206=AN # Andorra ~c206=AND # Andorra # Angola - bit 203 ~c203=AO # Angola ~c203=AGO # Angola # American Samoa - bit 211 ~c211=AQ # American Samoa ~c211=ASM # American Samoa # Argentina - bit 209 ~c209=AR # Argentina ~c209=ARG # Argentina # Australia - bit 215 ~c215=AUS # Australia ~c215=AS # Australia # Austria - bit 216 ~c216=AU # Austria ~c216=AUT # Austria # Anguilla - bit 204 ~c204=AV # Anguilla ~c204=AIA # Anguilla # Antarctica - bit 212 ~c212=AY # Antarctica ~c212=ATA # Antarctica # Bahrain - bit 224 ~c224=BA # Bahrain ~c224=BHR # Bahrain # Barbados - bit 233 ~c233=BB # Barbados ~c233=BRB # Barbados # Botswana - bit 237 ~c237=BC # Botswana ~c237=BWA # Botswana # Bermuda - bit 230 ~c230=BD # Bermuda ~c230=BMU # Bermuda # Belgium - bit 219 ~c219=BE # Belgium ~c219=BEL # Belgium # Bahamas, The - bit 225 ~c225=BF # Bahamas, The ~c225=BHS # Bahamas, The # Bangladesh - bit 222 ~c222=BG # Bangladesh ~c222=BGD # Bangladesh # Belize - bit 229 ~c229=BH # Belize ~c229=BLZ # Belize # Bosnia and Herzegovina - bit 226 ~c226=BK # Bosnia and Herzegovina ~c226=BIH # Bosnia and Herzegovina # Bolivia - bit 231 ~c231=BL # Bolivia ~c231=BOL # Bolivia # Burma - bit 346 ~c346=BM # Burma ~c346=MMR # Burma # Benin - bit 220 ~c220=BN # Benin ~c220=BEN # Benin # Belarus - bit 228 ~c228=BO # Belarus ~c228=BLR # Belarus # Solomon Islands - bit 397 ~c397=BP # Solomon Islands ~c397=SLB # Solomon Islands # Brazil - bit 232 ~c232=BR # Brazil ~c232=BRA # Brazil # Bhutan - bit 235 ~c235=BT # Bhutan ~c235=BTN # Bhutan # Bulgaria - bit 223 ~c223=BU # Bulgaria ~c223=BGR # Bulgaria # Bouvet Island - bit 236 ~c236=BV # Bouvet Island ~c236=BVT # Bouvet Island # Brunei - bit 234 ~c234=BX # Brunei ~c234=BRN # Brunei # Burundi - bit 218 ~c218=BY # Burundi ~c218=BDI # Burundi # Canada - bit 239 ~c239=CA # Canada ~c239=CAN # Canada # Cambodia - bit 318 ~c318=CB # Cambodia ~c318=KHM # Cambodia # Chad - bit 413 ~c413=CD # Chad ~c413=TCD # Chad # Sri Lanka - bit 329 ~c329=CE # Sri Lanka ~c329=LKA # Sri Lanka # Congo, Republic of the - bit 247 ~c247=CF # Congo, Republic of the ~c247=COG # Congo, Republic of the # Congo, Democratic Republic of the - bit 246 ~c246=CG # Congo, Democratic Republic of the ~c246=COD # Congo, Democratic Republic of the # China - bit 243 ~c243=CH # China ~c243=CHN # China # Chile - bit 242 ~c242=CI # Chile ~c242=CHL # Chile # Cayman Islands - bit 255 ~c255=CJ # Cayman Islands ~c255=CYM # Cayman Islands # Cocos (Keeling) Islands - bit 240 part of AUS ~c240=CK # Cocos (Keeling) Islands ~c240=CCK # Cocos (Keeling) Islands # Cameroon - bit 245 ~c245=CM # Cameroon ~c245=CMR # Cameroon # Comoros - bit 250 ~c250=CN # Comoros ~c250=COM # Comoros # Colombia - bit 249 ~c249=CO # Colombia ~c249=COL # Colombia # Northern Mariana Islands - bit 349 ~c349=CQ # Northern Mariana Islands ~c349=MNP # Northern Mariana Islands # Costa Rica - bit 252 ~c252=CS # Costa Rica ~c252=CRI # Costa Rica # Central African Republic - bit 238 ~c238=CT # Central African Republic ~c238=CAF # Central African Republic # Cuba - bit 253 ~c253=CU # Cuba ~c253=CUB # Cuba # Cape Verde - bit 251 ~c251=CV # Cape Verde ~c251=CPV # Cape Verde # Cook Islands - bit 248 ~c248=CW # Cook Islands ~c248=COK # Cook Islands # Cyprus - bit 256 ~c256=CY # Cyprus ~c256=CYP # Cyprus # Denmark - bit 261 ~c261=DA # Denmark ~c261=DNK # Denmark # Djibouti - bit 259 ~c259=DJ # Djibouti ~c259=DJI # Djibouti # Dominica - bit 260 ~c260=DO # Dominica ~c260=DMA # Dominica # Dominican Republic - bit 262 ~c262=DR # Dominican Republic ~c262=DOM # Dominican Republic # Ecuador - bit 264 ~c264=EC # Ecuador ~c264=ECU # Ecuador # Egypt - bit 265 ~c265=EG # Egypt ~c265=EGY # Egypt # Ireland - bit 305 ~c305=EI # Ireland ~c305=IRL # Ireland # Equatorial Guinea - bit 287 ~c287=EK # Equatorial Guinea ~c287=GNQ # Equatorial Guinea # Estonia - bit 269 ~c269=EN # Estonia ~c269=EST # Estonia # Eritrea - bit 266 ~c266=ER # Eritrea ~c266=ERI # Eritrea # El Salvador - bit 399 ~c399=ES # El Salvador ~c399=SLV # El Salvador # Ethiopia - bit 270 ~c270=ET # Ethiopia ~c270=ETH # Ethiopia # Czech Republic - bit 257 #~c257=EZ # Czech Republic ~c257=CZE # Czech Republic # French Guiana - bit 292 ~c292=FG # French Guiana ~c292=GUF # French Guiana # Finland - bit 271 ~c271=FI # Finland ~c271=FIN # Finland # Fiji - bit 272 ~c272=FJ # Fiji ~c272=FJI # Fiji # Falkland Islands (Islas Malvinas) - bit 273 ~c273=FK # Falkland Islands (Islas Malvinas) ~c273=FLK # Falkland Islands (Islas Malvinas) # Micronesia, Federated States of - bit 276 ~c276=FM # Micronesia, Federated States of ~c276=FSM # Micronesia, Federated States of # Faroe Islands - bit 275 ~c275=FO # Faroe Islands ~c275=FRO # Faroe Islands # French Polynesia - bit 384 ~c384=FP # French Polynesia ~c384=PYF # French Polynesia # France - bit 274 ~c274=FR # France ~c274=FRA # France # French Southern and Antarctic Lands - bit 213 ~c213=FS # French Southern and Antarctic Lands ~c213=ATF # French Southern and Antarctic Lands # Gambia, The - bit 285 ~c285=GA # Gambia, The ~c285=GMB # Gambia, The # Gabon - bit 277 ~c277=GB # Gabon ~c277=GAB # Gabon # Georgia - bit 279 ~c279=GG # Georgia ~c279=GEO # Georgia # Ghana - bit 281 ~c281=GH # Ghana ~c281=GHA # Ghana # Gibraltar - bit 282 ~c282=GI # Gibraltar ~c282=GIB # Gibraltar # Grenada - bit 289 ~c289=GJ # Grenada ~c289=GRD # Grenada # Guernsey - bit 280 part of UK ~c280=GK # Guernsey ~c280=GGY # Guernsey # Greenland - bit 290 ~c290=GL # Greenland ~c290=GRL # Greenland # Germany - bit 258 #~c258=GM # Germany ~c258=DEU # Germany # Guadeloupe - bit 284 ~c284=GP # Guadeloupe ~c284=GLP # Guadeloupe # Guam - bit 293 ~c293=GQ # Guam ~c293=GUM # Guam # Greece - bit 288 ~c288=GR # Greece ~c288=GRC # Greece # Guatemala - bit 291 ~c291=GT # Guatemala ~c291=GTM # Guatemala # Guinea - bit 283 ~c283=GV # Guinea ~c283=GIN # Guinea # Guyana - bit 294 ~c294=GY # Guyana ~c294=GUY # Guyana # Gaza Strip - bit 383 #~c383=GZ # Gaza Strip ~c383=PSE # Gaza Strip # Haiti - bit 299 ~c299=HA # Haiti ~c299=HTI # Haiti # Hong Kong - bit 295 ~c295=HK # Hong Kong ~c295=HKG # Hong Kong # Heard Island and McDonald Islands - bit 296 ~c296=HM # Heard Island and McDonald Islands ~c296=HMD # Heard Island and McDonald Islands # Honduras - bit 297 ~c297=HO # Honduras ~c297=HND # Honduras # Croatia - bit 298 ~c298=HR # Croatia ~c298=HRV # Croatia # Hungary - bit 300 ~c300=HU # Hungary ~c300=HUN # Hungary # Iceland - bit 308 ~c308=IC # Iceland ~c308=ISL # Iceland # Indonesia - bit 301 ~c301=ID # Indonesia ~c301=IDN # Indonesia # Isle of Man - bit 302 part of UK ~c302=IM # Isle of Man ~c302=IMN # Isle of Man # India - bit 303 ~c303=IN # India ~c303=IND # India # British Indian Ocean Territory - bit 304 ~c304=IO # British Indian Ocean Territory ~c304=IOT # British Indian Ocean Territory # Iran - bit 306 ~c306=IR # Iran ~c306=IRN # Iran # Israel - bit 309 ~c309=IS # Israel ~c309=ISR # Israel # Italy - bit 310 ~c310=IT # Italy ~c310=ITA # Italy # Cote d'Ivoire - bit 244 ~c244=IV # Cote d'Ivoire ~c244=CIV # Cote d'Ivoire # Iraq - bit 307 ~c307=IZ # Iraq ~c307=IRQ # Iraq # Japan - bit 314 ~c314=JA # Japan ~c314=JPN # Japan # Jersey - bit 312 part of UK ~c312=JE # Jersey ~c312=JEY # Jersey # Jamaica - bit 311 ~c311=JM # Jamaica ~c311=JAM # Jamaica # Jordan - bit 313 ~c313=JO # Jordan ~c313=JOR # Jordan # Kenya - bit 316 ~c316=KE # Kenya ~c316=KEN # Kenya # Kyrgyzstan - bit 317 ~c317=KG # Kyrgyzstan ~c317=KGZ # Kyrgyzstan # Korea, North - bit 380 ~c380=KN # Korea, North ~c380=PRK # Korea, North # Kiribati - bit 319 ~c319=KR # Kiribati ~c319=KIR # Kiribati # Korea, South - bit 321 ~c321=KS # Korea, South ~c321=ROK # Korea, South # Christmas Island - bit 254 ~c254=KT # Christmas Island ~c254=CXR # Christmas Island # Kuwait - bit 322 ~c322=KU # Kuwait ~c322=KWT # Kuwait # Kazakhstan - bit 315 ~c315=KZ # Kazakhstan ~c315=KAZ # Kazakhstan # Laos - bit 323 ~c323=LA # Laos ~c323=LAO # Laos # Lebanon - bit 324 ~c324=LE # Lebanon ~c324=LBN # Lebanon # Latvia - bit 333 ~c333=LG # Latvia ~c333=LVA # Latvia # Lithuania - bit 331 ~c331=LH # Lithuania ~c331=LTU # Lithuania # Liberia - bit 325 ~c325=LI # Liberia ~c325=LBR # Liberia # Slovakia - bit 406 ~c406=LO # Slovakia ~c406=SVK # Slovakia # Liechtenstein - bit 328 ~c328=LS # Liechtenstein ~c328=LIE # Liechtenstein # Lesotho - bit 330 ~c330=LT # Lesotho ~c330=LSO # Lesotho # Luxembourg - bit 332 ~c332=LU # Luxembourg ~c332=LUX # Luxembourg # Libya - bit 326 ~c326=LY # Libya ~c326=LBY # Libya # Madagascar - bit 339 ~c339=MA # Madagascar ~c339=MDG # Madagascar # Martinique - bit 353 ~c353=MB # Martinique ~c353=MTQ # Martinique # Macau - bit 334 ~c334=MC # Macau ~c334=MAC # Macau # Moldova - bit 338 ~c338=MD # Moldova ~c338=MDA # Moldova # Mayotte - bit 357 part of FRA ~c357=MF # Mayotte ~c357=MYT # Mayotte # Mongolia - bit 348 ~c348=MG # Mongolia ~c348=MNG # Mongolia # Montserrat - bit 352 ~c352=MH # Montserrat ~c352=MSR # Montserrat # Malawi - bit 355 ~c355=MI # Malawi ~c355=MWI # Malawi # Montenegro - bit 347 ~c347=MJ # Montenegro ~c347=MNE # Montenegro # Macedonia - bit 343 part of FYR ~c343=MK # Macedonia ~c343=MKD # Macedonia # Mali - bit 344 ~c344=ML # Mali ~c344=MLI # Mali # Monaco - bit 337 ~c337=MN # Monaco ~c337=MCO # Monaco # Morocco - bit 336 ~c336=MO # Morocco ~c336=MAR # Morocco # Mauritius - bit 354 ~c354=MP # Mauritius ~c354=MUS # Mauritius # Mauritania - bit 351 ~c351=MR # Mauritania ~c351=MRT # Mauritania # Malta - bit 345 ~c345=MT # Malta ~c345=MLT # Malta # Oman - bit 370 ~c370=MU # Oman ~c370=OMN # Oman # Maldives - bit 340 ~c340=MV # Maldives ~c340=MDV # Maldives # Mexico - bit 341 ~c341=MX # Mexico ~c341=MEX # Mexico # Malaysia - bit 356 ~c356=MY # Malaysia ~c356=MYS # Malaysia # Mozambique - bit 350 ~c350=MZ # Mozambique ~c350=MOZ # Mozambique # New Caledonia - bit 359 ~c359=NC # New Caledonia ~c359=NCL # New Caledonia # Niue - bit 364 ~c364=NE # Niue ~c364=NIU # Niue # Norfolk Island - bit 361 ~c361=NF # Norfolk Island ~c361=NFK # Norfolk Island # Niger - bit 360 ~c360=NG # Niger ~c360=NER # Niger # Vanuatu - bit 438 ~c438=NH # Vanuatu ~c438=VUT # Vanuatu # Nigeria - bit 362 ~c362=NI # Nigeria ~c362=NGA # Nigeria # Netherlands - bit 365 ~c365=NL # Netherlands ~c365=NLD # Netherlands # Norway - bit 366 ~c366=NO # Norway ~c366=NOR # Norway # Nepal - bit 367 ~c367=NP # Nepal ~c367=NPL # Nepal # Nauru - bit 368 ~c368=NR # Nauru ~c368=NRU # Nauru # Suriname - bit 405 ~c405=NS # Suriname ~c405=SUR # Suriname # Netherlands Antilles - bit 207 ~c207=NT # Netherlands Antilles ~c207=ANT # Netherlands Antilles # Nicaragua - bit 363 ~c363=NU # Nicaragua ~c363=NIC # Nicaragua # New Zealand - bit 369 ~c369=NZ # New Zealand ~c369=NZL # New Zealand # Paraguay - bit 382 ~c382=PA # Paraguay ~c382=PRY # Paraguay # Pitcairn Islands - bit 373 ~c373=PC # Pitcairn Islands ~c373=PCN # Pitcairn Islands # Peru - bit 374 ~c374=PE # Peru ~c374=PER # Peru # Pakistan - bit 371 ~c371=PK # Pakistan ~c371=PAK # Pakistan # Poland - bit 378 ~c378=PL # Poland ~c378=POL # Poland # Panama - bit 372 ~c372=PM # Panama ~c372=PAN # Panama # Portugal - bit 381 ~c381=PO # Portugal ~c381=PRT # Portugal # Papua New Guinea - bit 377 ~c377=PP # Papua New Guinea ~c377=PNG # Papua New Guinea # Palau - bit 376 #~c376=PS # Palau ~c376=PLW # Palau # Guinea-Bissau - bit 286 ~c286=PU # Guinea-Bissau ~c286=GNB # Guinea-Bissau # Qatar - bit 385 ~c385=QA # Qatar ~c385=QAT # Qatar # Serbia - bit 403 #~c403=RB # Serbia ~c403=SRB # Serbia # Reunion - bit 386 ~c386=RE # Reunion ~c386=REU # Reunion # Marshall Islands - bit 342 ~c342=RM # Marshall Islands ~c342=MHL # Marshall Islands # Saint Martin - bit 335 ~c335=RN # Saint Martin ~c335=MAF # Saint Martin # Romania - bit 387 ~c387=RO # Romania ~c387=ROU # Romania # Philippines - bit 375 ~c375=RP # Philippines ~c375=PHL # Philippines # Puerto Rico - bit 379 ~c379=RQ # Puerto Rico ~c379=PRI # Puerto Rico # Russia - bit 388 #~c388=RS # Russia ~c388=RUS # Russia # Rwanda - bit 389 ~c389=RW # Rwanda ~c389=RWA # Rwanda # Saudi Arabia - bit 390 ~c390=SA # Saudi Arabia ~c390=SAU # Saudi Arabia # Saint Pierre and Miquelon - bit 402 ~c402=SB # Saint Pierre and Miquelon ~c402=SPM # Saint Pierre and Miquelon # Saint Kitts and Nevis - bit 320 ~c320=SC # Saint Kitts and Nevis ~c320=KNA # Saint Kitts and Nevis # Seychelles - bit 410 ~c410=SE # Seychelles ~c410=SYC # Seychelles # South Africa - bit 442 ~c442=SF # South Africa ~c442=ZAF # South Africa # Senegal - bit 392 ~c392=SG # Senegal ~c392=SEN # Senegal # Saint Helena - bit 395 ~c395=SH # Saint Helena ~c395=SHN # Saint Helena # Slovenia - bit 407 #~c407=SI # Slovenia ~c407=SVN # Slovenia # Sierra Leone - bit 398 ~c398=SL # Sierra Leone ~c398=SLE # Sierra Leone # San Marino - bit 400 ~c400=SM # San Marino ~c400=SMR # San Marino # Singapore - bit 393 ~c393=SN # Singapore ~c393=SGP # Singapore # Somalia - bit 401 ~c401=SO # Somalia ~c401=SOM # Somalia # Spain - bit 268 #~c268=SP # Spain ~c268=ESP # Spain # Saint Lucia - bit 327 ~c327=ST # Saint Lucia ~c327=LCA # Saint Lucia # Sudan - bit 391 ~c391=SU # Sudan ~c391=SDN # Sudan # Svalbard - bit 396 #~c396=SV # Svalbard ~c396=SJM # Svalbard # Sweden - bit 408 ~c408=SW # Sweden ~c408=SWE # Sweden # South Georgia and the Islands - bit 394 ~c394=SX # South Georgia and the Islands ~c394=SGS # South Georgia and the Islands # Syria - bit 411 ~c411=SY # Syria ~c411=SYR # Syria # Switzerland - bit 241 ~c241=SZ # Switzerland ~c241=CHE # Switzerland # Saint Barthelemy - bit 227 ~c227=TB # Saint Barthelemy ~c227=BLM # Saint Barthelemy # Trinidad and Tobago - bit 421 ~c421=TD # Trinidad and Tobago ~c421=TTO # Trinidad and Tobago # Thailand - bit 415 ~c415=TH # Thailand ~c415=THA # Thailand # Tajikistan - bit 416 ~c416=TI # Tajikistan ~c416=TJK # Tajikistan # Turks and Caicos Islands - bit 412 ~c412=TK # Turks and Caicos Islands ~c412=TCA # Turks and Caicos Islands # Togo - bit 414 ~c414=TGO # Tokelau - bit 417 ~c417=TL # Tokelau ~c417=TKL # Tokelau # Tonga - bit 420 ~c420=TN # Tonga ~c420=TON # Tonga # Togo - bit 414 ~c414=TO # Togo ~c414=TGO # Togo # Sao Tome and Principe - bit 404 ~c404=TP # Sao Tome and Principe ~c404=STP # Sao Tome and Principe # Tunisia - bit 422 ~c422=TS # Tunisia ~c422=TUN # Tunisia # Timor-Leste - bit 419 ~c419=TT # Timor-Leste ~c419=TLS # Timor-Leste # Turkey - bit 423 ~c423=TU # Turkey ~c423=TUR # Turkey # Tuvalu - bit 424 ~c424=TV # Tuvalu ~c424=TUV # Tuvalu # Taiwan - bit 425 ~c425=TW # Taiwan ~c425=TWN # Taiwan # Turkmenistan - bit 418 ~c418=TX # Turkmenistan ~c418=TKM # Turkmenistan # Tanzania - bit 426 ~c426=TZ # Tanzania ~c426=TZA # Tanzania # Uganda - bit 427 ~c427=UG # Uganda ~c427=UGA # Uganda # United Kingdom - bit 278 ~c278=UK # United Kingdom ~c278=GBR # United Kingdom # Ukraine - bit 428 ~c428=UP # Ukraine ~c428=UKR # Ukraine # United States - bit 430 ~c430=US # United States ~c430=USA # United States # Burkina Faso - bit 221 ~c221=UV # Burkina Faso ~c221=BFA # Burkina Faso # Uruguay - bit 429 ~c429=UY # Uruguay ~c429=URY # Uruguay # Uzbekistan - bit 431 ~c431=UZ # Uzbekistan ~c431=UZB # Uzbekistan # Saint Vincent and the Grenadines - bit 433 ~c433=VC # Saint Vincent and the Grenadines ~c433=VCT # Saint Vincent and the Grenadines # Venezuela - bit 434 ~c434=VE # Venezuela ~c434=VEN # Venezuela # British Virgin Islands - bit 435 ~c435=VI # British Virgin Islands ~c435=VGB # British Virgin Islands # Vietnam - bit 437 ~c437=VM # Vietnam ~c437=VNM # Vietnam # Virgin Islands - bit 436 #~c436=VQ # Virgin Islands ~c436=VIR # Virgin Islands # Holy See (Vatican City) - bit 432 ~c432=VT # Holy See (Vatican City) ~c432=VAT # Holy See (Vatican City) # Namibia - bit 358 ~c358=WA # Namibia ~c358=NAM # Namibia # West Bank - bit 383 ~c383=WE # West Bank # Wallis and Futuna - bit 439 ~c439=WF # Wallis and Futuna ~c439=WLF # Wallis and Futuna # Western Sahara - bit 267 ~c267=WI # Western Sahara ~c267=ESH # Western Sahara # Samoa - bit 440 #~c440=WS # Samoa ~c440=WSM # Samoa # Swaziland - bit 409 ~c409=WZ # Swaziland ~c409=SWZ # Swaziland # Yemen - bit 441 #~c441=YM # Yemen ~c441=YEM # Yemen # Zambia - bit 443 ~c443=ZA # Zambia ~c443=ZMB # Zambia # Zimbabwe - bit 444 ~c444=ZI # Zimbabwe ~c444=ZWE # Zimbabwe #UNCLASSIFIED mcstrans-3.3/share/examples/nato/setrans.d/rel.conf000066400000000000000000000467301413427467300224510ustar00rootroot00000000000000#UNCLASSIFIED ModifierGroup=Releasable To Whitespace=- ,/ Join=/ Prefix=REL Prefix=REL TO Prefix=RELEASABLE TO Prefix=RELEASEABLE TO Default=c200.c511 ~c200.c511=EVERYBODY ~c200,~c205,~c219,~c223,~c239,~c257,~c258,~c261,~c268,~c269,~c274,~c278,~c288,~c298,~c300,~c308,~c310,~c331,~c332,~c333,~c365,~c366,~c378,~c381,~c387,~c406,~c407,~c423,~c430=NATO # Aruba - bit 201 ~c200,~c201=AA # Aruba ~c200,~c201=ABW # Aruba # Antigua and Barbuda - bit 214 ~c200,~c214=AC # Antigua and Barbuda ~c200,~c214=ATG # Antigua and Barbuda # United Arab Emirates - bit 208 #~c200,~c208=AE # United Arab Emirates ~c200,~c208=ARE # United Arab Emirates # Afghanistan - bit 202 ~c200,~c202=AF # Afghanistan ~c200,~c202=AFG # Afghanistan # Algeria - bit 263 ~c200,~c263=AG # Algeria ~c200,~c263=DZA # Algeria # Azerbaijan - bit 217 ~c200,~c217=AJ # Azerbaijan ~c200,~c217=AZE # Azerbaijan # Albania - bit 205 ~c200,~c205=AL # Albania ~c200,~c205=ALB # Albania # Armenia - bit 210 ~c200,~c210=AM # Armenia ~c200,~c210=ARM # Armenia # Andorra - bit 206 ~c200,~c206=AN # Andorra ~c200,~c206=AND # Andorra # Angola - bit 203 ~c200,~c203=AO # Angola ~c200,~c203=AGO # Angola # American Samoa - bit 211 ~c200,~c211=AQ # American Samoa ~c200,~c211=ASM # American Samoa # Argentina - bit 209 ~c200,~c209=AR # Argentina ~c200,~c209=ARG # Argentina # Australia - bit 215 ~c200,~c215=AUS # Australia ~c200,~c215=AS # Australia # Austria - bit 216 ~c200,~c216=AU # Austria ~c200,~c216=AUT # Austria # Anguilla - bit 204 ~c200,~c204=AV # Anguilla ~c200,~c204=AIA # Anguilla # Antarctica - bit 212 ~c200,~c212=AY # Antarctica ~c200,~c212=ATA # Antarctica # Bahrain - bit 224 ~c200,~c224=BA # Bahrain ~c200,~c224=BHR # Bahrain # Barbados - bit 233 ~c200,~c233=BB # Barbados ~c200,~c233=BRB # Barbados # Botswana - bit 237 ~c200,~c237=BC # Botswana ~c200,~c237=BWA # Botswana # Bermuda - bit 230 ~c200,~c230=BD # Bermuda ~c200,~c230=BMU # Bermuda # Belgium - bit 219 ~c200,~c219=BE # Belgium ~c200,~c219=BEL # Belgium # Bahamas, The - bit 225 ~c200,~c225=BF # Bahamas, The ~c200,~c225=BHS # Bahamas, The # Bangladesh - bit 222 ~c200,~c222=BG # Bangladesh ~c200,~c222=BGD # Bangladesh # Belize - bit 229 ~c200,~c229=BH # Belize ~c200,~c229=BLZ # Belize # Bosnia and Herzegovina - bit 226 ~c200,~c226=BK # Bosnia and Herzegovina ~c200,~c226=BIH # Bosnia and Herzegovina # Bolivia - bit 231 ~c200,~c231=BL # Bolivia ~c200,~c231=BOL # Bolivia # Burma - bit 346 ~c200,~c346=BM # Burma ~c200,~c346=MMR # Burma # Benin - bit 220 ~c200,~c220=BN # Benin ~c200,~c220=BEN # Benin # Belarus - bit 228 ~c200,~c228=BO # Belarus ~c200,~c228=BLR # Belarus # Solomon Islands - bit 397 ~c200,~c397=BP # Solomon Islands ~c200,~c397=SLB # Solomon Islands # Brazil - bit 232 ~c200,~c232=BR # Brazil ~c200,~c232=BRA # Brazil # Bhutan - bit 235 ~c200,~c235=BT # Bhutan ~c200,~c235=BTN # Bhutan # Bulgaria - bit 223 ~c200,~c223=BU # Bulgaria ~c200,~c223=BGR # Bulgaria # Bouvet Island - bit 236 ~c200,~c236=BV # Bouvet Island ~c200,~c236=BVT # Bouvet Island # Brunei - bit 234 ~c200,~c234=BX # Brunei ~c200,~c234=BRN # Brunei # Burundi - bit 218 ~c200,~c218=BY # Burundi ~c200,~c218=BDI # Burundi # Canada - bit 239 ~c200,~c239=CAN # Canada ~c200,~c239=CA # Canada # Cambodia - bit 318 ~c200,~c318=CB # Cambodia ~c200,~c318=KHM # Cambodia # Chad - bit 413 ~c200,~c413=CD # Chad ~c200,~c413=TCD # Chad # Sri Lanka - bit 329 ~c200,~c329=CE # Sri Lanka ~c200,~c329=LKA # Sri Lanka # Congo, Republic of the - bit 247 ~c200,~c247=CF # Congo, Republic of the ~c200,~c247=COG # Congo, Republic of the # Congo, Democratic Republic of the - bit 246 ~c200,~c246=CG # Congo, Democratic Republic of the ~c200,~c246=COD # Congo, Democratic Republic of the # China - bit 243 ~c200,~c243=CH # China ~c200,~c243=CHN # China # Chile - bit 242 ~c200,~c242=CI # Chile ~c200,~c242=CHL # Chile # Cayman Islands - bit 255 ~c200,~c255=CJ # Cayman Islands ~c200,~c255=CYM # Cayman Islands # Cocos (Keeling) Islands - bit 240 part of AUS ~c200,~c240=CK # Cocos (Keeling) Islands ~c200,~c240=CCK # Cocos (Keeling) Islands # Cameroon - bit 245 ~c200,~c245=CM # Cameroon ~c200,~c245=CMR # Cameroon # Comoros - bit 250 ~c200,~c250=CN # Comoros ~c200,~c250=COM # Comoros # Colombia - bit 249 ~c200,~c249=CO # Colombia ~c200,~c249=COL # Colombia # Northern Mariana Islands - bit 349 ~c200,~c349=CQ # Northern Mariana Islands ~c200,~c349=MNP # Northern Mariana Islands # Costa Rica - bit 252 ~c200,~c252=CS # Costa Rica ~c200,~c252=CRI # Costa Rica # Central African Republic - bit 238 ~c200,~c238=CT # Central African Republic ~c200,~c238=CAF # Central African Republic # Cuba - bit 253 ~c200,~c253=CU # Cuba ~c200,~c253=CUB # Cuba # Cape Verde - bit 251 ~c200,~c251=CV # Cape Verde ~c200,~c251=CPV # Cape Verde # Cook Islands - bit 248 ~c200,~c248=CW # Cook Islands ~c200,~c248=COK # Cook Islands # Cyprus - bit 256 ~c200,~c256=CY # Cyprus ~c200,~c256=CYP # Cyprus # Denmark - bit 261 ~c200,~c261=DA # Denmark ~c200,~c261=DNK # Denmark # Djibouti - bit 259 ~c200,~c259=DJ # Djibouti ~c200,~c259=DJI # Djibouti # Dominica - bit 260 ~c200,~c260=DO # Dominica ~c200,~c260=DMA # Dominica # Dominican Republic - bit 262 ~c200,~c262=DR # Dominican Republic ~c200,~c262=DOM # Dominican Republic # Ecuador - bit 264 ~c200,~c264=EC # Ecuador ~c200,~c264=ECU # Ecuador # Egypt - bit 265 ~c200,~c265=EG # Egypt ~c200,~c265=EGY # Egypt # Ireland - bit 305 ~c200,~c305=EI # Ireland ~c200,~c305=IRL # Ireland # Equatorial Guinea - bit 287 ~c200,~c287=EK # Equatorial Guinea ~c200,~c287=GNQ # Equatorial Guinea # Estonia - bit 269 ~c200,~c269=EN # Estonia ~c200,~c269=EST # Estonia # Eritrea - bit 266 ~c200,~c266=ER # Eritrea ~c200,~c266=ERI # Eritrea # El Salvador - bit 399 ~c200,~c399=ES # El Salvador ~c200,~c399=SLV # El Salvador # Ethiopia - bit 270 ~c200,~c270=ET # Ethiopia ~c200,~c270=ETH # Ethiopia # Czech Republic - bit 257 ~c200,~c257=CZE # Czech Republic #~c200,~c257=EZ # Czech Republic # French Guiana - bit 292 ~c200,~c292=FG # French Guiana ~c200,~c292=GUF # French Guiana # Finland - bit 271 ~c200,~c271=FI # Finland ~c200,~c271=FIN # Finland # Fiji - bit 272 ~c200,~c272=FJ # Fiji ~c200,~c272=FJI # Fiji # Falkland Islands (Islas Malvinas) - bit 273 ~c200,~c273=FK # Falkland Islands (Islas Malvinas) ~c200,~c273=FLK # Falkland Islands (Islas Malvinas) # Micronesia, Federated States of - bit 276 ~c200,~c276=FM # Micronesia, Federated States of ~c200,~c276=FSM # Micronesia, Federated States of # Faroe Islands - bit 275 ~c200,~c275=FO # Faroe Islands ~c200,~c275=FRO # Faroe Islands # French Polynesia - bit 384 ~c200,~c384=FP # French Polynesia ~c200,~c384=PYF # French Polynesia # France - bit 274 ~c200,~c274=FR # France ~c200,~c274=FRA # France # French Southern and Antarctic Lands - bit 213 ~c200,~c213=FS # French Southern and Antarctic Lands ~c200,~c213=ATF # French Southern and Antarctic Lands # Gambia, The - bit 285 ~c200,~c285=GA # Gambia, The ~c200,~c285=GMB # Gambia, The # Gabon - bit 277 ~c200,~c277=GB # Gabon ~c200,~c277=GAB # Gabon # Georgia - bit 279 ~c200,~c279=GG # Georgia ~c200,~c279=GEO # Georgia # Ghana - bit 281 ~c200,~c281=GH # Ghana ~c200,~c281=GHA # Ghana # Gibraltar - bit 282 ~c200,~c282=GI # Gibraltar ~c200,~c282=GIB # Gibraltar # Grenada - bit 289 ~c200,~c289=GJ # Grenada ~c200,~c289=GRD # Grenada # Guernsey - bit 280 part of UK ~c200,~c280=GK # Guernsey ~c200,~c280=GGY # Guernsey # Greenland - bit 290 ~c200,~c290=GL # Greenland ~c200,~c290=GRL # Greenland # Germany - bit 258 #~c200,~c258=GM # Germany ~c200,~c258=DEU # Germany # Guadeloupe - bit 284 ~c200,~c284=GP # Guadeloupe ~c200,~c284=GLP # Guadeloupe # Guam - bit 293 ~c200,~c293=GQ # Guam ~c200,~c293=GUM # Guam # Greece - bit 288 ~c200,~c288=GR # Greece ~c200,~c288=GRC # Greece # Guatemala - bit 291 ~c200,~c291=GT # Guatemala ~c200,~c291=GTM # Guatemala # Guinea - bit 283 ~c200,~c283=GV # Guinea ~c200,~c283=GIN # Guinea # Guyana - bit 294 ~c200,~c294=GY # Guyana ~c200,~c294=GUY # Guyana # Gaza Strip - bit 383 #~c200,~c383=GZ # Gaza Strip ~c200,~c383=PSE # Gaza Strip # Haiti - bit 299 ~c200,~c299=HA # Haiti ~c200,~c299=HTI # Haiti # Hong Kong - bit 295 ~c200,~c295=HK # Hong Kong ~c200,~c295=HKG # Hong Kong # Heard Island and McDonald Islands - bit 296 ~c200,~c296=HM # Heard Island and McDonald Islands ~c200,~c296=HMD # Heard Island and McDonald Islands # Honduras - bit 297 ~c200,~c297=HO # Honduras ~c200,~c297=HND # Honduras # Croatia - bit 298 ~c200,~c298=HR # Croatia ~c200,~c298=HRV # Croatia # Hungary - bit 300 ~c200,~c300=HU # Hungary ~c200,~c300=HUN # Hungary # Iceland - bit 308 ~c200,~c308=IC # Iceland ~c200,~c308=ISL # Iceland # Indonesia - bit 301 ~c200,~c301=ID # Indonesia ~c200,~c301=IDN # Indonesia # Isle of Man - bit 302 part of UK ~c200,~c302=IM # Isle of Man ~c200,~c302=IMN # Isle of Man # India - bit 303 ~c200,~c303=IN # India ~c200,~c303=IND # India # British Indian Ocean Territory - bit 304 ~c200,~c304=IO # British Indian Ocean Territory ~c200,~c304=IOT # British Indian Ocean Territory # Iran - bit 306 ~c200,~c306=IR # Iran ~c200,~c306=IRN # Iran # Israel - bit 309 ~c200,~c309=IS # Israel ~c200,~c309=ISR # Israel # Italy - bit 310 ~c200,~c310=IT # Italy ~c200,~c310=ITA # Italy # Cote d'Ivoire - bit 244 ~c200,~c244=IV # Cote d'Ivoire ~c200,~c244=CIV # Cote d'Ivoire # Iraq - bit 307 ~c200,~c307=IZ # Iraq ~c200,~c307=IRQ # Iraq # Japan - bit 314 ~c200,~c314=JA # Japan ~c200,~c314=JPN # Japan # Jersey - bit 312 part of UK ~c200,~c312=JE # Jersey ~c200,~c312=JEY # Jersey # Jamaica - bit 311 ~c200,~c311=JM # Jamaica ~c200,~c311=JAM # Jamaica # Jordan - bit 313 ~c200,~c313=JO # Jordan ~c200,~c313=JOR # Jordan # Kenya - bit 316 ~c200,~c316=KE # Kenya ~c200,~c316=KEN # Kenya # Kyrgyzstan - bit 317 ~c200,~c317=KG # Kyrgyzstan ~c200,~c317=KGZ # Kyrgyzstan # Korea, North - bit 380 ~c200,~c380=KN # Korea, North ~c200,~c380=PRK # Korea, North # Kiribati - bit 319 ~c200,~c319=KR # Kiribati ~c200,~c319=KIR # Kiribati # Korea, South - bit 321 ~c200,~c321=KS # Korea, South ~c200,~c321=ROK # Korea, South # Christmas Island - bit 254 ~c200,~c254=KT # Christmas Island ~c200,~c254=CXR # Christmas Island # Kuwait - bit 322 ~c200,~c322=KU # Kuwait ~c200,~c322=KWT # Kuwait # Kazakhstan - bit 315 ~c200,~c315=KZ # Kazakhstan ~c200,~c315=KAZ # Kazakhstan # Laos - bit 323 ~c200,~c323=LA # Laos ~c200,~c323=LAO # Laos # Lebanon - bit 324 ~c200,~c324=LE # Lebanon ~c200,~c324=LBN # Lebanon # Latvia - bit 333 ~c200,~c333=LG # Latvia ~c200,~c333=LVA # Latvia # Lithuania - bit 331 ~c200,~c331=LH # Lithuania ~c200,~c331=LTU # Lithuania # Liberia - bit 325 ~c200,~c325=LI # Liberia ~c200,~c325=LBR # Liberia # Slovakia - bit 406 ~c200,~c406=LO # Slovakia ~c200,~c406=SVK # Slovakia # Liechtenstein - bit 328 ~c200,~c328=LS # Liechtenstein ~c200,~c328=LIE # Liechtenstein # Lesotho - bit 330 ~c200,~c330=LT # Lesotho ~c200,~c330=LSO # Lesotho # Luxembourg - bit 332 ~c200,~c332=LU # Luxembourg ~c200,~c332=LUX # Luxembourg # Libya - bit 326 ~c200,~c326=LY # Libya ~c200,~c326=LBY # Libya # Madagascar - bit 339 ~c200,~c339=MA # Madagascar ~c200,~c339=MDG # Madagascar # Martinique - bit 353 ~c200,~c353=MB # Martinique ~c200,~c353=MTQ # Martinique # Macau - bit 334 ~c200,~c334=MC # Macau ~c200,~c334=MAC # Macau # Moldova - bit 338 ~c200,~c338=MD # Moldova ~c200,~c338=MDA # Moldova # Mayotte - bit 357 part of FRA ~c200,~c357=MF # Mayotte ~c200,~c357=MYT # Mayotte # Mongolia - bit 348 ~c200,~c348=MG # Mongolia ~c200,~c348=MNG # Mongolia # Montserrat - bit 352 ~c200,~c352=MH # Montserrat ~c200,~c352=MSR # Montserrat # Malawi - bit 355 ~c200,~c355=MI # Malawi ~c200,~c355=MWI # Malawi # Montenegro - bit 347 ~c200,~c347=MJ # Montenegro ~c200,~c347=MNE # Montenegro # Macedonia - bit 343 part of FYR ~c200,~c343=MK # Macedonia ~c200,~c343=MKD # Macedonia # Mali - bit 344 ~c200,~c344=ML # Mali ~c200,~c344=MLI # Mali # Monaco - bit 337 ~c200,~c337=MN # Monaco ~c200,~c337=MCO # Monaco # Morocco - bit 336 ~c200,~c336=MO # Morocco ~c200,~c336=MAR # Morocco # Mauritius - bit 354 ~c200,~c354=MP # Mauritius ~c200,~c354=MUS # Mauritius # Mauritania - bit 351 ~c200,~c351=MR # Mauritania ~c200,~c351=MRT # Mauritania # Malta - bit 345 ~c200,~c345=MT # Malta ~c200,~c345=MLT # Malta # Oman - bit 370 ~c200,~c370=MU # Oman ~c200,~c370=OMN # Oman # Maldives - bit 340 ~c200,~c340=MV # Maldives ~c200,~c340=MDV # Maldives # Mexico - bit 341 ~c200,~c341=MX # Mexico ~c200,~c341=MEX # Mexico # Malaysia - bit 356 ~c200,~c356=MY # Malaysia ~c200,~c356=MYS # Malaysia # Mozambique - bit 350 ~c200,~c350=MZ # Mozambique ~c200,~c350=MOZ # Mozambique # New Caledonia - bit 359 ~c200,~c359=NC # New Caledonia ~c200,~c359=NCL # New Caledonia # Niue - bit 364 ~c200,~c364=NE # Niue ~c200,~c364=NIU # Niue # Norfolk Island - bit 361 ~c200,~c361=NF # Norfolk Island ~c200,~c361=NFK # Norfolk Island # Niger - bit 360 ~c200,~c360=NG # Niger ~c200,~c360=NER # Niger # Vanuatu - bit 438 ~c200,~c438=NH # Vanuatu ~c200,~c438=VUT # Vanuatu # Nigeria - bit 362 ~c200,~c362=NI # Nigeria ~c200,~c362=NGA # Nigeria # Netherlands - bit 365 ~c200,~c365=NL # Netherlands ~c200,~c365=NLD # Netherlands # Norway - bit 366 ~c200,~c366=NO # Norway ~c200,~c366=NOR # Norway # Nepal - bit 367 ~c200,~c367=NP # Nepal ~c200,~c367=NPL # Nepal # Nauru - bit 368 ~c200,~c368=NR # Nauru ~c200,~c368=NRU # Nauru # Suriname - bit 405 ~c200,~c405=NS # Suriname ~c200,~c405=SUR # Suriname # Netherlands Antilles - bit 207 ~c200,~c207=NT # Netherlands Antilles ~c200,~c207=ANT # Netherlands Antilles # Nicaragua - bit 363 ~c200,~c363=NU # Nicaragua ~c200,~c363=NIC # Nicaragua # New Zealand - bit 369 ~c200,~c369=NZ # New Zealand ~c200,~c369=NZL # New Zealand # Paraguay - bit 382 ~c200,~c382=PA # Paraguay ~c200,~c382=PRY # Paraguay # Pitcairn Islands - bit 373 ~c200,~c373=PC # Pitcairn Islands ~c200,~c373=PCN # Pitcairn Islands # Peru - bit 374 ~c200,~c374=PE # Peru ~c200,~c374=PER # Peru # Pakistan - bit 371 ~c200,~c371=PK # Pakistan ~c200,~c371=PAK # Pakistan # Poland - bit 378 ~c200,~c378=PL # Poland ~c200,~c378=POL # Poland # Panama - bit 372 ~c200,~c372=PM # Panama ~c200,~c372=PAN # Panama # Portugal - bit 381 ~c200,~c381=PO # Portugal ~c200,~c381=PRT # Portugal # Papua New Guinea - bit 377 ~c200,~c377=PP # Papua New Guinea ~c200,~c377=PNG # Papua New Guinea # Palau - bit 376 #~c200,~c376=PS # Palau ~c200,~c376=PLW # Palau # Guinea-Bissau - bit 286 ~c200,~c286=PU # Guinea-Bissau ~c200,~c286=GNB # Guinea-Bissau # Qatar - bit 385 ~c200,~c385=QA # Qatar ~c200,~c385=QAT # Qatar # Serbia - bit 403 #~c200,~c403=RB # Serbia ~c200,~c403=SRB # Serbia # Reunion - bit 386 ~c200,~c386=RE # Reunion ~c200,~c386=REU # Reunion # Marshall Islands - bit 342 ~c200,~c342=RM # Marshall Islands ~c200,~c342=MHL # Marshall Islands # Saint Martin - bit 335 ~c200,~c335=RN # Saint Martin ~c200,~c335=MAF # Saint Martin # Romania - bit 387 ~c200,~c387=RO # Romania ~c200,~c387=ROU # Romania # Philippines - bit 375 ~c200,~c375=RP # Philippines ~c200,~c375=PHL # Philippines # Puerto Rico - bit 379 ~c200,~c379=RQ # Puerto Rico ~c200,~c379=PRI # Puerto Rico # Russia - bit 388 #~c200,~c388=RS # Russia ~c200,~c388=RUS # Russia # Rwanda - bit 389 ~c200,~c389=RW # Rwanda ~c200,~c389=RWA # Rwanda # Saudi Arabia - bit 390 ~c200,~c390=SA # Saudi Arabia ~c200,~c390=SAU # Saudi Arabia # Saint Pierre and Miquelon - bit 402 ~c200,~c402=SB # Saint Pierre and Miquelon ~c200,~c402=SPM # Saint Pierre and Miquelon # Saint Kitts and Nevis - bit 320 ~c200,~c320=SC # Saint Kitts and Nevis ~c200,~c320=KNA # Saint Kitts and Nevis # Seychelles - bit 410 ~c200,~c410=SE # Seychelles ~c200,~c410=SYC # Seychelles # South Africa - bit 442 ~c200,~c442=SF # South Africa ~c200,~c442=ZAF # South Africa # Senegal - bit 392 ~c200,~c392=SG # Senegal ~c200,~c392=SEN # Senegal # Saint Helena - bit 395 ~c200,~c395=SH # Saint Helena ~c200,~c395=SHN # Saint Helena # Slovenia - bit 407 #~c200,~c407=SI # Slovenia ~c200,~c407=SVN # Slovenia # Sierra Leone - bit 398 ~c200,~c398=SL # Sierra Leone ~c200,~c398=SLE # Sierra Leone # San Marino - bit 400 ~c200,~c400=SM # San Marino ~c200,~c400=SMR # San Marino # Singapore - bit 393 ~c200,~c393=SN # Singapore ~c200,~c393=SGP # Singapore # Somalia - bit 401 ~c200,~c401=SO # Somalia ~c200,~c401=SOM # Somalia # Spain - bit 268 #~c200,~c268=SP # Spain ~c200,~c268=ESP # Spain # Saint Lucia - bit 327 ~c200,~c327=ST # Saint Lucia ~c200,~c327=LCA # Saint Lucia # Sudan - bit 391 ~c200,~c391=SU # Sudan ~c200,~c391=SDN # Sudan # Svalbard - bit 396 #~c200,~c396=SV # Svalbard ~c200,~c396=SJM # Svalbard # Sweden - bit 408 ~c200,~c408=SW # Sweden ~c200,~c408=SWE # Sweden # South Georgia and the Islands - bit 394 ~c200,~c394=SX # South Georgia and the Islands ~c200,~c394=SGS # South Georgia and the Islands # Syria - bit 411 ~c200,~c411=SY # Syria ~c200,~c411=SYR # Syria # Switzerland - bit 241 ~c200,~c241=SZ # Switzerland ~c200,~c241=CHE # Switzerland # Saint Barthelemy - bit 227 ~c200,~c227=TB # Saint Barthelemy ~c200,~c227=BLM # Saint Barthelemy # Trinidad and Tobago - bit 421 ~c200,~c421=TD # Trinidad and Tobago ~c200,~c421=TTO # Trinidad and Tobago # Thailand - bit 415 ~c200,~c415=TH # Thailand ~c200,~c415=THA # Thailand # Tajikistan - bit 416 ~c200,~c416=TI # Tajikistan ~c200,~c416=TJK # Tajikistan # Turks and Caicos Islands - bit 412 ~c200,~c412=TK # Turks and Caicos Islands ~c200,~c412=TCA # Turks and Caicos Islands # Togo - bit 414 ~c200,~c414=TGO # Togo # Tokelau - bit 417 ~c200,~c417=TL # Tokelau ~c200,~c417=TKL # Tokelau # Tonga - bit 420 ~c200,~c420=TN # Tonga ~c200,~c420=TON # Tonga # Sao Tome and Principe - bit 404 ~c200,~c404=TP # Sao Tome and Principe ~c200,~c404=STP # Sao Tome and Principe # Tunisia - bit 422 ~c200,~c422=TS # Tunisia ~c200,~c422=TUN # Tunisia # Timor-Leste - bit 419 ~c200,~c419=TT # Timor-Leste ~c200,~c419=TLS # Timor-Leste # Turkey - bit 423 ~c200,~c423=TU # Turkey ~c200,~c423=TUR # Turkey # Tuvalu - bit 424 ~c200,~c424=TV # Tuvalu ~c200,~c424=TUV # Tuvalu # Taiwan - bit 425 ~c200,~c425=TW # Taiwan ~c200,~c425=TWN # Taiwan # Turkmenistan - bit 418 ~c200,~c418=TX # Turkmenistan ~c200,~c418=TKM # Turkmenistan # Tanzania - bit 426 ~c200,~c426=TZ # Tanzania ~c200,~c426=TZA # Tanzania # Uganda - bit 427 ~c200,~c427=UG # Uganda ~c200,~c427=UGA # Uganda # United Kingdom - bit 278 ~c200,~c278=UK # United Kingdom ~c200,~c278=GBR # United Kingdom # Ukraine - bit 428 ~c200,~c428=UP # Ukraine ~c200,~c428=UKR # Ukraine # United States - bit 430 ~c200,~c430=US # United States ~c200,~c430=USA # United States # Burkina Faso - bit 221 ~c200,~c221=UV # Burkina Faso ~c200,~c221=BFA # Burkina Faso # Uruguay - bit 429 ~c200,~c429=UY # Uruguay ~c200,~c429=URY # Uruguay # Uzbekistan - bit 431 ~c200,~c431=UZ # Uzbekistan ~c200,~c431=UZB # Uzbekistan # Saint Vincent and the Grenadines - bit 433 ~c200,~c433=VC # Saint Vincent and the Grenadines ~c200,~c433=VCT # Saint Vincent and the Grenadines # Venezuela - bit 434 ~c200,~c434=VE # Venezuela ~c200,~c434=VEN # Venezuela # British Virgin Islands - bit 435 ~c200,~c435=VI # British Virgin Islands ~c200,~c435=VGB # British Virgin Islands # Vietnam - bit 437 ~c200,~c437=VM # Vietnam ~c200,~c437=VNM # Vietnam # Virgin Islands - bit 436 #~c200,~c436=VQ # Virgin Islands ~c200,~c436=VIR # Virgin Islands # Holy See (Vatican City) - bit 432 ~c200,~c432=VT # Holy See (Vatican City) ~c200,~c432=VAT # Holy See (Vatican City) # Namibia - bit 358 ~c200,~c358=WA # Namibia ~c200,~c358=NAM # Namibia # West Bank - bit 383 ~c200,~c383=WE # West Bank # Wallis and Futuna - bit 439 ~c200,~c439=WF # Wallis and Futuna ~c200,~c439=WLF # Wallis and Futuna # Western Sahara - bit 267 ~c200,~c267=WI # Western Sahara ~c200,~c267=ESH # Western Sahara # Samoa - bit 440 #~c200,~c440=WS # Samoa ~c200,~c440=WSM # Samoa # Swaziland - bit 409 ~c200,~c409=WZ # Swaziland ~c200,~c409=SWZ # Swaziland # Yemen - bit 441 #~c200,~c441=YM # Yemen ~c200,~c441=YEM # Yemen # Zambia - bit 443 ~c200,~c443=ZA # Zambia ~c200,~c443=ZMB # Zambia # Zimbabwe - bit 444 ~c200,~c444=ZI # Zimbabwe ~c200,~c444=ZWE # Zimbabwe #UNCLASSIFIED mcstrans-3.3/share/examples/non-mls-color/000077500000000000000000000000001413427467300206435ustar00rootroot00000000000000mcstrans-3.3/share/examples/non-mls-color/README000066400000000000000000000002461413427467300215250ustar00rootroot00000000000000Non-MLS color example To use: cp secolor.conf /etc/selinux/mls/ run_init /etc/init.d/mcstrans restart To test: /usr/share/mcstrans/util/mlscolor-test non-mls.color mcstrans-3.3/share/examples/non-mls-color/non-mls.color000066400000000000000000000004501413427467300232650ustar00rootroot00000000000000system_u:system_r:inetd_t:SystemLow=#000000 #008000 #ffffff #000000 #d2b48c #ffa500 #000000 #008000 system_u:system_r:inetd_t:SystemHigh=#000000 #008000 #ffffff #000000 #d2b48c #ffa500 #000000 #008000 user_u:user_r:user_t:SystemLow=#000000 #008000 #ffffff #000000 #d2b48c #ffa500 #000000 #008000 mcstrans-3.3/share/examples/non-mls-color/secolor.conf000066400000000000000000000003551413427467300231630ustar00rootroot00000000000000 color black = #000000 color green = #008000 color yellow = #ffff00 color blue = #0000ff color white = #ffffff color red = #ff0000 color orange = #ffa500 color tan = #D2B48C user * = black green role * = white black type * = tan orange mcstrans-3.3/share/examples/pipes/000077500000000000000000000000001413427467300172645ustar00rootroot00000000000000mcstrans-3.3/share/examples/pipes/pipes.test000066400000000000000000000006101413427467300213020ustar00rootroot00000000000000Restricted Handle Via Iron Pipes Only==s2:c102,c200.c511 Restricted Handle Via Copper Pipes Only==s2:c103,c200.c511 Restricted Handle Via Plastic Pipes Only==s2:c101,c200.c511 Restricted Handle Via Galvanized Pipes Only==s2:c104,c200.c511 Restricted Handle Via Plastic,Iron,Copper Pipes Only==s2:c101.c103,c200.c511 Restricted Handle Via Iron,Plastic,Copper Pipes Only=s2:c101.c103,c200.c511 mcstrans-3.3/share/examples/pipes/setrans.conf000066400000000000000000000005251413427467300216140ustar00rootroot00000000000000 Domain=PipesTest s0=SystemLow s15:c0.c1023=SystemHigh s0-s15:c0.c1023=SystemLow-SystemHigh Base=Sensitivity Levels s1=Unclassified s1=U s2:c200.c511=Restricted s2:c200.c511=R s3:c200.c511=Confidential s3:c200.c511=C s4:c200.c511=Secret s4:c200.c511=S s5:c200.c511=Top Secret s5:c200.c511=TS Include=/etc/selinux/mls/setrans.d/pipes.conf mcstrans-3.3/share/examples/pipes/setrans.d/000077500000000000000000000000001413427467300211655ustar00rootroot00000000000000mcstrans-3.3/share/examples/pipes/setrans.d/pipes.conf000066400000000000000000000002171413427467300231540ustar00rootroot00000000000000ModifierGroup=Pipes Prefix=Handle Via Suffix=Pipes Only Suffix=Pipes Whitespace=, Join=, c101=Plastic c102=Iron c103=Copper c104=Galvanized mcstrans-3.3/share/examples/urcsts-via-include/000077500000000000000000000000001413427467300216655ustar00rootroot00000000000000mcstrans-3.3/share/examples/urcsts-via-include/README000066400000000000000000000005451413427467300225510ustar00rootroot00000000000000Simple handling of UNCLASSIFIED RESTRICTED CONFIDENTIAL SECRET TOP SECRET via include files To use: cp -L setrans.conf /etc/selinux/mls/ cp -L secolor.conf /etc/selinux/mls/ rm -f /etc/selinux/mls/setrans.d/* cp setrans.d/* /etc/selinux/mls/setrans.d run_init /etc/init.d/mcstrans restart To test: /usr/share/mcstrans/util/mlstrans-test urcsts.test mcstrans-3.3/share/examples/urcsts-via-include/secolor.conf000066400000000000000000000007431413427467300242060ustar00rootroot00000000000000 color black = #000000 color green = #008000 color yellow = #ffff00 color blue = #0000ff color white = #ffffff color red = #ff0000 color orange = #ffa500 color tan = #D2B48C user * = black black role * = black black type * = black black range s0-s0:c0.c1023 = black green range s1-s1:c0.c1023 = black green range s3-s3:c0.c1023 = black tan range s5-s5:c0.c1023 = white blue range s7-s7:c0.c1023 = black red range s9-s9:c0.c1023 = black orange range s15-s15:c0.c1023 = black yellow mcstrans-3.3/share/examples/urcsts-via-include/setrans.conf000066400000000000000000000007461413427467300242220ustar00rootroot00000000000000# # Multi-Level Security translation table for SELinux # # Uncomment the following to disable translation library # disable=1 # # Objects can be labeled with one of 16 levels and be categorized with 0-1023 # categories defined by the admin. # Objects can be in more than one category at a time. # Users can modify this table to translate the MLS labels for different purpose. # # Demonstrate Include by moving everything to an include file # Include=/etc/selinux/mls/setrans.d/*.conf mcstrans-3.3/share/examples/urcsts-via-include/setrans.d/000077500000000000000000000000001413427467300235665ustar00rootroot00000000000000mcstrans-3.3/share/examples/urcsts-via-include/setrans.d/c.conf000066400000000000000000000001201413427467300246500ustar00rootroot00000000000000# UNCLASSIFIED s5=CONFIDENTIAL s5=C O N F I D E N T I A L s5=C # UNCLASSIFIED mcstrans-3.3/share/examples/urcsts-via-include/setrans.d/r.conf000066400000000000000000000001121413427467300246700ustar00rootroot00000000000000# UNCLASSIFIED s3=RESTRICTED s3=R E S T R I C T E D s3=R # UNCLASSIFIED mcstrans-3.3/share/examples/urcsts-via-include/setrans.d/s.conf000066400000000000000000000000761413427467300247020ustar00rootroot00000000000000# UNCLASSIFIED s7=SECRET s7=S E C R E T s7=S # UNCLASSIFIED mcstrans-3.3/share/examples/urcsts-via-include/setrans.d/system.conf000066400000000000000000000001051413427467300257550ustar00rootroot00000000000000# UNCLASSIFIED s0=SystemLow s15:c0.c1023=SystemHigh # UNCLASSIFIED mcstrans-3.3/share/examples/urcsts-via-include/setrans.d/ts.conf000066400000000000000000000001371413427467300250640ustar00rootroot00000000000000# UNCLASSIFIED s9=TOP SECRET s9=T O P S E C R E T s9=T O P S E C R E T s9=TS # UNCLASSIFIED mcstrans-3.3/share/examples/urcsts-via-include/setrans.d/u.conf000066400000000000000000000000771413427467300247050ustar00rootroot00000000000000# UNCLASSIFIED s1=UNCLASSIFIED s1=UNCLAS s1=U # UNCLASSIFIED mcstrans-3.3/share/examples/urcsts-via-include/urcsts.color000066400000000000000000000036341413427467300242560ustar00rootroot00000000000000system_u:system_r:inetd_t:SystemLow=#000000 #000000 #000000 #000000 #000000 #000000 #000000 #008000 system_u:system_r:inetd_t:s0=#000000 #000000 #000000 #000000 #000000 #000000 #000000 #008000 system_u:system_r:inetd_t:s0:c1=#000000 #000000 #000000 #000000 #000000 #000000 #000000 #008000 system_u:system_r:inetd_t:UNCLASSIFIED=#000000 #000000 #000000 #000000 #000000 #000000 #000000 #008000 system_u:system_r:inetd_t:s1=#000000 #000000 #000000 #000000 #000000 #000000 #000000 #008000 system_u:system_r:inetd_t:s1:c2=#000000 #000000 #000000 #000000 #000000 #000000 #000000 #008000 system_u:system_r:inetd_t:RESTRICTED=#000000 #000000 #000000 #000000 #000000 #000000 #000000 #d2b48c system_u:system_r:inetd_t:s3=#000000 #000000 #000000 #000000 #000000 #000000 #000000 #d2b48c system_u:system_r:inetd_t:s3:c3=#000000 #000000 #000000 #000000 #000000 #000000 #000000 #d2b48c system_u:system_r:inetd_t:CONFIDENTIAL=#000000 #000000 #000000 #000000 #000000 #000000 #ffffff #0000ff system_u:system_r:inetd_t:s5=#000000 #000000 #000000 #000000 #000000 #000000 #ffffff #0000ff system_u:system_r:inetd_t:s5:c0.c5=#000000 #000000 #000000 #000000 #000000 #000000 #ffffff #0000ff system_u:system_r:inetd_t:SECRET=#000000 #000000 #000000 #000000 #000000 #000000 #000000 #ff0000 system_u:system_r:inetd_t:s7=#000000 #000000 #000000 #000000 #000000 #000000 #000000 #ff0000 system_u:system_r:inetd_t:s7:c200.c300=#000000 #000000 #000000 #000000 #000000 #000000 #000000 #ff0000 system_u:system_r:inetd_t:TOP SECRET=#000000 #000000 #000000 #000000 #000000 #000000 #000000 #ffa500 system_u:system_r:inetd_t:s9=#000000 #000000 #000000 #000000 #000000 #000000 #000000 #ffa500 system_u:system_r:inetd_t:s9:c1023=#000000 #000000 #000000 #000000 #000000 #000000 #000000 #ffa500 system_u:system_r:inetd_t:s15=#000000 #000000 #000000 #000000 #000000 #000000 #000000 #ffff00 system_u:system_r:inetd_t:SystemHigh=#000000 #000000 #000000 #000000 #000000 #000000 #000000 #ffff00 mcstrans-3.3/share/examples/urcsts-via-include/urcsts.test000066400000000000000000000004451413427467300241140ustar00rootroot00000000000000# UNCLASSIFIED SystemLow=s0 SystemHigh=s15:c0.c1023 UNCLASSIFIED==s1 UNCLAS=s1 U=s1 RESTRICTED==s3 R E S T R I C T E D=s3 R=s3 CONFIDENTIAL==s5 C O N F I D E N T I A L=s5 C=s5 SECRET==s7 S E C R E T=s7 S=s7 TOP SECRET==s9 T O P S E C R E T=s9 T O P S E C R E T=s9 TS=s9 # UNCLASSIFIED mcstrans-3.3/share/examples/urcsts/000077500000000000000000000000001413427467300174675ustar00rootroot00000000000000mcstrans-3.3/share/examples/urcsts/README000066400000000000000000000004771413427467300203570ustar00rootroot00000000000000Simple handling of UNCLASSIFIED RESTRICTED CONFIDENTIAL SECRET TOP SECRET To use: cp setrans.conf /etc/selinux/mls/setrans.conf cp secolor.conf /etc/selinux/mls/ run_init /etc/init.d/mcstrans restart To test: /usr/share/mcstrans/util/mlstrans-test urcsts.test /usr/share/mcstrans/util/mlscolor-test urcsts.color mcstrans-3.3/share/examples/urcsts/secolor.conf000066400000000000000000000007431413427467300220100ustar00rootroot00000000000000 color black = #000000 color green = #008000 color yellow = #ffff00 color blue = #0000ff color white = #ffffff color red = #ff0000 color orange = #ffa500 color tan = #D2B48C user * = black black role * = black black type * = black black range s0-s0:c0.c1023 = black green range s1-s1:c0.c1023 = black green range s3-s3:c0.c1023 = black tan range s5-s5:c0.c1023 = white blue range s7-s7:c0.c1023 = black red range s9-s9:c0.c1023 = black orange range s15-s15:c0.c1023 = black yellow mcstrans-3.3/share/examples/urcsts/setrans.conf000066400000000000000000000004401413427467300220130ustar00rootroot00000000000000# UNCLASSIFIED s0=SystemLow s15:c0.c1023=SystemHigh s1=UNCLASSIFIED s1=UNCLAS s1=U s3=RESTRICTED s3=R E S T R I C T E D s3=R s5=CONFIDENTIAL s5=C O N F I D E N T I A L s5=C s7=SECRET s7=S E C R E T s7=S s9=TOP SECRET s9=T O P S E C R E T s9=T O P S E C R E T s9=TS # UNCLASSIFIED mcstrans-3.3/share/examples/urcsts/urcsts.color000066400000000000000000000036341413427467300220600ustar00rootroot00000000000000system_u:system_r:inetd_t:SystemLow=#000000 #000000 #000000 #000000 #000000 #000000 #000000 #008000 system_u:system_r:inetd_t:s0=#000000 #000000 #000000 #000000 #000000 #000000 #000000 #008000 system_u:system_r:inetd_t:s0:c1=#000000 #000000 #000000 #000000 #000000 #000000 #000000 #008000 system_u:system_r:inetd_t:UNCLASSIFIED=#000000 #000000 #000000 #000000 #000000 #000000 #000000 #008000 system_u:system_r:inetd_t:s1=#000000 #000000 #000000 #000000 #000000 #000000 #000000 #008000 system_u:system_r:inetd_t:s1:c2=#000000 #000000 #000000 #000000 #000000 #000000 #000000 #008000 system_u:system_r:inetd_t:RESTRICTED=#000000 #000000 #000000 #000000 #000000 #000000 #000000 #d2b48c system_u:system_r:inetd_t:s3=#000000 #000000 #000000 #000000 #000000 #000000 #000000 #d2b48c system_u:system_r:inetd_t:s3:c3=#000000 #000000 #000000 #000000 #000000 #000000 #000000 #d2b48c system_u:system_r:inetd_t:CONFIDENTIAL=#000000 #000000 #000000 #000000 #000000 #000000 #ffffff #0000ff system_u:system_r:inetd_t:s5=#000000 #000000 #000000 #000000 #000000 #000000 #ffffff #0000ff system_u:system_r:inetd_t:s5:c0.c5=#000000 #000000 #000000 #000000 #000000 #000000 #ffffff #0000ff system_u:system_r:inetd_t:SECRET=#000000 #000000 #000000 #000000 #000000 #000000 #000000 #ff0000 system_u:system_r:inetd_t:s7=#000000 #000000 #000000 #000000 #000000 #000000 #000000 #ff0000 system_u:system_r:inetd_t:s7:c200.c300=#000000 #000000 #000000 #000000 #000000 #000000 #000000 #ff0000 system_u:system_r:inetd_t:TOP SECRET=#000000 #000000 #000000 #000000 #000000 #000000 #000000 #ffa500 system_u:system_r:inetd_t:s9=#000000 #000000 #000000 #000000 #000000 #000000 #000000 #ffa500 system_u:system_r:inetd_t:s9:c1023=#000000 #000000 #000000 #000000 #000000 #000000 #000000 #ffa500 system_u:system_r:inetd_t:s15=#000000 #000000 #000000 #000000 #000000 #000000 #000000 #ffff00 system_u:system_r:inetd_t:SystemHigh=#000000 #000000 #000000 #000000 #000000 #000000 #000000 #ffff00 mcstrans-3.3/share/examples/urcsts/urcsts.test000066400000000000000000000004451413427467300217160ustar00rootroot00000000000000# UNCLASSIFIED SystemLow=s0 SystemHigh=s15:c0.c1023 UNCLASSIFIED==s1 UNCLAS=s1 U=s1 RESTRICTED==s3 R E S T R I C T E D=s3 R=s3 CONFIDENTIAL==s5 C O N F I D E N T I A L=s5 C=s5 SECRET==s7 S E C R E T=s7 S=s7 TOP SECRET==s9 T O P S E C R E T=s9 T O P S E C R E T=s9 TS=s9 # UNCLASSIFIED mcstrans-3.3/share/util/000077500000000000000000000000001413427467300153035ustar00rootroot00000000000000mcstrans-3.3/share/util/mlscolor-test000066400000000000000000000021311413427467300200320ustar00rootroot00000000000000#!/usr/bin/python3 -E import sys import selinux verbose = 0 errors = 0 if len(sys.argv) > 1 and sys.argv[1] == "-v": verbose = 1 for arg in sys.argv[1:]: f = open(arg, 'r') for line in f: if line.startswith('#'): continue if not line.strip(): continue line = line.rstrip('\n') # print line context, expected = line.split("=") rc, raw = selinux.selinux_trans_to_raw_context(context) if rc < 0: print("Unable to get raw context of '%s'" % (context)) errors += 1 continue rc, colors = selinux.selinux_raw_context_to_color(raw) if rc < 0: print("Unable to get colors for '%s'" % (context)) errors += 1 continue colors = colors.rstrip() if colors != expected: print("For '%s' got\n\t'%s' expected\n\t'%s'" % (context, colors, expected)) errors += 1 continue f.close() s = "s" if errors == 1: s = "" print("mlscolor-test done with %d error%s" % (errors, s)) sys.exit(errors) mcstrans-3.3/share/util/mlstrans-test000066400000000000000000000025631413427467300200540ustar00rootroot00000000000000#!/usr/bin/python3 -E import sys import selinux verbose = 0 errors = 0 def untrans(trans, val): global errors, verbose (rc, raw) = selinux.selinux_trans_to_raw_context(trans) if raw != val: print("untrans: '%s' -> '%s' != '%s' FAILED" % (trans, raw, val)) errors += 1 else: if verbose: print("untrans: '%s' -> '%s' == '%s' SUCCESS" % (trans, raw, val)) def trans(raw, val): global errors, verbose (rc, trans) = selinux.selinux_raw_to_trans_context(raw) if trans != val: print("trans: '%s' -> '%s' != '%s' FAILED" % (raw, trans, val)) errors += 1 else: if verbose: print("trans: '%s' -> '%s' == '%s' SUCCESS" % (raw, trans, val)) if len(sys.argv) > 1 and sys.argv[1] == "-v": verbose = 1 for arg in sys.argv[1:]: f = open(arg, 'r') for line in f: if line.startswith('#'): continue if not line.strip(): continue line = line.rstrip('\n') if line.find("==") != -1: t, r = line.split("==") untrans("a:b:c:" + t, "a:b:c:" + r) trans("a:b:c:" + r, "a:b:c:" + t) else: t, r = line.split("=") untrans("a:b:c:" + t, "a:b:c:" + r) f.close() s = "s" if errors == 1: s = "" print("mlstrans-test done with %d error%s" % (errors, s)) sys.exit(errors) mcstrans-3.3/share/util/try-all000066400000000000000000000033411413427467300166130ustar00rootroot00000000000000#!/bin/bash shopt -s nullglob fail() { echo $1 exit 1 } [ `id -u` = 0 ] || fail "must run as root" for d in /usr/share/mcstrans/examples/*; do echo $d rm -rf /etc/selinux/mls/setrans.conf.bak /etc/selinux/mls/secolor.conf.bak /etc/selinux/mls/setrans.d.bak [ $? -eq 0 ] || fail "preclean failed" if [ -e $d/setrans.conf ]; then mv /etc/selinux/mls/setrans.conf /etc/selinux/mls/setrans.conf.bak [ $? -eq 0 ] || fail "setrans.conf backup failed" fi if [ -e /etc/selinux/mls/secolor.conf ]; then mv /etc/selinux/mls/secolor.conf /etc/selinux/mls/secolor.conf.bak [ $? -eq 0 ] || fail "secolor.conf backup failed" fi mv /etc/selinux/mls/setrans.d /etc/selinux/mls/setrans.d.bak [ $? -eq 0 ] || fail "setrans.d backup failed" if [ -e $d/setrans.conf ]; then cp -L $d/setrans.conf /etc/selinux/mls/setrans.conf fi if [ -e $d/secolor.conf ]; then cp -L $d/secolor.conf /etc/selinux/mls fi if [ -d $d/setrans.d ]; then cp -Lr $d/setrans.d /etc/selinux/mls fi runcon `cat /etc/selinux/mls/contexts/initrc_context` /etc/init.d/mcstrans restart for t in $d/*.test; do /usr/share/mcstrans/util/mlstrans-test $t done for c in $d/*.color; do /usr/share/mcstrans/util/mlscolor-test $c done if [ -e /etc/selinux/mls/setrans.conf.bak ]; then mv /etc/selinux/mls/setrans.conf.bak /etc/selinux/mls/setrans.conf fi if [ -e /etc/selinux/mls/secolor.conf.bak ]; then mv /etc/selinux/mls/secolor.conf.bak /etc/selinux/mls/secolor.conf fi rm -rf /etc/selinux/mls/setrans.d mv /etc/selinux/mls/setrans.d.bak /etc/selinux/mls/setrans.d restorecon -rv /etc/selinux/mls/setrans.conf /etc/selinux/mls/setrans.d >/dev/null runcon `cat /etc/selinux/mls/contexts/initrc_context` /etc/init.d/mcstrans restart done exit 0 mcstrans-3.3/src/000077500000000000000000000000001413427467300140135ustar00rootroot00000000000000mcstrans-3.3/src/.gitignore000066400000000000000000000000121413427467300157740ustar00rootroot00000000000000mcstransd mcstrans-3.3/src/Makefile000066400000000000000000000024431413427467300154560ustar00rootroot00000000000000# Installation directories. PREFIX ?= /usr SBINDIR ?= /sbin INITDIR ?= /etc/rc.d/init.d SYSTEMDDIR ?= $(PREFIX)/lib/systemd # If no specific libsepol.a is specified, fall back on LDFLAGS search path # Otherwise, as $(LIBSEPOLA) already appears in the dependencies, there # is no need to define a value for LDLIBS_LIBSEPOLA ifeq ($(LIBSEPOLA),) LDLIBS_LIBSEPOLA := -l:libsepol.a endif PROG_SRC=mcstrans.c mcscolor.c mcstransd.c mls_level.c PROG_OBJS= $(patsubst %.c,%.o,$(PROG_SRC)) PROG=mcstransd INITSCRIPT=mcstrans CFLAGS ?= -Wall -W -Wundef -Wmissing-noreturn -Wmissing-format-attribute all: $(PROG) $(PROG): $(PROG_OBJS) $(LIBSEPOLA) $(CC) $(LDFLAGS) -pie -o $@ $^ -lselinux -lcap -lpcre $(LDLIBS_LIBSEPOLA) %.o: %.c $(CC) $(CFLAGS) -D_GNU_SOURCE -D_FILE_OFFSET_BITS=64 -fPIE -c -o $@ $< install: all test -d $(DESTDIR)$(SBINDIR) || install -m 755 -d $(DESTDIR)$(SBINDIR) install -m 755 $(PROG) $(DESTDIR)$(SBINDIR) test -d $(DESTDIR)$(INITDIR) || install -m 755 -d $(DESTDIR)$(INITDIR) install -m 755 $(INITSCRIPT).init $(DESTDIR)$(INITDIR)/$(INITSCRIPT) test -d $(DESTDIR)$(SYSTEMDDIR)/system || install -m 755 -d $(DESTDIR)$(SYSTEMDDIR)/system install -m 644 mcstrans.service $(DESTDIR)$(SYSTEMDDIR)/system/ clean: -rm -f $(OBJS) $(LOBJS) $(TARGET) $(PROG) $(PROG_OBJS) *~ \#* mcstrans-3.3/src/README000066400000000000000000000002331413427467300146710ustar00rootroot00000000000000To rebuild with debugging support: make clean && env CFLAGS="-Wall -W -Wundef -Wmissing-noreturn -Wmissing-format-attribute -DDEBUG -g" LDFLAGS="-g" make mcstrans-3.3/src/mcscolor.c000066400000000000000000000155171413427467300160110ustar00rootroot00000000000000#include #include #include #include #include #include #include #include #include #include #include #include #include #include "mcstrans.h" /* Define data structures */ typedef struct secolor { uint32_t fg; uint32_t bg; } secolor_t; typedef struct semnemonic { char *name; uint32_t color; struct semnemonic *next; } semnemonic_t; typedef struct setab { char *pattern; secolor_t color; struct setab *next; } setab_t; #define COLOR_USER 0 #define COLOR_ROLE 1 #define COLOR_TYPE 2 #define COLOR_RANGE 3 #define N_COLOR 4 #define AUX_RULE_COLOR "color" static const char *rules[] = { "user", "role", "type", "range" }; static setab_t *clist[N_COLOR]; static setab_t *cend[N_COLOR]; static semnemonic_t *mnemonics; static char *my_context; void finish_context_colors(void) { setab_t *cur, *next; semnemonic_t *ptr; unsigned i; for (i = 0; i < N_COLOR; i++) { cur = clist[i]; while(cur) { next = cur->next; free(cur->pattern); free(cur); cur = next; } clist[i] = cend[i] = NULL; } ptr = mnemonics; while (ptr) { mnemonics = ptr->next; free(ptr->name); free(ptr); ptr = mnemonics; } mnemonics = NULL; freecon(my_context); my_context = NULL; } static int check_dominance(const char *pattern, const char *raw) { char *ctx; context_t con; struct av_decision avd; int rc = -1; context_t my_tmp; const char *raw_range; security_class_t context_class = string_to_security_class("context"); access_vector_t context_contains_perm = string_to_av_perm(context_class, "contains"); con = context_new(raw); if (!con) return -1; raw_range = context_range_get(con); my_tmp = context_new(my_context); if (!my_tmp) { context_free(con); return -1; } ctx = NULL; if (context_range_set(my_tmp, pattern)) goto out; ctx = strdup(context_str(my_tmp)); if (!ctx) goto out; if (context_range_set(my_tmp, raw_range)) goto out; raw = context_str(my_tmp); if (!raw) goto out; rc = security_compute_av_raw(ctx, raw, context_class, context_contains_perm, &avd); if (rc) goto out; rc = (context_contains_perm & avd.allowed) != context_contains_perm; out: free(ctx); context_free(my_tmp); context_free(con); return rc; } static const secolor_t *find_color(int idx, const char *component, const char *raw) { setab_t *ptr = clist[idx]; if (idx == COLOR_RANGE) { if (!raw) { return NULL; } } else if (!component) { return NULL; } while (ptr) { if (idx == COLOR_RANGE) { if (check_dominance(ptr->pattern, raw) == 0) return &ptr->color; } else { if (fnmatch(ptr->pattern, component, 0) == 0) return &ptr->color; } ptr = ptr->next; } return NULL; } static int add_secolor(int idx, char *pattern, uint32_t fg, uint32_t bg) { setab_t *cptr; cptr = calloc(1, sizeof(setab_t)); if (!cptr) return -1; cptr->pattern = strdup(pattern); if (!cptr->pattern) { free(cptr); return -1; } cptr->color.fg = fg & 0xffffff; cptr->color.bg = bg & 0xffffff; if (cend[idx]) { cend[idx]->next = cptr; cend[idx] = cptr; } else { clist[idx] = cptr; cend[idx] = cptr; } return 0; } static int find_mnemonic(const char *name, uint32_t *retval) { semnemonic_t *ptr; if (*name == '#') return sscanf(name, "#%x", retval) == 1 ? 0 : -1; ptr = mnemonics; while (ptr) { if (!strcmp(ptr->name, name)) { *retval = ptr->color; return 0; } ptr = ptr->next; } return -1; } static int add_mnemonic(const char *name, uint32_t color) { semnemonic_t *ptr = malloc(sizeof(semnemonic_t)); if (!ptr) return -1; ptr->color = color; ptr->name = strdup(name); if (!ptr->name) { free(ptr); return -1; } ptr->next = mnemonics; mnemonics = ptr; return 0; } /* Process line from color file. May modify the data pointed to by the buffer parameter */ static int process_color(char *buffer, int line) { char rule[10], pat[256], f[256], b[256]; uint32_t i, fg, bg; int ret; while(isspace(*buffer)) buffer++; if(buffer[0] == '#' || buffer[0] == '\0') return 0; ret = sscanf(buffer, "%8s %255s = %255s %255s", rule, pat, f, b); if (ret == 4) { if (find_mnemonic(f, &fg) == 0 && find_mnemonic(b, &bg) == 0) for (i = 0; i < N_COLOR; i++) if (!strcmp(rule, rules[i])) return add_secolor(i, pat, fg, bg); } else if (ret == 3) { if (!strcmp(rule, AUX_RULE_COLOR)) { if (sscanf(f, "#%x", &fg) == 1) return add_mnemonic(pat, fg); } } syslog(LOG_WARNING, "Line %d of secolors file is invalid.", line); return 0; } /* Read in color file. */ int init_colors(void) { FILE *cfg = NULL; size_t size = 0; char *buffer = NULL; int line = 0; getcon(&my_context); cfg = fopen(selinux_colors_path(), "r"); if (!cfg) return 1; __fsetlocking(cfg, FSETLOCKING_BYCALLER); while (getline(&buffer, &size, cfg) > 0) { if( process_color(buffer, ++line) < 0 ) break; } free(buffer); fclose(cfg); return 0; } static const unsigned precedence[N_COLOR][N_COLOR - 1] = { { COLOR_ROLE, COLOR_TYPE, COLOR_RANGE }, { COLOR_USER, COLOR_TYPE, COLOR_RANGE }, { COLOR_USER, COLOR_ROLE, COLOR_RANGE }, { COLOR_USER, COLOR_ROLE, COLOR_TYPE }, }; static const secolor_t default_color = { 0x000000, 0xffffff }; static int parse_components(context_t con, char **components) { components[COLOR_USER] = (char *)context_user_get(con); components[COLOR_ROLE] = (char *)context_role_get(con); components[COLOR_TYPE] = (char *)context_type_get(con); components[COLOR_RANGE] = (char *)context_range_get(con); return 0; } /* Look up colors. */ int raw_color(const char *raw, char **color_str) { #define CHARS_PER_COLOR 16 context_t con; uint32_t i, j, mask = 0; const secolor_t *items[N_COLOR]; char *result, *components[N_COLOR]; char buf[CHARS_PER_COLOR + 1]; size_t result_size = (N_COLOR * CHARS_PER_COLOR) + 1; int rc = -1; if (!color_str || *color_str) { return -1; } /* parse context and allocate memory */ con = context_new(raw); if (!con) return -1; if (parse_components(con, components) < 0) goto out; result = malloc(result_size); if (!result) goto out; result[0] = '\0'; /* find colors for which we have a match */ for (i = 0; i < N_COLOR; i++) { items[i] = find_color(i, components[i], raw); if (items[i]) mask |= (1 << i); } if (mask == 0) { items[0] = &default_color; mask = 1; } /* propagate colors according to the precedence rules */ for (i = 0; i < N_COLOR; i++) if (!(mask & (1 << i))) for (j = 0; j < N_COLOR - 1; j++) if (mask & (1 << precedence[i][j])) { items[i] = items[precedence[i][j]]; break; } /* print results into a big long string */ for (i = 0; i < N_COLOR; i++) { snprintf(buf, sizeof(buf), "#%06x #%06x ", items[i]->fg, items[i]->bg); strncat(result, buf, result_size-1); } *color_str = result; rc = 0; out: context_free(con); return rc; } mcstrans-3.3/src/mcstrans.c000066400000000000000000001211641413427467300160160ustar00rootroot00000000000000 /* Copyright (c) 2008-2009 Nall Design Works Copyright 2006 Trusted Computer Solutions, Inc. */ /* Exported Interface int init_translations(void); void finish_context_translations(void); int trans_context(const char *, char **); int untrans_context(const char *, char **); */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "mls_level.h" #include "mcstrans.h" #define N_BUCKETS 1453 #define OVECCOUNT (512*3) #define log_error(fmt, ...) fprintf(stderr, fmt, __VA_ARGS__) #ifdef DEBUG #define log_debug(fmt, ...) fprintf(stderr, fmt, __VA_ARGS__) #else #define log_debug(fmt, ...) do {} while (0) #endif static unsigned int maxbit=0; /* Define data structures */ typedef struct context_map { char *raw; char *trans; } context_map_t; typedef struct context_map_node { char *key; context_map_t *map; struct context_map_node *next; } context_map_node_t; typedef struct affix { char *text; struct affix *next; } affix_t; typedef struct word { char *text; ebitmap_t cat; ebitmap_t normal; ebitmap_t inverse; struct word *next; } word_t; typedef struct word_group { char *name; char *whitespace; char *join; affix_t *prefixes; affix_t *suffixes; word_t *words; pcre *prefix_regexp; pcre *word_regexp; pcre *suffix_regexp; ebitmap_t def; word_t **sword; unsigned int sword_len; struct word_group *next; } word_group_t; typedef struct base_classification { char *trans; mls_level_t *level; struct base_classification *next; } base_classification_t; typedef struct domain { char *name; context_map_node_t *raw_to_trans[N_BUCKETS]; context_map_node_t *trans_to_raw[N_BUCKETS]; base_classification_t *base_classifications; word_group_t *groups; pcre *base_classification_regexp; struct domain *next; } domain_t; static domain_t *domains; typedef struct sens_constraint { char op; char *text; unsigned int sens; ebitmap_t cat; struct sens_constraint *next; } sens_constraint_t; static sens_constraint_t *sens_constraints; typedef struct cat_constraint { char op; char *text; int nbits; ebitmap_t mask; ebitmap_t cat; struct cat_constraint *next; } cat_constraint_t; static cat_constraint_t *cat_constraints; unsigned int hash(const char *str) { unsigned int hash = 5381; int c; while ((c = *(unsigned const char *)str++)) hash = ((hash << 5) + hash) + c; return hash; } static int add_to_hashtable(context_map_node_t **table, char *key, context_map_t *map) { unsigned int bucket = hash(key) % N_BUCKETS; context_map_node_t **n; for (n = &table[bucket]; *n; n = &(*n)->next) ; *n = malloc(sizeof(context_map_node_t)); if (! *n) goto err; (*n)->key = key; (*n)->map = map; (*n)->next = NULL; return 0; err: syslog(LOG_ERR, "add_to_hashtable: allocation error"); return -1; } static int numdigits(unsigned int n) { int count = 1; while ((n = n / 10)) count++; return count; } static int parse_category(ebitmap_t *e, const char *raw, int allowinverse) { int inverse = 0; unsigned int low, high; while (*raw) { if (allowinverse && *raw == '~') { inverse = !inverse; raw++; continue; } if (sscanf(raw,"c%u", &low) != 1) return -1; raw += numdigits(low) + 1; if (*raw == '.') { raw++; if (sscanf(raw,"c%u", &high) != 1) return -1; raw += numdigits(high) + 1; } else { high = low; } while (low <= high) { if (low >= maxbit) maxbit = low + 1; if (ebitmap_set_bit(e, low, inverse ? 0 : 1) < 0) return -1; low++; } if (*raw == ',') { raw++; inverse = 0; } else if (*raw != '\0') { return -1; } } return 0; } int parse_ebitmap(ebitmap_t *e, ebitmap_t *def, const char *raw) { int rc = ebitmap_cpy(e, def); if (rc < 0) return rc; rc = parse_category(e, raw, 1); if (rc < 0) return rc; return 0; } mls_level_t * parse_raw(const char *raw) { mls_level_t *mls = calloc(1, sizeof(mls_level_t)); if (!mls) goto err; if (sscanf(raw,"s%u", &mls->sens) != 1) goto err; raw += numdigits(mls->sens) + 1; if (*raw == ':') { raw++; if (parse_category(&mls->cat, raw, 0) < 0) goto err; } else if (*raw != '\0') { goto err; } return mls; err: ebitmap_destroy(&mls->cat); free(mls); return NULL; } void destroy_word(word_t **list, word_t *word) { if (!word) { return; } for (; list && *list; list = &(*list)->next) { if (*list == word) { *list = word->next; break; } } free(word->text); ebitmap_destroy(&word->cat); ebitmap_destroy(&word->normal); ebitmap_destroy(&word->inverse); memset(word, 0, sizeof(word_t)); free(word); } word_t * create_word(word_t **list, const char *text) { word_t *w = calloc(1, sizeof(word_t)); if (!w) { goto err; } w->text = strdup(text); if (!w->text) { goto err; } if (list) { for (; *list; list = &(*list)->next) ; *list = w; } return w; err: log_error("create_word: allocation error %s", strerror(errno)); destroy_word(NULL, w); return NULL; } void destroy_group(word_group_t **list, word_group_t *group) { for (; list && *list; list = &(*list)->next) { if (*list == group) { *list = group->next; break; } } while(group->prefixes) { affix_t *next = group->prefixes->next; free(group->prefixes->text); free(group->prefixes); group->prefixes=next; } while(group->suffixes) { affix_t *next = group->suffixes->next; free(group->suffixes->text); free(group->suffixes); group->suffixes=next; } while(group->words) destroy_word(&group->words, group->words); free(group->whitespace); free(group->name); free(group->sword); free(group->join); pcre_free(group->prefix_regexp); pcre_free(group->word_regexp); pcre_free(group->suffix_regexp); ebitmap_destroy(&group->def); free(group); } word_group_t * create_group(word_group_t **list, const char *name) { word_group_t *group = calloc(1, sizeof(word_group_t)); if (!group) return NULL; group->name = strdup(name); if (!group->name) { goto err; } group->join = strdup(" "); if (!group->join) { goto err; } group->whitespace = strdup(" "); if (!group->whitespace) { goto err; } group->sword = NULL; if (list) { for (; *list; list = &(*list)->next) ; *list = group; } return group; err: log_error("allocation error %s", strerror(errno)); destroy_group(NULL, group); return NULL; } void destroy_domain(domain_t *domain) { int i; unsigned int rt = 0, tr = 0; for (i=0; i < N_BUCKETS; i++) { context_map_node_t *ptr; for (ptr = domain->trans_to_raw[i]; ptr;) { context_map_node_t *t = ptr->next; free(ptr); ptr = t; tr++; } domain->trans_to_raw[i] = NULL; } for (i=0; i < N_BUCKETS; i++) { context_map_node_t *ptr; for (ptr = domain->raw_to_trans[i]; ptr;) { context_map_node_t *t = ptr->next; free(ptr->map->raw); free(ptr->map->trans); free(ptr->map); free(ptr); ptr = t; rt++; } domain->raw_to_trans[i] = NULL; } while (domain->base_classifications) { base_classification_t *next = domain->base_classifications->next; free(domain->base_classifications->trans); ebitmap_destroy(&domain->base_classifications->level->cat); free(domain->base_classifications->level); free(domain->base_classifications); domain->base_classifications = next; } pcre_free(domain->base_classification_regexp); while (domain->groups) destroy_group(&domain->groups, domain->groups); free(domain->name); free(domain); syslog(LOG_INFO, "cache sizes: tr = %u, rt = %u", tr, rt); } domain_t * create_domain(const char *name) { domain_t *domain = calloc(1, sizeof(domain_t)); if (!domain) { goto err; } domain->name = strdup(name); if (!domain->name) { goto err; } domain_t **d = &domains; for (; *d; d = &(*d)->next) ; *d = domain; return domain; err: log_error("allocation error %s", strerror(errno)); destroy_domain(domain); return NULL; } int add_word(word_group_t *group, char *raw, char *trans) { if (strchr(trans,'-')) { log_error("'%s'is invalid because '-' is illegal in modifiers.\n", trans); return -1; } word_t *word = create_word(&group->words, trans); int rc = parse_ebitmap(&word->cat, &group->def, raw); if (rc < 0) { log_error(" syntax error in %s\n", raw); destroy_word(&group->words, word); return -1; } if (ebitmap_andnot(&word->normal, &word->cat, &group->def, maxbit) < 0) return -1; ebitmap_t temp; if (ebitmap_xor(&temp, &word->cat, &group->def) < 0) return -1; if (ebitmap_and(&word->inverse, &temp, &group->def) < 0) return -1; ebitmap_destroy(&temp); return 0; } int add_constraint(char op, char *raw, char *tok) { log_debug("%s\n", "add_constraint"); ebitmap_t empty; ebitmap_init(&empty); if (!raw || !*raw) { syslog(LOG_ERR, "unable to parse line"); return -1; } if (*raw == 's') { sens_constraint_t *constraint = calloc(1, sizeof(sens_constraint_t)); if (!constraint) { log_error("allocation error %s", strerror(errno)); return -1; } if (sscanf(raw,"s%u", &constraint->sens) != 1) { syslog(LOG_ERR, "unable to parse level"); free(constraint); return -1; } if (parse_ebitmap(&constraint->cat, &empty, tok) < 0) { syslog(LOG_ERR, "unable to parse cat"); free(constraint); return -1; } if (asprintf(&constraint->text, "%s%c%s", raw, op, tok) < 0) { log_error("asprintf failed %s", strerror(errno)); return -1; } constraint->op = op; sens_constraint_t **p; for (p= &sens_constraints; *p; p = &(*p)->next) ; *p = constraint; return 0; } else if (*raw == 'c' ) { cat_constraint_t *constraint = calloc(1, sizeof(cat_constraint_t)); if (!constraint) { log_error("allocation error %s", strerror(errno)); return -1; } if (parse_ebitmap(&constraint->mask, &empty, raw) < 0) { syslog(LOG_ERR, "unable to parse mask"); free(constraint); return -1; } if (parse_ebitmap(&constraint->cat, &empty, tok) < 0) { syslog(LOG_ERR, "unable to parse cat"); ebitmap_destroy(&constraint->mask); free(constraint); return -1; } if (asprintf(&constraint->text, "%s%c%s", raw, op, tok) < 0) { log_error("asprintf failed %s", strerror(errno)); return -1; } constraint->nbits = ebitmap_cardinality(&constraint->cat); constraint->op = op; cat_constraint_t **p; for (p= &cat_constraints; *p; p = &(*p)->next) ; *p = constraint; return 0; } else { return -1; } return 0; } int violates_constraints(mls_level_t *l) { int nbits; sens_constraint_t *s; ebitmap_t common; for (s=sens_constraints; s; s=s->next) { if (s->sens == l->sens) { if (ebitmap_and(&common, &s->cat, &l->cat) < 0) return 1; nbits = ebitmap_cardinality(&common); ebitmap_destroy(&common); if (nbits) { char *text = mls_level_to_string(l); syslog(LOG_WARNING, "%s violates %s", text, s->text); free(text); return 1; } } } cat_constraint_t *c; for (c=cat_constraints; c; c=c->next) { if (ebitmap_and(&common, &c->mask, &l->cat) < 0) return 1; nbits = ebitmap_cardinality(&common); ebitmap_destroy(&common); if (nbits > 0) { if (ebitmap_and(&common, &c->cat, &l->cat) < 0) return 1; nbits = ebitmap_cardinality(&common); ebitmap_destroy(&common); if ((c->op == '!' && nbits) || (c->op == '>' && nbits != c->nbits)) { char *text = mls_level_to_string(l); syslog(LOG_WARNING, "%s violates %s (%d,%d)", text, c->text, nbits, c->nbits); free(text); return 1; } } } return 0; } void destroy_sens_constraint(sens_constraint_t **list, sens_constraint_t *constraint) { if (!constraint) { return; } for (; list && *list; list = &(*list)->next) { if (*list == constraint) { *list = constraint->next; break; } } ebitmap_destroy(&constraint->cat); free(constraint->text); memset(constraint, 0, sizeof(sens_constraint_t)); free(constraint); } void destroy_cat_constraint(cat_constraint_t **list, cat_constraint_t *constraint) { if (!constraint) { return; } for (; list && *list; list = &(*list)->next) { if (*list == constraint) { *list = constraint->next; break; } } ebitmap_destroy(&constraint->mask); ebitmap_destroy(&constraint->cat); free(constraint->text); memset(constraint, 0, sizeof(cat_constraint_t)); free(constraint); } static int add_base_classification(domain_t *domain, char *raw, char *trans) { mls_level_t *level = parse_raw(raw); if (level) { base_classification_t **i; base_classification_t *base_classification = calloc(1, sizeof(base_classification_t)); if (!base_classification) { log_error("allocation error %s", strerror(errno)); return -1; } base_classification->trans=strdup(trans); if (!base_classification->trans) { log_error("allocation error %s", strerror(errno)); free(base_classification); return -1; } base_classification->level=level; for (i=&domain->base_classifications; *i; i=&(*i)->next) ; *i = base_classification; return 0; } log_error(" add_base_classification error %s %s\n", raw, trans); return -1; } static int add_cache(domain_t *domain, char *raw, char *trans) { context_map_t *map = calloc(1, sizeof(context_map_t)); if (!map) goto err; map->raw = strdup(raw); if (!map->raw) { goto err; } map->trans = strdup(trans); if (!map->trans) { goto err; } log_debug(" add_cache (%s,%s)\n", raw, trans); if (add_to_hashtable(domain->raw_to_trans, map->raw, map) < 0) goto err; if (add_to_hashtable(domain->trans_to_raw, map->trans, map) < 0) goto err; return 0; err: log_error("%s: allocation error", "add_cache"); return -1; } static context_map_t * find_in_table(context_map_node_t **table, const char *key) { unsigned int bucket = hash(key) % N_BUCKETS; context_map_node_t **n; for (n = &table[bucket]; *n; n = &(*n)->next) if (!strcmp((*n)->key, key)) return (*n)->map; return NULL; } char * trim(char *str, const char *whitespace) { char *p = str + strlen(str); while (p > str && strchr(whitespace, *(p-1)) != NULL) *--p = 0; return str; } char * triml(char *str, const char *whitespace) { char *p = str; while (*p && (strchr(whitespace, *p) != NULL)) p++; return p; } int update(char **p, char *const val) { free (*p); *p = strdup(val); if (!*p) { log_error("allocation error %s", strerror(errno)); return -1; } return 0; } int append(affix_t **affixes, const char *val) { affix_t *affix = calloc(1, sizeof(affix_t)); if (!affix) { goto err; } affix->text = strdup(val); if (!affix->text) goto err; for (;*affixes; affixes = &(*affixes)->next) ; *affixes = affix; return 0; err: log_error("allocation error %s", strerror(errno)); free(affix); return -1; } static int read_translations(const char *filename); /* Process line from translation file. Remove white space and set raw do data before the "=" and tok to data after it Modifies the data pointed to by the buffer parameter */ static int process_trans(char *buffer) { static domain_t *domain; static word_group_t *group; static int base_classification; static int lineno = 0; char op='\0'; lineno++; log_debug("%d: %s", lineno, buffer); /* zap leading whitespace */ buffer = triml(buffer, "\t "); /* Ignore comments */ if (*buffer == '#') return 0; char *comment = strpbrk (buffer, "#"); if (comment) { *comment = '\0'; } /* zap trailing whitespace */ buffer = trim(buffer, "\t \r\n"); if (*buffer == 0) return 0; char *delim = strpbrk (buffer, "=!>"); if (! delim) { syslog(LOG_ERR, "invalid line (no !, = or >) %d", lineno); return -1; } op = *delim; *delim = '\0'; char *raw = buffer; char *tok = delim+1; /* remove trailing/leading whitespace from the split tokens */ trim(raw, "\t "); tok = triml(tok, "\t "); if (! *raw) { syslog(LOG_ERR, "invalid line %d", lineno); return -1; } if (! *tok) { syslog(LOG_ERR, "invalid line %d", lineno); return -1; } /* constraints have different syntax */ if (op == '!' || op == '>') { return add_constraint(op, raw, tok); } if (!strcmp(raw, "Domain")) { domain = create_domain(tok); group = NULL; return 0; } if (!domain) { domain = create_domain("Default"); if (!domain) return -1; group = NULL; } if (!group && (!strcmp(raw, "Whitespace") || !strcmp(raw, "Join") || !strcmp(raw, "Prefix") || !strcmp(raw, "Suffix") || !strcmp(raw, "Default"))) { syslog(LOG_ERR, "expected ModifierGroup declaration on line %d", lineno); return -1; } if (!strcmp(raw, "Include")) { unsigned int n; glob_t g; g.gl_offs = 0; if (glob(tok, GLOB_ERR, NULL, &g) < 0) { globfree(&g); return -1; } for (n=0; n < g.gl_pathc; n++) { if (read_translations(g.gl_pathv[n]) < 0) { globfree(&g); return -1; } } globfree(&g); } else if (!strcmp(raw, "Base")) { base_classification = 1; } else if (!strcmp(raw, "ModifierGroup")) { group = create_group(&domain->groups, tok); if (!group) return -1; base_classification = 0; } else if (!strcmp(raw, "Whitespace")) { if (update (&group->whitespace, tok) < 0) return -1; } else if (!strcmp(raw, "Join")) { if (update (&group->join, tok) < 0) return -1; } else if (!strcmp(raw, "Prefix")) { if (append (&group->prefixes, tok) < 0) return -1; } else if (!strcmp(raw, "Suffix")) { if (append (&group->suffixes, tok) < 0) return -1; } else if (!strcmp(raw, "Default")) { ebitmap_t empty; ebitmap_init(&empty); if (parse_ebitmap(&group->def, &empty, tok) < 0) { syslog(LOG_ERR, "unable to parse Default %d", lineno); return -1; } } else if (group) { if (add_word(group, raw, tok) < 0) { syslog(LOG_ERR, "unable to add base_classification on line %d", lineno); return -1; } } else { if (base_classification) { if (add_base_classification(domain, raw, tok) < 0) { syslog(LOG_ERR, "unable to add base_classification on line %d", lineno); return -1; } } if (add_cache(domain, raw, tok) < 0) return -1; } return 0; } int read_translations(const char *filename) { size_t size = 0; char *buffer = NULL; int rval = 0; FILE *cfg = fopen(filename,"r"); if (!cfg) { syslog(LOG_ERR, "%s file open failed", filename); return -1; } __fsetlocking(cfg, FSETLOCKING_BYCALLER); while (getline(&buffer, &size, cfg) > 0) { if( process_trans(buffer) < 0 ) { syslog(LOG_ERR, "%s file read failed", filename); rval = -1; break; } } free(buffer); fclose(cfg); return rval; } int init_translations(void) { if (is_selinux_mls_enabled() <= 0) return -1; return(read_translations(selinux_translations_path())); } char * extract_range(const char *incon) { context_t con = context_new(incon); if (!con) { syslog(LOG_ERR, "extract_range context_new(%s) failed: %s", incon, strerror(errno)); return NULL; } const char *range = context_range_get(con); if (!range) { syslog(LOG_ERR, "extract_range: context_range_get(%s) failed: %m", incon); context_free(con); return NULL; } char *r = strdup(range); if (!r) { log_error("extract_range: allocation error %s", strerror(errno)); return NULL; } context_free(con); return r; } char * new_context_str(const char *incon, const char *range) { char *rcon = NULL; context_t con = context_new(incon); if (!con) { goto exit; } context_range_set(con, range); rcon = strdup(context_str(con)); context_free(con); if (!rcon) { goto exit; } return rcon; exit: log_error("new_context_str: %s %s", incon, strerror(errno)); return NULL; } char * find_in_hashtable(const char *range, domain_t *domain, context_map_node_t **table) { char *trans = NULL; context_map_t *map = find_in_table(table, range); if (map) { trans = strdup((table == domain->raw_to_trans) ? map->trans: map->raw); if (!trans) { log_error("find_in_hashtable: allocation error %s", strerror(errno)); return NULL; } log_debug(" found %s in hashtable returning %s\n", range, trans); } return trans; } void emit_whitespace(char*buffer, char *whitespace) { strcat(buffer, "["); strcat(buffer, whitespace); strcat(buffer, "]"); } static int string_size(const void *p1, const void *p2) { return strlen(*(char **)p2) - strlen(*(char **)p1); } static int word_size(const void *p1, const void *p2) { word_t *w1 = *(word_t **)p1; word_t *w2 = *(word_t **)p2; int w1_len=strlen(w1->text); int w2_len=strlen(w2->text); if (w1_len == w2_len) return strcmp(w1->text, w2->text); return (w2_len - w1_len); } void build_regexp(pcre **r, char *buffer) { const char *error; int error_offset; if (*r) pcre_free(*r); *r = pcre_compile(buffer, PCRE_CASELESS, &error, &error_offset, NULL); if (error) { log_error("pcre=%s, error=%s\n", buffer, error ? error: "none"); } buffer[0] = '\0'; } int build_regexps(domain_t *domain) { char buffer[1024 * 128]; buffer[0] = '\0'; base_classification_t *bc; word_group_t *g; affix_t *a; word_t *w; size_t n_el, i; for (n_el = 0, bc = domain->base_classifications; bc; bc = bc->next) { n_el++; } char **sortable = calloc(n_el, sizeof(char *)); if (!sortable) { log_error("allocation error %s", strerror(errno)); return -1; } for (i=0, bc = domain->base_classifications; bc; bc = bc->next) { sortable[i++] = bc->trans; } qsort(sortable, n_el, sizeof(char *), string_size); for (i = 0; i < n_el; i++) { strcat(buffer, sortable[i]); if (i < n_el) strcat(buffer,"|"); } free(sortable); log_debug(">>> %s classification regexp=%s\n", domain->name, buffer); build_regexp(&domain->base_classification_regexp, buffer); for (g = domain->groups; g; g = g->next) { if (g->prefixes) { strcat(buffer,"(?:"); for (a = g->prefixes; a; a = a->next) { strcat(buffer, a->text); if (a->next) strcat(buffer,"|"); } strcat(buffer,")"); strcat(buffer,"[ ]+"); log_debug(">>> %s %s prefix regexp=%s\n", domain->name, g->name, buffer); build_regexp(&g->prefix_regexp, buffer); } if (g->prefixes) strcat(buffer, "^"); strcat(buffer, "(?:"); g->sword_len=0; for (w = g->words; w; w = w->next) g->sword_len++; g->sword = calloc(g->sword_len, sizeof(word_t *)); if (!g->sword) { log_error("allocation error %s", strerror(errno)); return -1; } i=0; for (w = g->words; w; w = w->next) g->sword[i++]=w; qsort(g->sword, g->sword_len, sizeof(word_t *), word_size); for (i=0; i < g->sword_len; i++) { if (i) strcat(buffer,"|"); strcat(buffer,"\\b"); strcat(buffer, g->sword[i]->text); strcat(buffer,"\\b"); } if (g->whitespace) { strcat(buffer,"|["); strcat(buffer, g->whitespace); strcat(buffer, "]+"); } strcat(buffer, ")+"); if (g->suffixes) strcat(buffer, "$"); log_debug(">>> %s %s modifier regexp=%s\n", domain->name, g->name, buffer); build_regexp(&g->word_regexp, buffer); if (g->suffixes) { strcat(buffer,"[ ]+"); strcat(buffer,"(?:"); for (a = g->suffixes; a; a = a->next) { strcat(buffer, a->text); if (a->next) strcat(buffer,"|"); } strcat(buffer,")"); log_debug(">>> %s %s suffix regexp=%s\n", domain->name, g->name, buffer); build_regexp(&g->suffix_regexp, buffer); } } return 0; } char * compute_raw_from_trans(const char *level, domain_t *domain) { #ifdef DEBUG struct timeval startTime; gettimeofday(&startTime, 0); #endif int rc = 0; int ovector[OVECCOUNT]; word_group_t *g = NULL; char *work = NULL; char *r = NULL; const char * match = NULL; int work_len; mls_level_t *mraw = NULL; ebitmap_t set, clear, tmp; ebitmap_init(&set); ebitmap_init(&clear); ebitmap_init(&tmp); work = strdup(level); if (!work) { log_error("compute_raw_from_trans: allocation error %s", strerror(errno)); goto err; } work_len = strlen(work); if (!domain->base_classification_regexp) if (build_regexps(domain) < 0) goto err; if (!domain->base_classification_regexp) goto err; log_debug(" compute_raw_from_trans work = %s\n", work); rc = pcre_exec(domain->base_classification_regexp, 0, work, work_len, 0, PCRE_ANCHORED, ovector, OVECCOUNT); if (rc > 0) { match = NULL; pcre_get_substring(work, ovector, rc, 0, &match); log_debug(" compute_raw_from_trans match = %s len = %u\n", match, strlen(match)); base_classification_t *bc; for (bc = domain->base_classifications; bc; bc = bc->next) { if (!strcmp(bc->trans, match)) { log_debug(" compute_raw_from_trans base classification %s matched %s\n", level, bc->trans); mraw = malloc(sizeof(mls_level_t)); if (!mraw) { log_error("allocation error %s", strerror(errno)); goto err; } if (mls_level_cpy(mraw, bc->level) < 0) goto err; break; } } memset(work + ovector[0], '#', ovector[1] - ovector[0]); char *p=work + ovector[0] + ovector[1]; while (*p && (strchr(" ", *p) != NULL)) *p++ = '#'; pcre_free((char *)match); match = NULL; } else { log_debug(" compute_raw_from_trans no base classification matched %s\n", level); } if (mraw == NULL) { goto err; } int complete = 0; int change = 1; while(change && !complete) { change = 0; for (g = domain->groups; g && !change && !complete; g = g->next) { int prefix = 0, suffix = 0; int prefix_offset = 0, prefix_len = 0; int suffix_offset = 0, suffix_len = 0; if (g->prefix_regexp) { rc = pcre_exec(g->prefix_regexp, 0, work, work_len, 0, 0, ovector, OVECCOUNT); if (rc > 0) { prefix = 1; prefix_offset = ovector[0]; prefix_len = ovector[1] - ovector[0]; } } if (g->suffix_regexp) { rc = pcre_exec(g->suffix_regexp, 0, work, work_len, 0, 0, ovector, OVECCOUNT); if (rc > 0) { suffix = 1; suffix_offset = ovector[0]; suffix_len = ovector[1] - ovector[0]; } } /* anchors prefix ^, suffix $ */ if (((!g->prefixes && !g->suffixes) || (g->prefixes && prefix) || (g->suffixes && suffix)) && g->word_regexp) { char *s = work + prefix_offset + prefix_len; int l = (suffix_len ? suffix_offset : work_len) - prefix_len - prefix_offset; rc = pcre_exec(g->word_regexp, 0, s, l, 0, 0, ovector, OVECCOUNT); if (rc > 0) { match = NULL; pcre_get_substring(s, ovector, rc, 0, &match); trim((char *)match, g->whitespace); if (*match) { char *p = triml((char *)match, g->whitespace); while (p && *p) { int plen = strlen(p); unsigned int i; for (i = 0; i < g->sword_len; i++) { word_t *w = g->sword[i]; int wlen = strlen(w->text); if (plen >= wlen && !strncmp(w->text, p, strlen(w->text))){ if (ebitmap_andnot(&set, &w->cat, &g->def, maxbit) < 0) goto err; if (ebitmap_xor(&tmp, &w->cat, &g->def) < 0) goto err; if (ebitmap_and(&clear, &tmp, &g->def) < 0) goto err; if (ebitmap_union(&mraw->cat, &set) < 0) goto err; ebitmap_destroy(&tmp); if (ebitmap_cpy(&tmp, &mraw->cat) < 0) goto err; ebitmap_destroy(&mraw->cat); if (ebitmap_andnot(&mraw->cat, &tmp, &clear, maxbit) < 0) goto err; ebitmap_destroy(&tmp); ebitmap_destroy(&set); ebitmap_destroy(&clear); p += strlen(w->text); change++; break; } } if (i == g->sword_len) { syslog(LOG_ERR, "conversion error"); break; } p = triml(p, g->whitespace); } memset(work + prefix_offset, '#', prefix_len); memset(work + suffix_offset, '#', suffix_len); memset(s + ovector[0], '#', ovector[1] - ovector[0]); } pcre_free((void *)match); match = NULL; } } /* YYY */ complete=1; char *p = work; while(*p) { if (isalnum(*p++)) { complete=0; break; } } } } free(work); if (violates_constraints(mraw)) { complete = 0; } if (complete) r = mls_level_to_string(mraw); mls_level_destroy(mraw); free(mraw); #ifdef DEBUG struct timeval stopTime; gettimeofday(&stopTime, 0); long int ms; if (startTime.tv_usec > stopTime.tv_usec) ms = (stopTime.tv_sec - startTime.tv_sec - 1) * 1000 + (stopTime.tv_usec/1000 + 1000 - startTime.tv_usec/1000); else ms = (stopTime.tv_sec - startTime.tv_sec ) * 1000 + (stopTime.tv_usec/1000 - startTime.tv_usec/1000); log_debug(" compute_raw_from_trans in %ld ms'\n", ms); #endif return r; err: mls_level_destroy(mraw); free(mraw); free(work); pcre_free((void *)match); ebitmap_destroy(&tmp); ebitmap_destroy(&set); ebitmap_destroy(&clear); return NULL; } char * compute_trans_from_raw(const char *level, domain_t *domain) { #ifdef DEBUG struct timeval startTime; gettimeofday(&startTime, 0); #endif word_group_t *g; mls_level_t *l = NULL; char *rval = NULL; word_group_t *groups = NULL; ebitmap_t bit_diff, temp, handled, nothandled, unhandled, orig_unhandled; ebitmap_init(&bit_diff); ebitmap_init(&temp); ebitmap_init(&handled); ebitmap_init(¬handled); ebitmap_init(&unhandled); ebitmap_init(&orig_unhandled); if (!level) goto err; l = parse_raw(level); if (!l) goto err; log_debug(" compute_trans_from_raw raw = %s\n", level); /* YYY */ /* check constraints */ if (violates_constraints(l)) { syslog(LOG_ERR, "%s violates constraints", level); goto err; } int doInverse = l->sens > 0; base_classification_t *bc, *last = NULL; int done = 0; for (bc = domain->base_classifications; bc && !done; bc = bc->next) { if (l->sens == bc->level->sens) { /* skip if alias of last bc */ if (last && last->level->sens == bc->level->sens && ebitmap_cmp(&last->level->cat, &bc->level->cat) == 0) continue; /* compute bits not consumed by base classification */ if (ebitmap_xor(&unhandled, &l->cat, &bc->level->cat) < 0) goto err; if (ebitmap_cpy(&orig_unhandled, &unhandled) < 0) goto err; /* prebuild groups */ for (g = domain->groups; g; g = g->next) { word_group_t **t; for (t = &groups; *t; t = &(*t)->next) if (!strcmp(g->name, (*t)->name)) break; if (! *t) { word_group_t *wg = create_group(&groups, g->name); if (g->prefixes) if (append(&wg->prefixes, g->prefixes->text) < 0) goto err; if (g->suffixes) if (append(&wg->suffixes, g->suffixes->text) < 0) goto err; if (g->join) if (update(&wg->join, g->join) < 0) goto err; } } int loops, hamming, change=1; for (loops = 50; ebitmap_cardinality(&unhandled) && loops > 0 && change; loops--) { change = 0; hamming = 10000; if (ebitmap_xor(&handled, &unhandled, &orig_unhandled) < 0) goto err; if (ebitmap_not(¬handled, &handled, maxbit) < 0) goto err; word_group_t *currentGroup = NULL; word_t *currentWord = NULL; for (g = domain->groups; g && hamming; g = g->next) { word_t *w; for (w = g->words; w && hamming; w = w->next) { int cardinality = ebitmap_cardinality(&w->normal); /* If the word is all inverse bits and the level does not have inverse bits - skip */ if (cardinality && !doInverse) { continue; } /* if only unhandled bits are different */ if (ebitmap_or(&temp, &w->normal, &w->inverse) < 0) goto err; if (ebitmap_and(&bit_diff, &temp, ¬handled) < 0) goto err; ebitmap_destroy(&temp); // xor bit_diff handled? if (ebitmap_and(&temp, &bit_diff, &unhandled) < 0) goto err; if (ebitmap_cmp(&bit_diff, &temp)) { int h = ebitmap_hamming_distance(&bit_diff, &unhandled); if (h < hamming) { hamming = h; currentGroup = g; currentWord = w; } } ebitmap_destroy(&bit_diff); ebitmap_destroy(&temp); } } ebitmap_destroy(&handled); ebitmap_destroy(¬handled); if (currentWord) { if (ebitmap_xor(&bit_diff, ¤tWord->cat, &bc->level->cat) < 0) goto err; if (ebitmap_cpy(&temp, &unhandled) < 0) goto err; ebitmap_destroy(&unhandled); if (ebitmap_andnot(&unhandled, &temp, &bit_diff, maxbit) < 0) goto err; ebitmap_destroy(&bit_diff); ebitmap_destroy(&temp); word_group_t **t; for (t = &groups; *t; t = &(*t)->next) if (!strcmp(currentGroup->name, (*t)->name)) break; create_word(&(*t)->words, currentWord->text); change++; } } done = (ebitmap_cardinality(&unhandled) == 0); ebitmap_destroy(&unhandled); ebitmap_destroy(&orig_unhandled); if (done) { char buffer[9999]; buffer[0] = 0; strcat(buffer, bc->trans); strcat(buffer, " "); for (g=groups; g; g = g->next) { if (g->words && g->prefixes) { strcat(buffer, g->prefixes->text); strcat(buffer, " "); } word_t *w; for (w=g->words; w; w = w->next) { strcat(buffer, w->text); if (w->next) strcat(buffer, g->join); } if (g->words && g->suffixes) { strcat(buffer, " "); strcat(buffer, g->suffixes->text); } word_group_t *n = g->next; while(g->words && n) { if (n->words) { strcat(buffer, " "); break; } n = n->next; } } rval = strdup(buffer); if (!rval) { log_error("compute_trans_from_raw: allocation error %s", strerror(errno)); goto err; } } /* clean up */ while (groups) destroy_group(&groups, groups); } last = bc; } if (l) { mls_level_destroy(l); free(l); } #ifdef DEBUG struct timeval stopTime; gettimeofday(&stopTime, 0); long int ms; if (startTime.tv_usec > stopTime.tv_usec) ms = (stopTime.tv_sec - startTime.tv_sec - 1) * 1000 + (stopTime.tv_usec/1000 + 1000 - startTime.tv_usec/1000); else ms = (stopTime.tv_sec - startTime.tv_sec ) * 1000 + (stopTime.tv_usec/1000 - startTime.tv_usec/1000); log_debug(" compute_trans_from_raw in %ld ms'\n", ms); #endif return rval; err: while (groups) destroy_group(&groups, groups); mls_level_destroy(l); free(l); return NULL; } int trans_context(const char *incon, char **rcon) { char *trans = NULL; *rcon = NULL; #ifdef DEBUG struct timeval startTime; gettimeofday(&startTime, 0); #endif log_debug(" trans_context input = %s\n", incon); char *range = extract_range(incon); if (!range) return -1; domain_t *domain = domains; for (;domain; domain = domain->next) { trans = find_in_hashtable(range, domain, domain->raw_to_trans); if (trans) break; /* try split and translate */ char *lrange = NULL, *urange = NULL; char *ltrans = NULL, *utrans = NULL; char *dashp = strchr(range,'-'); if (dashp) { *dashp = 0; lrange = range; urange = dashp+1; } else { trans = compute_trans_from_raw(range, domain); if (trans) if (add_cache(domain, range, trans) < 0) { free(range); return -1; } } if (lrange && urange) { ltrans = find_in_hashtable(lrange, domain, domain->raw_to_trans); if (! ltrans) { ltrans = compute_trans_from_raw(lrange, domain); if (ltrans) { if (add_cache(domain, lrange, ltrans) < 0) { free(range); return -1; } } else { ltrans = strdup(lrange); if (! ltrans) { log_error("strdup failed %s", strerror(errno)); free(range); return -1; } } } utrans = find_in_hashtable(urange, domain, domain->raw_to_trans); if (! utrans) { utrans = compute_trans_from_raw(urange, domain); if (utrans) { if (add_cache(domain, urange, utrans) < 0) { free(ltrans); free(range); return -1; } } else { utrans = strdup(urange); if (! utrans) { log_error("strdup failed %s", strerror(errno)); free(ltrans); free(range); return -1; } } } if (strcmp(ltrans, utrans) == 0) { if (asprintf(&trans, "%s", ltrans) < 0) { log_error("asprintf failed %s", strerror(errno)); free(utrans); free(ltrans); free(range); return -1; } } else { if (asprintf(&trans, "%s-%s", ltrans, utrans) < 0) { log_error("asprintf failed %s", strerror(errno)); free(utrans); free(ltrans); free(range); return -1; } } free(ltrans); free(utrans); *dashp = '-'; break; } if (dashp) *dashp = '-'; } if (trans) { *rcon = new_context_str(incon, trans); free(trans); } else { *rcon = new_context_str(incon, range); } free(range); #ifdef DEBUG struct timeval stopTime; gettimeofday(&stopTime, 0); long int ms; if (startTime.tv_usec > stopTime.tv_usec) ms = (stopTime.tv_sec - startTime.tv_sec - 1) * 1000 + (stopTime.tv_usec/1000 + 1000 - startTime.tv_usec/1000); else ms = (stopTime.tv_sec - startTime.tv_sec ) * 1000 + (stopTime.tv_usec/1000 - startTime.tv_usec/1000); log_debug(" trans_context input='%s' output='%s in %ld ms'\n", incon, *rcon, ms); #endif return 0; } int untrans_context(const char *incon, char **rcon) { char *raw = NULL; *rcon = NULL; #ifdef DEBUG struct timeval startTime; gettimeofday(&startTime, 0); #endif log_debug(" untrans_context incon = %s\n", incon); char *range = extract_range(incon); if (!range) return -1; log_debug(" untrans_context range = %s\n", range); domain_t *domain = domains; for (;domain; domain = domain->next) { raw = find_in_hashtable(range, domain, domain->trans_to_raw); if (raw) break; /* try split and translate */ char *lrange = NULL, *urange = NULL; char *lraw = NULL, *uraw = NULL; char *dashp = strchr(range,'-'); if (dashp) { *dashp = 0; lrange = range; urange = dashp+1; } else { raw = compute_raw_from_trans(range, domain); if (raw) { char *canonical = find_in_hashtable(raw, domain, domain->raw_to_trans); if (!canonical) { canonical = compute_trans_from_raw(raw, domain); if (canonical && strcmp(canonical, range)) if (add_cache(domain, raw, canonical) < 0) { free(range); return -1; } } if (canonical) free(canonical); if (add_cache(domain, raw, range) < 0) { free(range); return -1; } } else { log_debug("untrans_context unable to compute raw context %s\n", range); } } if (lrange && urange) { lraw = find_in_hashtable(lrange, domain, domain->trans_to_raw); if (! lraw) { lraw = compute_raw_from_trans(lrange, domain); if (lraw) { char *canonical = find_in_hashtable(lraw, domain, domain->raw_to_trans); if (!canonical) { canonical = compute_trans_from_raw(lraw, domain); if (canonical) if (add_cache(domain, lraw, canonical) < 0) { free(lraw); free(range); return -1; } } if (canonical) free(canonical); if (add_cache(domain, lraw, lrange) < 0) { free(lraw); free(range); return -1; } } else { lraw = strdup(lrange); if (! lraw) { log_error("strdup failed %s", strerror(errno)); free(range); return -1; } } } uraw = find_in_hashtable(urange, domain, domain->trans_to_raw); if (! uraw) { uraw = compute_raw_from_trans(urange, domain); if (uraw) { char *canonical = find_in_hashtable(uraw, domain, domain->raw_to_trans); if (!canonical) { canonical = compute_trans_from_raw(uraw, domain); if (canonical) if (add_cache(domain, uraw, canonical) < 0) { free(uraw); free(lraw); free(range); return -1; } } if (canonical) free(canonical); if (add_cache(domain, uraw, urange) < 0) { free(uraw); free(lraw); free(range); return -1; } } else { uraw = strdup(urange); if (! uraw) { log_error("strdup failed %s", strerror(errno)); free(lraw); free(range); return -1; } } } if (strcmp(lraw, uraw) == 0) { if (asprintf(&raw, "%s", lraw) < 0) { log_error("asprintf failed %s", strerror(errno)); free(uraw); free(lraw); free(range); return -1; } } else { if (asprintf(&raw, "%s-%s", lraw, uraw) < 0) { log_error("asprintf failed %s", strerror(errno)); free(uraw); free(lraw); free(range); return -1; } } free(lraw); free(uraw); *dashp = '-'; break; } if (dashp) *dashp = '-'; } if (raw) { *rcon = new_context_str(incon, raw); free(raw); } else { *rcon = new_context_str(incon, range); } free(range); #ifdef DEBUG struct timeval stopTime; gettimeofday(&stopTime, 0); long int ms; if (startTime.tv_usec > stopTime.tv_usec) ms = (stopTime.tv_sec - startTime.tv_sec - 1) * 1000 + (stopTime.tv_usec/1000 + 1000 - startTime.tv_usec/1000); else ms = (stopTime.tv_sec - startTime.tv_sec ) * 1000 + (stopTime.tv_usec/1000 - startTime.tv_usec/1000); log_debug(" untrans_context input='%s' output='%s' n %ld ms\n", incon, *rcon, ms); #endif return 0; } void finish_context_translations(void) { while(domains) { domain_t *next = domains->next; destroy_domain(domains); domains = next; } while(sens_constraints) { sens_constraint_t *next = sens_constraints->next; destroy_sens_constraint(&sens_constraints, sens_constraints); sens_constraints = next; } while(cat_constraints) { cat_constraint_t *next = cat_constraints->next; destroy_cat_constraint(&cat_constraints, cat_constraints); cat_constraints = next; } } mcstrans-3.3/src/mcstrans.h000066400000000000000000000004211413427467300160130ustar00rootroot00000000000000/* Copyright (c) 2006 Trusted Computer Solutions, Inc. */ #include extern int init_translations(void); extern void finish_context_translations(void); extern int trans_context(const char *, char **); extern int untrans_context(const char *, char **); mcstrans-3.3/src/mcstrans.init000066400000000000000000000033611413427467300165350ustar00rootroot00000000000000#!/bin/bash # # mcstransd This starts and stops mcstransd # # chkconfig: - 08 87 # description: This starts the SELinux Context Translation System Daemon # # processname: /sbin/mcstransd # pidfile: /var/run/mcstransd.pid # # Return values according to LSB for all commands but status: # 0 - success # 1 - generic or unspecified error # 2 - invalid or excess argument(s) # 3 - unimplemented feature (e.g. "reload") # 4 - insufficient privilege # 5 - program is not installed # 6 - program is not configured # 7 - program is not running PATH=/sbin:/bin:/usr/bin:/usr/sbin prog="mcstransd" lockfile=/var/lock/subsys/$prog # Source function library. . /etc/init.d/functions # Allow anyone to run status if [ "$1" = "status" ] ; then status $prog RETVAL=$? exit $RETVAL fi # Check that we are root ... so non-root users stop here test $EUID = 0 || exit 4 # If selinux is not enabled, return success test -x /usr/sbin/selinuxenabled && /usr/sbin/selinuxenabled || exit 0 RETVAL=0 start(){ test -x /sbin/mcstransd || exit 5 echo -n $"Starting $prog: " if status $prog > /dev/null; then echo -n $"$prog: already running" failure echo return 1 fi unset HOME MAIL USER USERNAME daemon $prog "$EXTRAOPTIONS" RETVAL=$? echo if test $RETVAL = 0 ; then touch $lockfile fi return $RETVAL } stop(){ echo -n $"Stopping $prog: " killproc $prog RETVAL=$? echo rm -f $lockfile return $RETVAL } restart(){ stop start } condrestart(){ [ -e $lockfile ] && restart return 0 } # See how we were called. case "$1" in start) start ;; stop) stop ;; restart|force-reload) restart ;; condrestart) condrestart ;; *) echo $"Usage: $0 {start|stop|status|restart|force-reload|condrestart}" RETVAL=3 esac exit $RETVAL mcstrans-3.3/src/mcstrans.service000066400000000000000000000005031413427467300172250ustar00rootroot00000000000000[Unit] Description=Translates SELinux MCS/MLS labels to human readable form Documentation=man:mcstransd(8) ConditionSecurity=selinux DefaultDependencies=no Before=shutdown.target sysinit.target Conflicts=shutdown.target [Service] ExecStart=/sbin/mcstransd -f RuntimeDirectory=setrans [Install] WantedBy=multi-user.target mcstrans-3.3/src/mcstransd.c000066400000000000000000000307361413427467300161660ustar00rootroot00000000000000/* Copyright (c) 2006 Trusted Computer Solutions, Inc. */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "mcstrans.h" #ifdef UNUSED #elif defined(__GNUC__) # define UNUSED(x) UNUSED_ ## x __attribute__((unused)) #elif defined(__LCLINT__) # define UNUSED(x) /*@unused@*/ x #else # define UNUSED(x) x #endif #define SETRANS_UNIX_SOCKET "/var/run/setrans/.setrans-unix" #define SETRANS_INIT 1 #define RAW_TO_TRANS_CONTEXT 2 #define TRANS_TO_RAW_CONTEXT 3 #define RAW_CONTEXT_TO_COLOR 4 #define MAX_DATA_BUF 4096 #define MAX_DESCRIPTORS 8192 #ifdef DEBUG //#define log_debug(fmt, ...) syslog(LOG_DEBUG, fmt, __VA_ARGS__) #define log_debug(fmt, ...) fprintf(stderr, fmt, __VA_ARGS__) #else #define log_debug(fmt, ...) do {} while (0) #endif extern int init_translations(void); extern void finish_context_translations(void); extern int trans_context(const char *, char **); extern int untrans_context(const char *, char **); extern int init_colors(void); extern void finish_context_colors(void); extern int raw_color(const char *, char **); #define SETRANSD_PATHNAME "/sbin/mcstransd" /* name of program (for error messages) */ #define SETRANSD_PROGNAME "mcstransd" static int sockfd = -1; /* socket we are listening on */ static volatile int restart_daemon = 0; static void cleanup_exit(int ret) __attribute__ ((noreturn)); static void cleanup_exit(int ret) { finish_context_colors(); finish_context_translations(); if (sockfd >=0) (void)unlink(SETRANS_UNIX_SOCKET); log_debug("%s\n", "cleanup_exit"); exit(ret); } static void clean_exit(void); static __attribute__((noreturn)) void clean_exit(void) { log_debug("%s\n", "clean_exit"); cleanup_exit(0); } static int send_response(int fd, uint32_t function, char *data, int32_t ret_val) { struct iovec resp_hdr[3]; uint32_t data_size; struct iovec resp_data; ssize_t count; if (!data) data = (char *)""; data_size = strlen(data) + 1; resp_hdr[0].iov_base = &function; resp_hdr[0].iov_len = sizeof(function); resp_hdr[1].iov_base = &data_size; resp_hdr[1].iov_len = sizeof(data_size); resp_hdr[2].iov_base = &ret_val; resp_hdr[2].iov_len = sizeof(ret_val); while (((count = writev(fd, resp_hdr, 3)) < 0) && (errno == EINTR)); if (count != (sizeof(function) + sizeof(data_size) + sizeof(ret_val))) { syslog(LOG_ERR, "Failed to write response header"); return -1; } resp_data.iov_base = data; resp_data.iov_len = data_size; while (((count = writev(fd, &resp_data, 1)) < 0) && (errno == EINTR)); if (count < 0 || (size_t)count != data_size) { syslog(LOG_ERR, "Failed to write response data"); return -1; } return ret_val; } static int get_peer_pid(int fd, pid_t *pid) { int ret; socklen_t size = sizeof(struct ucred); struct ucred peercred; /* get the context of the requesting process */ ret = getsockopt(fd, SOL_SOCKET, SO_PEERCRED, &peercred, &size); if (ret < 0) { syslog(LOG_ERR, "Failed to get PID of client process"); return -1; } *pid = peercred.pid; return ret; } static int process_request(int fd, uint32_t function, char *data1, char *UNUSED(data2)) { int32_t result; char *out = NULL; int ret; switch (function) { case SETRANS_INIT: result = 0; ret = send_response(fd, function, NULL, result); break; case RAW_TO_TRANS_CONTEXT: result = trans_context(data1, &out); ret = send_response(fd, function, out, result); break; case TRANS_TO_RAW_CONTEXT: result = untrans_context(data1, &out); ret = send_response(fd, function, out, result); break; case RAW_CONTEXT_TO_COLOR: result = raw_color(data1, &out); ret = send_response(fd, function, out, result); break; default: result = -1; ret = -1; break; } if (result) { pid_t pid = 0; get_peer_pid(fd, &pid); syslog(LOG_ERR, "Invalid request func=%d from=%u", function, pid); } free(out); return ret; } static int service_request(int fd) { struct iovec req_hdr[3]; uint32_t function; uint32_t data1_size; uint32_t data2_size; struct iovec req_data[2]; char *data1; char *data2; int ret; ssize_t count; req_hdr[0].iov_base = &function; req_hdr[0].iov_len = sizeof(function); req_hdr[1].iov_base = &data1_size; req_hdr[1].iov_len = sizeof(data1_size); req_hdr[2].iov_base = &data2_size; req_hdr[2].iov_len = sizeof(data2_size); while (((count = readv(fd, req_hdr, 3)) < 0) && (errno == EINTR)); if (count <= 0) { return 1; } if (count != (sizeof(function) + sizeof(data1_size) + sizeof(data2_size) )) { log_debug("Failed to read request header %d != %u\n",(int)count, (unsigned)(sizeof(function) + sizeof(data1_size) + sizeof(data2_size) )); return -1; } if (!data1_size || !data2_size || data1_size > MAX_DATA_BUF || data2_size > MAX_DATA_BUF ) { log_debug("Header invalid data1_size=%u data2_size=%u\n", data1_size, data2_size); return -1; } data1 = malloc(data1_size); if (!data1) { log_debug("Could not allocate %d bytes\n", data1_size); return -1; } data2 = malloc(data2_size); if (!data2) { free(data1); log_debug("Could not allocate %d bytes\n", data2_size); return -1; } req_data[0].iov_base = data1; req_data[0].iov_len = data1_size; req_data[1].iov_base = data2; req_data[1].iov_len = data2_size; while (((count = readv(fd, req_data, 2)) < 0) && (errno == EINTR)); if (count <= 0 || (size_t)count != (data1_size + data2_size) || data1[data1_size - 1] != '\0' || data2[data2_size - 1] != '\0') { free(data1); free(data2); log_debug("Failed to read request data (%d)\n", (int)count); return -1; } ret = process_request(fd, function, data1, data2); free(data1); free(data2); return ret; } static int add_pollfd(struct pollfd **ufds, int *nfds, int connfd) { int ii = 0; /* First see if we can find an already invalidated ufd */ for (ii = 0; ii < *nfds; ii++) { if ((*ufds)[ii].fd == -1) break; } if (ii == *nfds) { struct pollfd *tmp = (struct pollfd *)realloc(*ufds, (*nfds+1)*sizeof(struct pollfd)); if (!tmp) { syslog(LOG_ERR, "realloc failed for %d fds", *nfds+1); return -1; } *ufds = tmp; (*nfds)++; } (*ufds)[ii].fd = connfd; (*ufds)[ii].events = POLLIN|POLLPRI; (*ufds)[ii].revents = 0; return 0; } static void adj_pollfds(struct pollfd **ufds, int *nfds) { int ii, jj; jj = 0; for (ii = 0; ii < *nfds; ii++) { if ((*ufds)[ii].fd != -1) { if (jj < ii) (*ufds)[jj] = (*ufds)[ii]; jj++; } } *nfds = jj; } static int process_events(struct pollfd **ufds, int *nfds) { int ii = 0; int ret = 0; for (ii = 0; ii < *nfds; ii++) { short revents = (*ufds)[ii].revents; int connfd = (*ufds)[ii].fd; if (revents & (POLLIN | POLLPRI)) { if (connfd == sockfd) { /* Probably received a connection */ if ((connfd = accept(sockfd, NULL, NULL)) < 0) { syslog(LOG_ERR, "accept() failed: %m"); return -1; } if (add_pollfd(ufds, nfds, connfd)) { syslog(LOG_ERR, "Failed to add fd (%d) to poll list\n", connfd); return -1; } } else { ret = service_request(connfd); if (ret) { if (ret < 0) { syslog(LOG_ERR, "Servicing of request " "failed for fd (%d)\n", connfd); } /* Setup pollfd for deletion later. */ (*ufds)[ii].fd = -1; close(connfd); /* So we don't get bothered later */ revents = revents & ~(POLLHUP); } } revents = revents & ~(POLLIN | POLLPRI); } if (revents & POLLHUP) { log_debug("The connection with fd (%d) hung up\n", connfd); /* Set the pollfd up for deletion later. */ (*ufds)[ii].fd = -1; close(connfd); revents = revents & ~(POLLHUP); } if (revents) { syslog(LOG_ERR, "Unknown/error events (%x) encountered" " for fd (%d)\n", revents, connfd); /* Set the pollfd up for deletion later. */ (*ufds)[ii].fd = -1; close(connfd); } (*ufds)[ii].revents = 0; } /* Delete any invalidated ufds */ adj_pollfds(ufds, nfds); return 0; } static void process_connections(void) __attribute__ ((noreturn)); static void process_connections(void) { int ret = 0; int nfds = 1; struct pollfd *ufds = (struct pollfd *)malloc(sizeof(struct pollfd)); if (!ufds) { syslog(LOG_ERR, "Failed to allocate a pollfd"); cleanup_exit(1); } ufds[0].fd = sockfd; ufds[0].events = POLLIN|POLLPRI; ufds[0].revents = 0; while (1) { if (restart_daemon) { syslog(LOG_NOTICE, "Reload Translations"); finish_context_colors(); finish_context_translations(); if (init_translations()) { syslog(LOG_ERR, "Failed to initialize label translations"); cleanup_exit(1); } if (init_colors()) { syslog(LOG_ERR, "Failed to initialize color translations"); syslog(LOG_ERR, "No color information will be available"); } restart_daemon = 0; } ret = poll(ufds, nfds, -1); if (ret < 0) { if (errno == EINTR) { continue; } syslog(LOG_ERR, "poll() failed: %m"); cleanup_exit(1); } ret = process_events(&ufds, &nfds); if (ret) { syslog(LOG_ERR, "Error processing events"); cleanup_exit(1); } } } static void sigterm_handler(int sig) __attribute__ ((noreturn)); static void sigterm_handler(int UNUSED(sig)) { cleanup_exit(0); } static void sighup_handler(int UNUSED(sig)) { restart_daemon = 1; } static void initialize(void) { struct sigaction act; struct sockaddr_un addr; struct rlimit rl ; if (init_translations()) { syslog(LOG_ERR, "Failed to initialize label translations"); cleanup_exit(1); } if (init_colors()) { syslog(LOG_ERR, "Failed to initialize color translations"); syslog(LOG_ERR, "No color information will be available"); } /* the socket will be unlinked when the daemon terminates */ act.sa_handler = sigterm_handler; sigemptyset(&act.sa_mask); sigaddset(&act.sa_mask, SIGINT); sigaddset(&act.sa_mask, SIGQUIT); sigaddset(&act.sa_mask, SIGTERM); sigaddset(&act.sa_mask, SIGHUP); act.sa_flags = 0; sigaction(SIGINT, &act, NULL); sigaction(SIGQUIT, &act, NULL); sigaction(SIGTERM, &act, NULL); /* restart the daemon on SIGHUP */ act.sa_handler = sighup_handler; sigemptyset(&act.sa_mask); sigaddset(&act.sa_mask, SIGINT); sigaddset(&act.sa_mask, SIGQUIT); sigaddset(&act.sa_mask, SIGTERM); act.sa_flags = 0; sigaction(SIGHUP, &act, NULL); /* ignore SIGPIPE (in case a client terminates after sending request) */ act.sa_handler = SIG_IGN; sigemptyset(&act.sa_mask); act.sa_flags = 0; sigaction(SIGPIPE, &act, NULL); atexit(clean_exit); sockfd = socket(PF_UNIX, SOCK_STREAM, 0); if (sockfd < 0) { syslog(LOG_ERR, "socket() failed: %m"); cleanup_exit(1); } memset(&addr, 0, sizeof(addr)); addr.sun_family = AF_UNIX; strncpy(addr.sun_path, SETRANS_UNIX_SOCKET, sizeof(addr.sun_path) - 1); (void)unlink(SETRANS_UNIX_SOCKET); if (bind(sockfd, (struct sockaddr *)&addr, sizeof(addr)) < 0) { syslog(LOG_ERR, "bind() failed: %m"); cleanup_exit(1); } if (listen(sockfd, SOMAXCONN) < 0) { syslog(LOG_ERR, "listen() failed: %m"); cleanup_exit(1); } if (chmod(SETRANS_UNIX_SOCKET, S_IRWXU | S_IRWXG | S_IRWXO)) { syslog(LOG_ERR, "chmod() failed: %m"); cleanup_exit(1); } /* Raise the rlimit for file descriptors... */ rl.rlim_max = MAX_DESCRIPTORS; rl.rlim_cur = MAX_DESCRIPTORS; setrlimit(RLIMIT_NOFILE, &rl); } void dropprivs(void) { cap_t new_caps; new_caps = cap_init(); if (cap_set_proc(new_caps)) { syslog(LOG_ERR, "Error dropping capabilities, aborting: %s\n", strerror(errno)); cleanup_exit(-1); } cap_free(new_caps); } static void usage(char *program) { printf("%s [-f] [-h] \n", program); } int main(int argc, char *argv[]) { int opt; int do_fork = 1; while ((opt = getopt(argc, argv, "hf")) > 0) { switch (opt) { case 'f': do_fork = 0; break; case 'h': usage(argv[0]); exit(0); break; case '?': usage(argv[0]); exit(-1); } } #ifndef DEBUG /* Make sure we are root */ if (getuid() != 0) { syslog(LOG_ERR, "You must be root to run this program.\n"); return 4; } #endif openlog(SETRANSD_PROGNAME, 0, LOG_DAEMON); syslog(LOG_NOTICE, "%s starting", argv[0]); initialize(); #ifndef DEBUG dropprivs(); /* run in the background as a daemon */ if (do_fork && daemon(0, 0)) { syslog(LOG_ERR, "daemon() failed: %m"); cleanup_exit(1); } #endif syslog(LOG_NOTICE, "%s initialized", argv[0]); process_connections(); /* we should never get here */ return 1; } mcstrans-3.3/src/mls_level.c000066400000000000000000000057431413427467300161520ustar00rootroot00000000000000#include #include "mls_level.h" #include mls_level_t *mls_level_from_string(char *mls_context) { char delim; char *scontextp, *p, *lptr; mls_level_t *l; if (!mls_context) { return NULL; } l = (mls_level_t *) calloc(1, sizeof(mls_level_t)); /* Extract low sensitivity. */ scontextp = p = mls_context; while (*p && *p != ':' && *p != '-') p++; delim = *p; if (delim != 0) *p++ = 0; if (*scontextp != 's') goto err; l->sens = atoi(scontextp + 1); if (delim == ':') { /* Extract category set. */ while (1) { scontextp = p; while (*p && *p != ',' && *p != '-') p++; delim = *p; if (delim != 0) *p++ = 0; /* Separate into level if exists */ if ((lptr = strchr(scontextp, '.')) != NULL) { /* Remove '.' */ *lptr++ = 0; } if (*scontextp != 'c') goto err; int bit = atoi(scontextp + 1); if (ebitmap_set_bit(&l->cat, bit, 1)) goto err; /* If level, set all categories in level */ if (lptr) { if (*lptr != 'c') goto err; int ubit = atoi(lptr + 1); int i; for (i = bit + 1; i <= ubit; i++) { if (ebitmap_set_bit (&l->cat, i, 1)) goto err; } } if (delim != ',') break; } } return l; err: free(l); return NULL; } /* * Return the length in bytes for the MLS fields of the * security context string representation of `context'. */ unsigned int mls_compute_string_len(mls_level_t *l) { unsigned int len = 0; char temp[16]; unsigned int i, level = 0; ebitmap_node_t *cnode; if (!l) return 0; len += snprintf(temp, sizeof(temp), "s%d", l->sens); ebitmap_for_each_bit(&l->cat, cnode, i) { if (ebitmap_node_get_bit(cnode, i)) { if (level) { level++; continue; } len++; /* : or ,` */ len += snprintf(temp, sizeof(temp), "c%d", i); level++; } else { if (level > 1) len += snprintf(temp, sizeof(temp), ".c%d", i-1); level = 0; } } /* Handle case where last category is the end of level */ if (level > 1) len += snprintf(temp, sizeof(temp), ".c%d", i-1); return len; } char *mls_level_to_string(mls_level_t *l) { unsigned int wrote_sep, len = mls_compute_string_len(l); unsigned int i, level = 0; ebitmap_node_t *cnode; wrote_sep = 0; if (len == 0) return NULL; char *result = (char *)malloc(len + 1); char *p = result; p += sprintf(p, "s%d", l->sens); /* categories */ ebitmap_for_each_bit(&l->cat, cnode, i) { if (ebitmap_node_get_bit(cnode, i)) { if (level) { level++; continue; } if (!wrote_sep) { *p++ = ':'; wrote_sep = 1; } else *p++ = ','; p += sprintf(p, "c%d", i); level++; } else { if (level > 1) { if (level > 2) *p++ = '.'; else *p++ = ','; p += sprintf(p, "c%d", i-1); } level = 0; } } /* Handle case where last category is the end of level */ if (level > 1) { if (level > 2) *p++ = '.'; else *p++ = ','; p += sprintf(p, "c%d", i-1); } *(result + len) = 0; return result; } mcstrans-3.3/src/mls_level.h000066400000000000000000000003671413427467300161540ustar00rootroot00000000000000#ifndef __mls_level_h__ #define __mls_level_h__ #include unsigned int mls_compute_string_len(mls_level_t *r); mls_level_t *mls_level_from_string(char *mls_context); char *mls_level_to_string(mls_level_t *r); #endif mcstrans-3.3/utils/000077500000000000000000000000001413427467300143645ustar00rootroot00000000000000mcstrans-3.3/utils/.gitignore000066400000000000000000000000241413427467300163500ustar00rootroot00000000000000transcon untranscon mcstrans-3.3/utils/Makefile000066400000000000000000000016311413427467300160250ustar00rootroot00000000000000# Installation directories. PREFIX ?= /usr SBINDIR ?= $(PREFIX)/sbin TARGETS=transcon untranscon # If no specific libsepol.a is specified, fall back on LDFLAGS search path # Otherwise, as $(LIBSEPOLA) already appears in the dependencies, there # is no need to define a value for LDLIBS_LIBSEPOLA ifeq ($(LIBSEPOLA),) LDLIBS_LIBSEPOLA := -l:libsepol.a endif all: $(TARGETS) transcon: transcon.o ../src/mcstrans.o ../src/mls_level.o $(LIBSEPOLA) $(CC) $(LDFLAGS) -o $@ $^ -lpcre -lselinux $(LDLIBS_LIBSEPOLA) untranscon: untranscon.o ../src/mcstrans.o ../src/mls_level.o $(LIBSEPOLA) $(CC) $(LDFLAGS) -o $@ $^ -lpcre -lselinux $(LDLIBS_LIBSEPOLA) %.o: %.c $(CC) $(CFLAGS) -D_GNU_SOURCE -I../src -fPIE -c -o $@ $< install: all -mkdir -p $(DESTDIR)$(SBINDIR) install -m 755 $(TARGETS) $(DESTDIR)$(SBINDIR) test: ./mlstrans-test-runner.py ../test/*.test clean: rm -f $(TARGETS) *.o *~ \#* relabel: mcstrans-3.3/utils/callgrind-mcstransd000066400000000000000000000003171413427467300202430ustar00rootroot00000000000000#!/bin/bash service mcstrans stop cd ~root runcon -u system_u -r system_r -t setrans_t -l s15:c0.c1023 -- valgrind --tool=callgrind /usr/src/redhat/BUILD/*/src/mcstransd run_init /etc/init.d/mcstrans start mcstrans-3.3/utils/transcon.c000066400000000000000000000010611413427467300163550ustar00rootroot00000000000000#include #include #include #include #include #include #include #include "mcstrans.h" static __attribute__((__noreturn__)) void usage(const char *progname) { fprintf(stderr, "usage: %s context\n", progname); exit(1); } int main(int argc, char **argv) { char *scon; if ( argc != 2 ) usage(argv[0]); if (init_translations()==0) { if(trans_context(argv[1],&scon) == 0) { printf("%s\n", scon); freecon(scon); return 0; } } printf("Failed\n"); return -1; } mcstrans-3.3/utils/untranscon.c000066400000000000000000000010351413427467300167210ustar00rootroot00000000000000#include #include #include #include #include #include #include #include "mcstrans.h" static __attribute__((__noreturn__)) void usage(const char *progname) { fprintf(stderr, "usage: %s context\n", progname); exit(1); } int main(int argc, char **argv) { char *scon; if ( argc != 2 ) usage(argv[0]); if (init_translations()==0) { if(untrans_context(argv[1],&scon) == 0) { printf("%s\n", scon); freecon(scon); return 0; } } return -1; } mcstrans-3.3/utils/valgrind-mcstransd000066400000000000000000000004161413427467300201120ustar00rootroot00000000000000#!/bin/bash service mcstrans stop #valgrind -v --leak-check=full --show-reachable=yes ../src/mcstransd runcon -u system_u -r system_r -t setrans_t -l s15:c0.c1023 -- valgrind -v --leak-check=full --show-reachable=yes ../src/mcstransd run_init /etc/init.d/mcstrans start