From: dac.override@gmail.com (Dominick Grift)
Date: Wed, 28 Dec 2016 16:11:54 +0100
Subject: [refpolicy] [PATCH] Policy for gpg's dirmngr
In-Reply-To: <20161228145816.25231-1-aranea@aixah.de>
References: <20161228145816.25231-1-aranea@aixah.de>
Message-ID: <2b2c0eda-e5a2-e95e-1c2e-cdb6bbf7232d@gmail.com>
To: refpolicy@oss.tresys.com
List-Id: refpolicy.oss.tresys.com
On 12/28/2016 03:58 PM, Luis Ressel via refpolicy wrote:
> GnuPG 2.1 uses a separate dirmngr process for retrieving keys from a
> keyserver. This dirmngr is an integral part of GnuPG 2.1 and has some
> considerable differences from the old 'dirmngr' provided as an addon
> package for GnuPG 2.0. Using the same policies for both of those daemons
> would result in an unwieldy policy with too many permissions.
>
> The fc collision for /usr/bin/dirmngr shouldn't be a problem, as GnuPG
> 2.0 and 2.1 can't be installed in parallel; and to the best of my
> knowledge, the (no longer maintained) dirmngr addon for GnuPG 2.0 isn't
> in widespread use anyway.
> ---
> gpg.fc | 2 ++
> gpg.if | 39 +++++++++++++++++++++++++++------
> gpg.te | 79 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
> 3 files changed, 113 insertions(+), 7 deletions(-)
>
> diff --git a/gpg.fc b/gpg.fc
> index 3067dae..d96b347 100644
> --- a/gpg.fc
> +++ b/gpg.fc
> @@ -1,8 +1,10 @@
> HOME_DIR/\.gnupg(/.+)? gen_context(system_u:object_r:gpg_secret_t,s0)
> HOME_DIR/\.gnupg/log-socket -s gen_context(system_u:object_r:gpg_agent_tmp_t,s0)
> +HOME_DIR/\.gnupg/S\.dirmngr -s gen_context(system_u:object_r:gpg_dirmngr_tmp_t,s0)
> HOME_DIR/\.gnupg/S\.gpg-agent.* -s gen_context(system_u:object_r:gpg_agent_tmp_t,s0)
> HOME_DIR/\.gnupg/S\.scdaemon -s gen_context(system_u:object_r:gpg_agent_tmp_t,s0)
>
> +/usr/bin/dirmngr -- gen_context(system_u:object_r:gpg_dirmngr_exec_t,s0)
> /usr/bin/gpg(2)? -- gen_context(system_u:object_r:gpg_exec_t,s0)
> /usr/bin/gpgsm -- gen_context(system_u:object_r:gpg_exec_t,s0)
> /usr/bin/gpg-agent -- gen_context(system_u:object_r:gpg_agent_exec_t,s0)
> diff --git a/gpg.if b/gpg.if
> index efffff8..7612c57 100644
> --- a/gpg.if
> +++ b/gpg.if
> @@ -17,32 +17,35 @@
> #
> interface(`gpg_role',`
> gen_require(`
> - attribute_role gpg_roles, gpg_agent_roles, gpg_helper_roles, gpg_pinentry_roles;
> + attribute_role gpg_roles, gpg_agent_roles, gpg_dirmngr_roles, gpg_helper_roles, gpg_pinentry_roles;
> type gpg_t, gpg_exec_t, gpg_agent_t;
> type gpg_agent_exec_t, gpg_agent_tmp_t, gpg_helper_t;
> type gpg_pinentry_t, gpg_pinentry_tmp_t, gpg_secret_t;
> + type gpg_dirmngr_t, gpg_dirmngr_exec_t, gpg_dirmngr_tmp_t;
> ')
>
> roleattribute $1 gpg_roles;
> roleattribute $1 gpg_agent_roles;
> + roleattribute $1 gpg_dirmngr_roles;
> roleattribute $1 gpg_helper_roles;
> roleattribute $1 gpg_pinentry_roles;
>
> domtrans_pattern($2, gpg_exec_t, gpg_t)
> domtrans_pattern($2, gpg_agent_exec_t, gpg_agent_t)
> + domtrans_pattern($2, gpg_dirmngr_exec_t, gpg_dirmngr_t)
>
> allow $2 self:process setrlimit;
> - allow $2 { gpg_t gpg_agent_t gpg_helper_t gpg_pinentry_t }:process { ptrace signal_perms };
> - ps_process_pattern($2, { gpg_t gpg_agent_t gpg_helper_t gpg_pinentry_t })
> + allow $2 { gpg_t gpg_agent_t gpg_dirmngr_t gpg_helper_t gpg_pinentry_t }:process { ptrace signal_perms };
> + ps_process_pattern($2, { gpg_t gpg_agent_t gpg_dirmngr_t gpg_helper_t gpg_pinentry_t })
>
> allow gpg_pinentry_t $2:process signull;
> allow gpg_helper_t $2:fd use;
> - allow { gpg_t gpg_agent_t gpg_helper_t gpg_pinentry_t } $2:fifo_file { read write };
> + allow { gpg_t gpg_agent_t gpg_dirmngr_t gpg_helper_t gpg_pinentry_t } $2:fifo_file { read write };
>
> - allow $2 { gpg_agent_tmp_t gpg_secret_t }:dir { manage_dir_perms relabel_dir_perms };
> - allow $2 { gpg_agent_tmp_t gpg_secret_t }:file { manage_file_perms relabel_file_perms };
> + allow $2 { gpg_agent_tmp_t gpg_dirmngr_tmp_t gpg_secret_t }:dir { manage_dir_perms relabel_dir_perms };
> + allow $2 { gpg_agent_tmp_t gpg_dirmngr_tmp_t gpg_secret_t }:file { manage_file_perms relabel_file_perms };
> allow $2 gpg_secret_t:lnk_file { manage_lnk_file_perms relabel_lnk_file_perms };
> - allow $2 { gpg_agent_tmp_t gpg_pinentry_tmp_t gpg_secret_t }:sock_file { manage_sock_file_perms relabel_sock_file_perms };
> + allow $2 { gpg_agent_tmp_t gpg_dirmngr_tmp_t gpg_pinentry_tmp_t gpg_secret_t }:sock_file { manage_sock_file_perms relabel_sock_file_perms };
> filetrans_pattern($2, gpg_secret_t, gpg_agent_tmp_t, sock_file, "log-socket")
> userdom_user_home_dir_filetrans($2, gpg_secret_t, dir, ".gnupg")
>
> @@ -216,6 +219,28 @@ interface(`gpg_stream_connect_agent',`
>
> ########################################
> ##
> +## Connect to gpg dirmngr socket
> +##
> +##
> +##
> +## Domain allowed access.
> +##
> +##
> +#
> +interface(`gpg_stream_connect_dirmngr',`
> + gen_require(`
> + type gpg_dirmngr_t, gpg_dirmngr_tmp_t;
> + type gpg_secret_t;
> + ')
> +
> + stream_connect_pattern($1, gpg_dirmngr_tmp_t, gpg_dirmngr_tmp_t, gpg_dirmngr_t)
> + allow $1 gpg_secret_t:dir search_dir_perms;
> + userdom_search_user_runtime($1)
> + userdom_search_user_home_dirs($1)
> +')
> +
> +########################################
> +##
> ## Send messages to and from gpg
> ## pinentry over DBUS.
> ##
> diff --git a/gpg.te b/gpg.te
> index 64e3c5c..5c2e526 100644
> --- a/gpg.te
> +++ b/gpg.te
> @@ -19,6 +19,8 @@ roleattribute system_r gpg_roles;
>
> attribute_role gpg_agent_roles;
>
> +attribute_role gpg_dirmngr_roles;
> +
> attribute_role gpg_helper_roles;
> roleattribute system_r gpg_helper_roles;
>
> @@ -72,6 +74,18 @@ optional_policy(`
> pulseaudio_tmpfs_content(gpg_pinentry_tmpfs_t)
> ')
>
> +type gpg_dirmngr_t;
> +type gpg_dirmngr_exec_t;
> +typealias gpg_dirmngr_t alias { user_gpg_dirmngr_t staff_gpg_dirmngr_t sysadm_gpg_dirmngr_t };
> +typealias gpg_dirmngr_t alias { auditadm_gpg_dirmngr_t secadm_gpg_dirmngr_t };
You do not have to typealias because I do not believe these types exist
> +userdom_user_application_domain(gpg_dirmngr_t, gpg_dirmngr_exec_t)
> +role gpg_dirmngr_roles types gpg_dirmngr_t;
> +
> +type gpg_dirmngr_tmp_t;
> +typealias gpg_dirmngr_tmp_t alias { user_gpg_dirmngr_tmp_t staff_gpg_dirmngr_tmp_t sysadm_gpg_dirmngr_tmp_t };
> +typealias gpg_dirmngr_tmp_t alias { auditadm_gpg_dirmngr_tmp_t secadm_gpg_dirmngr_tmp_t };
> +userdom_user_tmp_file(gpg_dirmngr_tmp_t)
> +
> ########################################
> #
> # Local policy
> @@ -94,8 +108,10 @@ manage_lnk_files_pattern(gpg_t, gpg_secret_t, gpg_secret_t)
> userdom_user_home_dir_filetrans(gpg_t, gpg_secret_t, dir)
>
> gpg_stream_connect_agent(gpg_t)
> +gpg_stream_connect_dirmngr(gpg_t)
>
> domtrans_pattern(gpg_t, gpg_agent_exec_t, gpg_agent_t)
> +domtrans_pattern(gpg_t, gpg_dirmngr_exec_t, gpg_dirmngr_t)
> domtrans_pattern(gpg_t, gpg_helper_exec_t, gpg_helper_t)
>
> kernel_read_sysctl(gpg_t)
> @@ -359,3 +375,66 @@ optional_policy(`
> optional_policy(`
> xserver_user_x_domain_template(gpg_pinentry, gpg_pinentry_t, gpg_pinentry_tmpfs_t)
> ')
> +
> +##############################
> +#
> +# Dirmngr local policy
> +#
> +
> +allow gpg_dirmngr_t self:unix_stream_socket { create_stream_socket_perms connectto };
> +
> +manage_dirs_pattern(gpg_dirmngr_t, gpg_secret_t, gpg_secret_t)
> +manage_files_pattern(gpg_dirmngr_t, gpg_secret_t, gpg_secret_t)
> +manage_lnk_files_pattern(gpg_dirmngr_t, gpg_secret_t, gpg_secret_t)
> +manage_sock_files_pattern(gpg_dirmngr_t, gpg_secret_t, gpg_secret_t)
> +
This would be something i would be trying to avoid. Especially with a
process that needs to be able to connect to the network.
I think that this is probably not needed either. AFAIK, dirmngr only
needs to maintain ~/.gnupg/crls.d (besides its socket and reading its
~/.gnupg/dirmngr.conf)
Ideally only the gpg process itself would be able to ever touch gpg
secrets (files that is).
Also ideally there should not be sockets with gpg_secret_t type in the
first place
> +manage_dirs_pattern(gpg_dirmngr_t, gpg_dirmngr_tmp_t, gpg_dirmngr_tmp_t)
> +manage_files_pattern(gpg_dirmngr_t, gpg_dirmngr_tmp_t, gpg_dirmngr_tmp_t)
> +manage_sock_files_pattern(gpg_dirmngr_t, gpg_dirmngr_tmp_t, gpg_dirmngr_tmp_t)
> +files_tmp_filetrans(gpg_dirmngr_t, gpg_dirmngr_tmp_t, { file sock_file dir })
> +
> +filetrans_pattern(gpg_dirmngr_t, gpg_secret_t, gpg_dirmngr_tmp_t, sock_file, "S.dirmngr")
> +
> +domain_use_interactive_fds(gpg_dirmngr_t)
> +
> +userdom_use_user_terminals(gpg_dirmngr_t)
> +userdom_search_user_home_dirs(gpg_dirmngr_t)
> +
> +miscfiles_read_generic_certs(gpg_dirmngr_t)
> +miscfiles_read_localization(gpg_dirmngr_t)
> +
> +auth_use_nsswitch(gpg_dirmngr_t)
> +
> +corenet_all_recvfrom_unlabeled(gpg_dirmngr_t)
> +corenet_all_recvfrom_netlabel(gpg_dirmngr_t)
> +corenet_tcp_sendrecv_generic_if(gpg_dirmngr_t)
> +corenet_tcp_sendrecv_generic_node(gpg_dirmngr_t)
> +
> +# Key retrieval via HKP and LDAP (optionally tunnelled via Tor)
> +sysnet_use_ldap(gpg_dirmngr_t)
> +corenet_tcp_connect_pgpkeyserver_port(gpg_dirmngr_t)
> +corenet_tcp_sendrecv_pgpkeyserver_port(gpg_dirmngr_t)
> +corenet_sendrecv_pgpkeyserver_client_packets(gpg_dirmngr_t)
> +corenet_tcp_connect_http_port(gpg_dirmngr_t)
> +corenet_tcp_sendrecv_http_port(gpg_dirmngr_t)
> +corenet_sendrecv_http_client_packets(gpg_dirmngr_t)
> +corenet_tcp_connect_tor_port(gpg_dirmngr_t)
> +corenet_tcp_sendrecv_tor_port(gpg_dirmngr_t)
> +corenet_sendrecv_tor_client_packets(gpg_dirmngr_t)
> +
> +# Since version 2.1.17, gnupg uses a custom DNS implementation
> +sysnet_dns_name_resolve(gpg_dirmngr_t)
sysnet_dns_name_resolve is already enclosed with auth_use_nsswitch() i
believe (probably sysnet_use_ldap is also enclosed with
auth_use_nsswitch() (not sure)
> +corenet_udp_bind_generic_node(gpg_dirmngr_t)
> +corenet_udp_bind_all_unreserved_ports(gpg_dirmngr_t)
> +
> +tunable_policy(`use_nfs_home_dirs',`
> + fs_manage_nfs_dirs(gpg_dirmngr_t)
> + fs_manage_nfs_files(gpg_dirmngr_t)
> + fs_manage_nfs_symlinks(gpg_dirmngr_t)
> +')
> +
> +tunable_policy(`use_samba_home_dirs',`
> + fs_manage_cifs_dirs(gpg_dirmngr_t)
> + fs_manage_cifs_files(gpg_dirmngr_t)
> + fs_manage_cifs_symlinks(gpg_dirmngr_t)
> +')
>
--
Key fingerprint = 5F4D 3CDB D3F8 3652 FBD8 02D5 3B6C 5F1D 2C7B 6B02
https://sks-keyservers.net/pks/lookup?op=get&search=0x3B6C5F1D2C7B6B02
Dominick Grift
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 648 bytes
Desc: OpenPGP digital signature
Url : http://oss.tresys.com/pipermail/refpolicy/attachments/20161228/39ab2d96/attachment.bin