Policy for gpg's dirmngr
PATCH 1/1 Policy for gpg's dirmngr
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(-)
gpg.fc +2 -0
@@ -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)
gpg.if +32 -7
@@ -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',` ######################################## ## <summary> +## Connect to gpg dirmngr socket +## </summary> +## <param name="domain"> +## <summary> +## Domain allowed access. +## </summary> +## </param> +# +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) +') + +######################################## +## <summary> ## Send messages to and from gpg ## pinentry over DBUS. ## </summary>
gpg.te +79 -0
102 lines not on this page · raw message
Signature · 1 line
2.11.0
PATCH 1/1 Policy for gpg's dirmngr
Quoted 121 lines · Luis Ressel via refpolicy
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/dirmngrshouldn'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(-)gpg.fc +2
-0@@ -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)gpg.if +32
-7@@ -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',` ######################################## ## <summary> +## Connect to gpg dirmngr socket +## </summary> +## <param name="domain"> +## <summary> +## Domain allowed access. +## </summary> +## </param> +# +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) +') + +######################################## +## <summary> ## Send messages to and from gpg ## pinentry over DBUS. ## </summary>gpg.te +2
-0@@ -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;
gpg.te optional_policy(` · line 80
Quoted 7 lines
gpg.te +4
-0@@ -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
Quoted 29 lines
gpg.te +13
-0+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) ') + +############################## +#
gpg.te optional_policy(` · line 390
Quoted 10 lines
gpg.te +10
-0+# 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
Quoted 26 lines
gpg.te +26
-0+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)
gpg.te optional_policy(` · line 426
Quoted 10 lines
gpg.te +10
-0+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)
Quoted 15 lines
gpg.te +14
-0+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) +')
Signature · 11 lines
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
PATCH 1/1 Policy for gpg's dirmngr
Quoted 179 lines · Dominick Grift
Quoted 121 lines · Luis Ressel via refpolicy
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/dirmngrshouldn'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(-)gpg.fc +2
-0@@ -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)gpg.if +32
-7@@ -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',` ######################################## ## <summary> +## Connect to gpg dirmngr socket +## </summary> +## <param name="domain"> +## <summary> +## Domain allowed access. +## </summary> +## </param> +# +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) +') + +######################################## +## <summary> ## Send messages to and from gpg ## pinentry over DBUS. ## </summary>gpg.te +2
-0@@ -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;gpg.te optional_policy(` · line 80
Quoted 7 lines
gpg.te +4
-0@@ -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
Quoted 29 lines
gpg.te +13
-0+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) ') + +############################## +#gpg.te optional_policy(` · line 390
Quoted 10 lines
gpg.te +10
-0+# 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)
Quoted 6 lines
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_ttype in the first place
This is what my ~/.gnupg looks like
drwx------. 4 kcinimod kcinimod
wheel.id:wheel.role:gpg.home_user_file:s0 4096 Dec 12 22:42 .
drwx--x---+ 32 kcinimod kcinimod wheel.id:wheel.role:home_dir.file:s0
4096 Dec 27 23:00 ..
drwx------. 2 kcinimod kcinimod
wheel.id:wheel.role:dirmngr.home_user_file:s0 4096 Jul 12 18:05 crls.d
-rw-------. 1 kcinimod kcinimod
wheel.id:wheel.role:dirmngr.home_user_file:s0 2373 Jan 6 2016
dirmngr.conf
-rw-rw-r--. 1 kcinimod kcinimod
wheel.id:wheel.role:gpg_agent.home_user_file:s0 202 Jan 7 2016
gpg-agent.conf
-rw-rw-r--. 1 kcinimod kcinimod wheel.id:wheel.role:gpg_agent.home_user_file:s0 1372398 Dec 28 15:56 gpg-agent.log
-rw-------. 1 kcinimod kcinimod
wheel.id:wheel.role:gpg.home_user_file:s0 6716 Jan 7 2016
gpg.conf
drwx------. 2 kcinimod kcinimod
wheel.id:wheel.role:gpg_agent.home_user_file:s0 4096 Jan 8 2016
private-keys-v1.d
-rw-rw-r--. 1 kcinimod kcinimod
wheel.id:wheel.role:gpg.home_user_file:s0 5180 Jan 6 2016
publickey.asc
-rw-r--r--. 1 kcinimod kcinimod
wheel.id:wheel.role:gpg.home_user_file:s0 73551 Dec 12 22:42
pubring.kbx
-rw-r--r--. 1 kcinimod kcinimod
wheel.id:wheel.role:gpg.home_user_file:s0 28973 Nov 14 11:01
pubring.kbx~
-rw-------. 1 kcinimod kcinimod
wheel.id:wheel.role:gpg.home_user_file:s0 600 Dec 14 23:13random_seed
-rw-rw-r--. 1 kcinimod kcinimod
wheel.id:wheel.role:scdaemon.home_user_file:s0 7 Dec 28 15:56
reader_0.status
-rw-rw-r--. 1 kcinimod kcinimod
wheel.id:wheel.role:scdaemon.home_user_file:s0 7 Dec 26 09:36
reader_-1.status
-rw-rw-r--. 1 kcinimod kcinimod
wheel.id:wheel.role:scdaemon.home_user_file:s0 68 Jan 7 2016
scdaemon.conf
-rw-r-----. 1 kcinimod kcinimod
wheel.id:wheel.role:gpg_agent.home_user_file:s0 676 Jan 8 2016
sshcontrol
-rw-------. 1 kcinimod kcinimod
wheel.id:wheel.role:gpg.home_user_file:s0 1320 Dec 12 22:42
trustdb.gpg
And /run/user/1000/gnupg:
drwx------. 2 kcinimod kcinimod
wheel.id:wheel.role:gpg.tmpfs_user_file:s0 100 Dec 28 15:56 .
drwx------. 10 kcinimod kcinimod sys.id:sys.role:tmpfs.fs:s0
300 Dec 28 16:13 ..
srwx------. 1 kcinimod kcinimod
wheel.id:wheel.role:gpg_agent.tmpfs_user_file:s0 0 Dec 28 15:56
S.gpg-agent
srwx------. 1 kcinimod kcinimod
wheel.id:wheel.role:gpg_agent.tmpfs_user_file:s0 0 Dec 28 15:56
S.gpg-agent.ssh
srwx------. 1 kcinimod kcinimod
wheel.id:wheel.role:scdaemon.tmpfs_user_file:s0 0 Dec 28 15:56 S.scdaemon
Quoted 58 lines
Quoted 26 lines
gpg.te +26
-0+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)gpg.te optional_policy(` · line 426
Quoted 10 lines
gpg.te +10
-0+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_resolveis already enclosed withauth_use_nsswitch()i believe (probablysysnet_use_ldapis also enclosed withauth_use_nsswitch()(not sure)Quoted 15 lines
gpg.te +14
-0+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) +')
Signature · 11 lines
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/112af7e8/attachment-0001.bin
PATCH 1/1 Policy for gpg's dirmngr
In reply to Dominick GriftQuoted 9 lines · On Wed, 28 Dec 2016 16:11:54 +0100 Dominick Grift via refpolicy…
Quoted 6 lines
gpg.te +3
-0+type gpg_dirmngr_t; +type gpg_dirmngr_exec_t; +typealias gpg_dirmngr_t alias { user_gpg_dirmngr_t
staff_gpg_dirmngr_tsysadm_gpg_dirmngr_t}; +typealiasgpg_dirmngr_talias {auditadm_gpg_dirmngr_tsecadm_gpg_dirmngr_t};You do not have to typealias because I do not believe these types exist
Good catch!
Quoted 10 lines
Quoted 6 lines
gpg.te +4
-0+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.
Quoted 6 lines
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).
You're right; I'll change this. When gnupg 2.1 has gained a wider user base, the whole gpg policy could use an overhaul; gpg_secret_t is currently a catch-all type which is also used for config files and the like. If we relabel those, we could restrict access to gpg_secret_t further; gpg itself does not need to access the private keys (all private keys operation are handled by gpg-agent).
Quoted 2 lines
Also ideally there should not be sockets with
gpg_secret_ttype in the first place
Agreed. I probably forgot to drop that when I added the filetrans for the S.dirmngr socket.
Quoted 3 lines
sysnet_dns_name_resolveis already enclosed withauth_use_nsswitch()i believe (probablysysnet_use_ldapis also enclosed withauth_use_nsswitch()(not sure)
sysnet_dns_name_resolve() is indeed redundant. sysnet_use_ldap() is required, though, as auth_use_nsswitch() only grants this when the authlogin_nsswitch_use_ldap boolean is set.
Thanks for your feedback!
Luis
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 833 bytes
Desc: OpenPGP digital signature
Url : http://oss.tresys.com/pipermail/refpolicy/attachments/20161228/e58bcf0b/attachment.bin