Email: slawrence@tresys.com
Subject: Add chcon method to libselinux python bindings
Date: Mon, 7 Jun 2010 17:40:05 -0400
Adds a chcon method to the libselinux python bindings to change the
context of a file/directory tree.
Signed-off-by: Chad Sellers <csellers@tresys.com>
This patch simply removes duplicate slashes (meaning "//") from
pathnames passed into selabel_lookup. It does not do a full
realpath() calculation (e.g. following symlinks, etc.), as the
client should really do that before calling into libselinux.
Signed-off-by: Chad Sellers <csellers@tresys.com>
for the given database object identified by its name and object class.
It is necessary to implement a feature something like the restorecon on databases.
The specfile shall be described as follows:
------------------------
#
# The specfile for database objects
# (for SE-PostgreSQL)
#
# <object class> <object name> <security context>
#
db_database * system_u:object_r:sepgsql_db_t:s0
db_schema *.pg_catalog system_u:obejct_r:sepgsql_sys_schema_t:s0
db_schema *.* system_u:object_r:sepgsql_schema_t:s0
db_table *.pg_catalog.* system_u:object_r:sepgsql_sysobj_t:s0
db_table *.*.* system_u:object_r:sepgsql_table_t:s0
------------------------
- All the characters after the '#' are ignored.
- Wildcards ('*' and '?') are available.
- It returns the first match security context.
Note that hierarchy of the namespace of database objects depends on RDBMS.
So, author of the specfile needs to write correct patterns which are suitable
for the target RDBMS. The patched selabel_*() interfaces don't have any
heuristics for the namespace hierarchy to be suitable for widespread RDBMSs.
In the case of SE-PgSQL, when we lookup an expected security context for the
'my_table' table in the 'public' schema and 'postgres' database, the caller
shall provide 'postgres.public.my_table' as a key.
In the default, it tries to read a specfile which maps database objects and security
context from the /etc/selinux/$POLICYTYPE/contexts/sepgsql_contexts.
Note that when another RDBMS uses this interface, it needs to give an explicit
SELABEL_OPT_PATH option on the selabel_open().
Signed-off-by: KaiGai Kohei <kaigai@ak.jp.nec.com>
Acked-by: Eamon Walsh <ewalsh@tycho.nsa.gov>
avc_open() creates the netlink socket in nonblocking mode. If the
application later takes control of the netlink socket with
avc_netlink_acquire_fd() and then calls avc_netlink_loop(), it
will fail with EWOULDBLOCK.
To remedy this, remove the O_NONBLOCK flag from the netlink socket
at the start of avc_netlink_loop(). Also, with this fix, there is
no need for avc_open() to ever create a blocking socket, so change
that and update the man page.
-v2: use poll() in avc_netlink_check_nb(). This makes both
avc_netlink_loop() and avc_netlink_check_nb() independent of the
O_NONBLOCK flag.
-v3: move poll() to avc_receive() internal function; patch by
KaiGai Kohei <kaigai@kaigai.gr.jp>
Signed-off-by: Eamon Walsh <ewalsh@tycho.nsa.gov>
On 02/24/2010 02:24 PM, Daniel J Walsh wrote:
>
Ignore the first patch it was missing pc.in files.
Acked-by: Eamon Walsh <ewalsh@tycho.nsa.gov>
Signed-off-by: Joshua Brindle <method@manicmethod.com>
Email: dwalsh@redhat.com
Subject: Fix memory leak on disabled selinux machines.
Date: Wed, 24 Feb 2010 14:15:31 -0500
I think this patch originally came from Eric Paris and was updated by
others but has not been adopted yet. Not sure why.
Always free buf on exit.
Signed-off-by: Joshua Brindle <method@manicmethod.com>
On Mon, 2010-02-15 at 14:19 -0800, Justin Mattock wrote:
> this is new:
>
>
> make[2]: Leaving directory `/home/kernel/selinux/libselinux/include'
> make -C src install
> make[2]: Entering directory `/home/kernel/selinux/libselinux/src'
> cc -Werror -Wall -W -Wundef -Wshadow -Wmissing-noreturn
> -Wmissing-format-attribute -I../include -I/usr/include -D_GNU_SOURCE
> -D_FILE_OFFSET_BITS=64 -c -o label_file.o label_file.c
> cc1: warnings being treated as errors
> label_file.c: In function 'init':
> label_file.c:434: error: implicit declaration of function 'fstat'
> label_file.c:436: error: implicit declaration of function 'S_ISREG'
> make[2]: *** [label_file.o] Error 1
> make[2]: Leaving directory `/home/kernel/selinux/libselinux/src'
> make[1]: *** [install] Error 2
> make[1]: Leaving directory `/home/kernel/selinux/libselinux'
> make: *** [install] Error 1
>
> three areas where this could of been created
> update glibc
> updated kernel
> update userspace(altohugh there was not vary many commits in the pull).
Newer glibc headers expose a failure to #include the required headers
for stat(2). Also exposes a conflict in redefining close() in that
file. Patch below should fix.
Only audit the permissions specified by the policy, excluding any
permissions specified via dontaudit or not specified via auditallow.
This only shows up when a single avc_has_perm() call is made with
multiple permissions where some of those permissions are dontaudit'd or
auditallow'd while others are not. The corresponding kernel patch has
already been applied, see:
http://git.kernel.org/?p=linux/kernel/git/jmorris/security-testing-2.6.git;a=commit;h=b6cac5a30b325e14cda425670bb3568d3cad0aa8
Signed-off-by: Stephen D. Smalley <sds@tycho.nsa.gov>
Hi folks,
The script, src/exception.sh, contains so called bashisms
(constructs not supported by POSIX, but present as bash
extensions). This means when trying to build on systems where /bin/sh
is not bash, the build fails with an error. This patch uses bash to
run exception.sh. This bug affects a significant subset of Debian and
Debian derivative machines.
manoj
Signed-off-by: Manoj Srivastava <srivasta@debian.org>
Signed-off-by: Joshua Brindle <method@manicmethod.com>
Email: guido@trentalancia.com
Subject: Contributed manual pages for libselinux
Date: Sat, 21 Nov 2009 20:51:17 +0100
Hello Eamon !
On Fri, 2009-11-20 at 21:42 -0500, Eamon Walsh wrote:
> Hi, thanks for doing this. Some quick review below.
You are welcome, I suppose it was a boring task for many...
Thanks very much for reviewing the changes. And please accept my
apologies for not placing "[PATCH]" in the subject of the original post.
I had just subscribed to the list.
I left you cc address intact here...
> There is too much in matchpathcon(3) now. It's going to need to be
> split up into different pages, perhaps the init/fini/teardown stuff in
> one page, the lookup calls in another, and the non-matchpathcon prefixed
> calls in a third page.
>
> Also, .so manpage links are needed for all the calls here.
Yes, matchpathcon is a mess. Following your guidelines, I have now
splitted the huge and messy page in several different man pages. It's
easier to consult and easier to maintain.
The first part (page) is strictly related to _init, its variant
_init_index, _fini, matchpathcon and its variant matchpathcon_index.
Nice and concise. References are provided in the "SEE ALSO" section to
the rest.
The second page describes the auxiliary lookup calls
(matchpathcon_checkmatches) and the inode associations functions
(matchpathcon_filespec_{add,destroy,eval}). The reference section points
to the main matchpathcon page.
A third page has been created for the functions that are used to set the
flags (set_matchpathcon_flags) or to configure the behaviour of the main
matchpathcon functions (set_matchpathcon_invalidcon and
set_matchpathcon_printf).
A fourth and fifth page is devoted to functions that should never had
ended up in matchpathcon (selinux_file_context_cmp and
selinux_file_context_verify in one page and selinux_lsetfilecon_default
in another one): we do not really need to save electrons needed for new
pages...
>
>
> > * print_access_vector
> >
>
> Looks good.
No modifications.
> > * security_disable
> >
>
> See the selinux.h comments for this. It needs to be documented that
> this function can only be called at startup time.
Ok. I have stressed that now and also mentioned that after the policy
has been loaded at startup, then only "setenforce" can be used to alter
(not disable) the mode of the SELinux kernel code (for example by
placing it into "permissive" mode).
> > * security_set_boolean_list
> >
>
> a RETURN VALUE section is needed in this page, documenting at least this
> call if not the others in that page.
I have now added a "RETURN VALUE" section.
Also, to avoid confusion, I have rephrased the word "returns" in
"provides" when not strictly referring the to the return value of the
function (take for example security_get_boolean_names(), strictly
speaking the function returns an integer representing 0=success or
-1=failure, although from a conceptual point of view it also returns a
list trough modification of one of its parameters passed by reference).
Usually when an application developer looks at the "RETURN VALUE"
section it is because he/she has already planned/coded the call to the
function (and thus also the handling to parameters passed by reference)
and only needs to check for the function exit status so that it can be
handled properly at the call point.
> > * selinux_check_passwd_access
> >
>
> This is a replacement for the inconsistently named "checkPasswdAccess"
> function. So, the existing description of checkPasswdAccess should be
> moved to this function, and checkPasswdAccess should be changed to "this
> is a deprecated alias for selinux_check_passwd_access".
Yes, I have now mentioned that checkPasswdAccess is deprecated. We are
referring to file security_compute_av.3 as the description of these two
functions lives there...
By the way, it has been pointed out that this function should not
hard-code a string. I also agree with him, there is a generic constant
for such "passwd" object class, it is defined in flask.h could be used
instead of the string, thus avoiding hard-coding and also allowing to
save a few cycles and be theoretically future-proof (if ever the name
would change, say to "password", "auth-token" or anything else).
libselinux/src/checkAccess.c.orig 2009-11-21 20:07:21.000000000
libselinux/src/checkAccess.c 2009-11-21 20:08:36.000000000
@@ -13,17 +13,12 @@ int selinux_check_passwd_access(access_v
if (is_selinux_enabled() == 0)
return 0;
if (getprevcon_raw(&user_context) == 0) {
- security_class_t passwd_class;
struct av_decision avd;
int retval;
- passwd_class = string_to_security_class("passwd");
- if (passwd_class == 0)
- return 0;
-
retval = security_compute_av_raw(user_context,
user_context,
- passwd_class,
+ SECCLASS_PASSWD,
requested,
&avd);
Note that the above code, should really live in the application and not
in the selinux library. It used to be like that, then for some reason it
has been introduced. Redhat's passwd and cronie are calling the library
function and thus at the moment they rely on it. But for example,
util-linux-ng has the code in it and does not call this function, as I
believe it should be. A very minor issue anyway...
> > * selinux_init_load_policy
> >
>
> A paragraph break is needed in the DESCRIPTION section before this function.
Done. I have also added a note to the already mentioned fact that after
initial policy load, SELinux cannot be anymore disabled using calls to
security_disable(3).
> > * selinux_lsetfilecon_default
> >
>
> See notes above about the matchpathcon manpage.
Yes, separate man page now.
> > * selinux_mkload_policy
> >
>
> Looks good.
No modifications.
> > * set_selinuxmnt
> >
>
> This manpage includes two static functions that are not part of the
> libselinux API (at least, not anymore) and should be removed.
>
> Also, I'm not comfortable with the description given. Instead, use the
> comments in selinux.h, which are more accurate and verbose.
>
Please let me know if things are any better now.
I did also provide on the same day a patch for beautifying and improving
the command-line option parsing of a few utilities (a ticket had been
created by somebody). That patch provides those improvement according to
GNU-style parsing of "help" and "version" options (including long-option
variants). I think it also fixes a couple of typos here and there. Feel
free to include that patch too if you like it, so that the ticket can be
closed ! I will attach it again in another separate message: it has been
slightly modified in order to apply cleanly to the latest git snapshot.
More important, I was also thinking about fingerprinting (and
subsequently checking) the libraries with some cryptographic hash
function such as the NIST-recommended SHA2. It is beginning to be done
for security-related projects like OpenSSL, so I believe it is even more
essential for SELinux. Ever thought about anything like that ?
Best regards,
Guido
Signed-off-By: Joshua Brindle <method@manicmethod.com>
Having a pkgconfig files allows the pkg-config tool to be used to
query the presence of the library (or a particular version of it),
and to obtain the C flags and linker arguments to build with it.
Based on Debian patches by Manoj Srivastava <srivasta@debian.org>.
Signed-off-by: Eamon Walsh <ewalsh@tycho.nsa.gov>
In integrating SELinux policy into rpm, we have a need to be
able to reset the configuration data (e.g. policy type) loaded
into libselinux. These values are currently loaded lazily by a
number of different functions (e.g. matchpatchcon_init()).
Since we are changing rpm to install policy, including initial
base policy, we need to be able to reload these configuration
items after the policy has been installed.
reset_selinux_config() already exists and is used by
selinux_init_load_policy() for a similar reason, but it is not
exported. This was probably intentionaly since it is not thread
safe at all. That said, rpm needs to do the same thing. This
patch makes the function public, and places a warning in the
header comment that it is not thread safe.
Signed-off-by: Chad Sellers <csellers@tresys.com>
On 09/16/2009 03:35 PM, Joshua Brindle wrote:
>
>
> Joshua Brindle wrote:
>>
>>
>> Daniel J Walsh wrote:
>>> What do you think of this one. Removed excess swig cruft,
>>>
>>> You need to run
>>>
>>> make swigify to generate those changes.
>>>
>>
>> Ok, looking at this now. I don't completely get how it works. I'm trying
>> to reproduce what you are doing by hand but nothing comes out of gcc:
>>
>> [root@localhost src]# echo '#include "../include/selinux/selinux.h"' >
>> temp.c
>> [root@localhost src]# gcc -c temp.c -aux-info temp.aux
>> [root@localhost src]# ls temp.*
>> temp.c temp.o
>>
>>
>> What is the purpose of the aux-info thing, and why doesn't it work on my
>> F11 machine?
>>
>> also, I'm not sure if the best place for selinuxswig_exception.i is
>> swigify or pywrap. In the swigify case it shouldn't be in the clean
>> target because if you check out the repo and do make clean; make pywrap
>> you'll get an error. (I can make these fixes, I'm just trying to figure
>> out how it all works first).
>>
>
> Oh, one more thing, should this be python specific? (E.g, should it be
> named selinuxswig_python_exception.i ?)
Changed name to selinux_python_exception.i
WOrks for me on F11 and F12
dwalsh@localhost$ echo '#include "../include/selinux/selinux.h"' > temp.c
dwalsh@localhost$ gcc -c temp.c -aux-info temp.aux
dwalsh@localhost$ ls temp.*
temp.aux temp.c temp.o
cat temp.aux
/* compiled from: . */
/* /usr/include/sys/select.h:109:NC */ extern int select (int, fd_set *, fd_set *, fd_set *, struct timeval *);
/* /usr/include/sys/select.h:121:NC */ extern int pselect (int, fd_set *, fd_set *, fd_set *, const struct timespec *, const __sigset_t *);
/* /usr/include/sys/sysmacros.h:31:NC */ extern unsigned int gnu_dev_major (long long unsigned int);
/* /usr/include/sys/sysmacros.h:34:NC */ extern unsigned int gnu_dev_minor (long long unsigned int);
/* /usr/include/sys/sysmacros.h:37:NC */ extern long long unsigned int gnu_dev_makedev (unsigned int, unsigned int);
/* ../include/selinux/selinux.h:12:NC */ extern int is_selinux_enabled (void);
/* ../include/selinux/selinux.h:14:NC */ extern int is_selinux_mls_enabled (void);
/* ../include/selinux/selinux.h:19:NC */ extern void freecon (security_context_t);
/* ../include/selinux/selinux.h:22:NC */ extern void freeconary (security_context_t *);
...
commit 38d98bd958f42ea18c9376e624d733795665ee22
Author: Dan Walsh <dwalsh@redhat.com>
Date: Wed Sep 16 16:51:14 2009 -0400
Add exception code
the refcounting under the following justifications:
1. Managing the refcounts by calling sidput() and sidget() as
appropriate is a difficult and bug-prone task for users of the library.
2. The userspace AVC doesn't currently make use of the refcounts to
reclaim unused SID's unless avc_cleanup() is explicitly called.
3. The kernel itself no longer uses refcounting for it's own SID's.
The implication of this change is that SID's (basically malloc'ed copies
of security contexts) will persist in the AVC's SID table until the next
call to avc_destroy(). This presents the potential for increased memory
usage, but in practice I don't believe this will be an issue. ABI
compatibility is preserved: the avc_cleanup(), sidput(), and sidget()
calls are changed to no-ops.
Signed-off-by: Eamon Walsh <ewalsh@tycho.nsa.gov>
Acked-by: Stephen Smalley <sds@tycho.nsa.gov>
Revive Steve Grubb's patch for libselinux lazy init and extend it to
address not only the reading of /etc/selinux/config but also probing
for /selinux/class and reading of /selinux/mls. This should reduce the
need for dontaudit rules for programs that link with libselinux and it
should reduce unnecessary overhead.
I did not convert init_selinuxmnt over to lazy init since the functions
that use selinux_mnt are not localized, and it only requires stat'ing
of /selinux in the common case.
I couldn't see a valid reason why we needed fini_obj_class_compat(), as
the existence of /selinux/class will only change across a reboot with
different kernel versions. fini_context_translations() already had a
comment saying that it was unnecessary as well.
Before:
$ strace ls 2> err
$ grep selinux err
open("/lib/libselinux.so.1", O_RDONLY) = 3
open("/etc/selinux/config", O_RDONLY|O_LARGEFILE) = 3
statfs64("/selinux", 84, {f_type=0xf97cff8c, f_bsize=4096, f_blocks=0, f_bfree=0, f_bavail=0, f_files=0, f_ffree=0, f_fsid={0, 0}, f_namelen=255, f_frsize=4096}) = 0
stat64("/selinux/class", {st_mode=S_IFDIR|0555, st_size=0, ...}) = 0
open("/selinux/mls", O_RDONLY|O_LARGEFILE) = 3
After:
$ strace ls 2> err
$ grep selinux err
open("/lib/libselinux.so.1", O_RDONLY) = 3
statfs64("/selinux", 84, {f_type=0xf97cff8c, f_bsize=4096, f_blocks=0, f_bfree=0, f_bavail=0, f_files=0, f_ffree=0, f_fsid={0, 0}, f_namelen=255, f_frsize=4096}) = 0
Original-patch-by: Steve Grubb <linux_4ever@yahoo.com>
Signed-off-by: Stephen Smalley <sds@tycho.nsa.gov>
Email: dwalsh@redhat.com
Subject: This patch add seusers support to SELinux
Date: Mon, 18 May 2009 14:20:30 -0400
The idea here is to break the seusers file up into lots of little
seusers file that can be user specific, also adds the service field to
be used by tools like pam_selinux to choose which is the correct context
to log a user in as.
Patch was added to facilitate IPA handing out SELinux content for
selection of roles at login.
Signed-off-by: Joshua Brindle <method@manicmethod.com>
On Wed, 2009-05-20 at 22:57 +0800, Dennis Wronka wrote:
> Okay, here we go:
>
> I unmounted /selinux and then got this:
> load_policy: Can't load policy: Invalid argument
>
> I attached my kernel-config and the two traces (trace1 for the "Device or
> resource busy"-error, trace2 for the "Invalid argument"-error).
Possible patch for libselinux to a) gracefully handle the situation
where selinuxfs is already mounted, b) report errors when switching to
permissive, and c) proceed with the policy load even if we cannot switch
to permissive mode as requested, as proceeding without a policy when the
kernel only supports enforcing mode is not desirable.
Signed-off-by: Joshua Brindle <method@manicmethod.com>
Al was complaining that he has selinux disabled and has 100,000+ mounts
in /proc/mounts. Every time he runs ls the thing takes 5 seconds
because the libselinux constructor runs the entirety of his /proc/mounts
looking for selinuxfs, which doesn't exist. Speed things up by first
checking for selinuxfs in /proc/filesystems, only if the fs is even
registered should we bother to run all of /proc/mounts.
Signed-off-by: Eric Paris <eparis@redhat.com>
Email: tmraz@redhat.com
Subject: Problems with freeing thread local storage in libselinux
Date: Wed, 06 May 2009 12:38:35 +0200
On Wed, 2009-05-06 at 01:32 -0500, Manoj Srivastava wrote:
> Hi folks,
>
> There have been numerous reports in Debian and derivatives of
> programs linked with libselinux intermittently getting segfaults.
> There is, for instance, the Debian report 505920[0], and Ubuntu
> reports[1], [3] and [5], and Gnome [2]. I have not been able to
> reproduce the error myself, though I have run the test cases a number
> of times.
>
> The common thread in unclutter, libavg, gst-inspect et al. is a
> segmentation fault in libselinux1, in the 'fini' destructor functions,
> referencing the thread local variables.
>
> The Ubuntu bug log reference my old patch for libselinux from
> 1.X days, where I replaced the thread local storage with regular
> variables and mutexes, and people report success with that. I suspect
> that something is corrupting the thread local storage. From the ubuntu
> report:
> --8<---------------cut here---------------start------------->8---
> Valgrind reports:
> =29183== Invalid read of size 8
> ==29183== at 0xE29B9DD: fini_context_translations (setrans_client.c:211)
> ==29183== by 0xE28F1F1: (within /lib/libselinux.so.1)
> ==29183== by 0xE29D040: (within /lib/libselinux.so.1)
> ==29183== by 0x570010F: exit (exit.c:75)
> 505920==29183== by 0x56E91CA: (below main) (libc-start.c:252)
> ==29183== Address 0x80 is not stack'd, malloc'd or (recently) free'd
> ==29183==
> ==29183== Process terminating with default action of signal 11 (SIGSEGV): dumping core
> ==29183== Access not within mapped region at address 0x80
> ==29183== at 0xE29B9DD: fini_context_translations (setrans_client.c:211)
> ==29183== by 0xE28F1F1: (within /lib/libselinux.so.1)
> ==29183== by 0xE29D040: (within /lib/libselinux.so.1)==29183== by 0x570010F: exit (exit.c:75)
> ==29183== by 0x56E91CA: (below main) (libc-start.c:252)
>
>
> (gdb) bt
> #0 0x00007f3ae812a9dd in fini_context_translations () at setrans_client.c:211
> #1 0x00007f3ae811e1f2 in __do_global_dtors_aux () from /lib/libselinux.so.1
> #2 0x00007ffff9097700 in ?? ()
> #3 0x00007f3ae812c041 in _fini () from /lib/libselinux.so.1
> #4 0x00007ffff9097700 in ?? ()
> #5 0x00007f3af0e88796 in _dl_fini () from /lib64/ld-linux-x86-64.so.2
> Backtrace stopped: previous frame inner to this frame (corrupt stack?)
> --8<---------------cut here---------------end--------------->8---
>
> There have been two sets of patches proposed for this; first one
> merely initializes the variables in the init function, and this works
> for a number of people, but at least one person has reported a second
> segfault even with the patch installed[6]
>
> The second patch below converts a thread local cache to a
> process wide cache, with mutex guards, which makes the cache slower,
> and non-thread local caches means that cache misses are more likely.
>
> I'll try and follow up with people who can reproduce the
> problems to see if either one of the patches solve their problems
> without triggering other segmentation faults, but I'd appreciate
> comments if anyone has insight into the issue.
The problem is with freeing storage referenced by TLS variables in
destructors. The destructor is called only in one of the threads and the
variables might not be even properly initialized in that thread. One
possibility is to not free the storage at all but that will leak memory
if the libselinux is loaded/unloaded multiple times in a process.
The only proper way is to use TSD (pthread_key_create,
pthread_setspecific etc.) to store the pointers to the cached contexts.
The attached patch implements this. I did not test it thoroughly though.
--
Tomas Mraz
No matter how far down the wrong road you've gone, turn back.
Turkish proverb
Signed-off-by: Chad Sellers <csellers@tresys.com>
Email: dwalsh@redhat.com
Subject: SELinux context patch
Date: Mon, 18 May 2009 14:16:12 -0400
This patch adds context files for virtual_domain and virtual_image,
these are both being used to locat the default context to be executed by
svirt.
I also included the subs patch which I submitted before. This patch
allows us to substitute prefixes to matchpathcon.
So we can say /export/home == /home
and
/web == /var/www
Author: Chad Sellers
Email: csellers@tresys.com
Flipped free()'s in original patch when strdup'd fail to proper order.
Signed-off-by: Chad Sellers <csellers@tresys.com>
Email: dwalsh@redhat.com
Subject: Patch to getdefaultcon to print just the correct match and add verbose option
Date: Wed, 04 Mar 2009 15:41:37 -0500
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1
I really want to rename this to selinuxdefaultcon, which is what we ship
in Fedora.
Also exit with proper error on failure.
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.9 (GNU/Linux)
Comment: Using GnuPG with Fedora - http://enigmail.mozdev.org
iEYEARECAAYFAkmu54AACgkQrlYvE4MpobNoZACdHgQDP2Hp/KDBpGCD7G08HjOX
p68An25Uu83SlOqjKyy9EG8ZgdIcuTCB
=L6UU
-----END PGP SIGNATURE-----
Signed-off-by: Chad Sellers <csellers@tresys.com>