This list is closed, nobody may subscribe to it.
| 2007 |
Jan
|
Feb
(10) |
Mar
(26) |
Apr
(8) |
May
(3) |
Jun
|
Jul
(26) |
Aug
(10) |
Sep
|
Oct
|
Nov
(2) |
Dec
(4) |
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 2008 |
Jan
|
Feb
(13) |
Mar
(4) |
Apr
(3) |
May
(5) |
Jun
|
Jul
(7) |
Aug
(8) |
Sep
(5) |
Oct
(16) |
Nov
|
Dec
(6) |
| 2009 |
Jan
(2) |
Feb
|
Mar
(3) |
Apr
|
May
|
Jun
(19) |
Jul
(4) |
Aug
|
Sep
(13) |
Oct
(10) |
Nov
(12) |
Dec
(2) |
| 2010 |
Jan
|
Feb
(2) |
Mar
(17) |
Apr
(28) |
May
|
Jun
(17) |
Jul
(11) |
Aug
(12) |
Sep
(2) |
Oct
|
Nov
|
Dec
(1) |
| 2011 |
Jan
|
Feb
|
Mar
(20) |
Apr
(10) |
May
(1) |
Jun
|
Jul
|
Aug
(15) |
Sep
(14) |
Oct
(2) |
Nov
|
Dec
|
| 2012 |
Jan
(1) |
Feb
(53) |
Mar
(15) |
Apr
(4) |
May
(2) |
Jun
(13) |
Jul
|
Aug
|
Sep
(12) |
Oct
|
Nov
|
Dec
(6) |
| 2013 |
Jan
(7) |
Feb
(8) |
Mar
(4) |
Apr
(5) |
May
|
Jun
|
Jul
|
Aug
(5) |
Sep
(6) |
Oct
|
Nov
(5) |
Dec
(8) |
| 2014 |
Jan
(17) |
Feb
(24) |
Mar
(8) |
Apr
(7) |
May
(18) |
Jun
(15) |
Jul
(5) |
Aug
(2) |
Sep
(49) |
Oct
(28) |
Nov
(7) |
Dec
(30) |
| 2015 |
Jan
(40) |
Feb
|
Mar
(9) |
Apr
(2) |
May
(9) |
Jun
(31) |
Jul
(33) |
Aug
(5) |
Sep
(20) |
Oct
|
Nov
(3) |
Dec
(12) |
| 2016 |
Jan
(14) |
Feb
(29) |
Mar
(10) |
Apr
(4) |
May
(4) |
Jun
|
Jul
(5) |
Aug
(19) |
Sep
(21) |
Oct
(2) |
Nov
(36) |
Dec
(30) |
| 2017 |
Jan
(101) |
Feb
(12) |
Mar
(7) |
Apr
(2) |
May
(29) |
Jun
(22) |
Jul
(7) |
Aug
(93) |
Sep
(27) |
Oct
(39) |
Nov
|
Dec
|
|
From: Dan C. <dan...@or...> - 2015-04-07 09:22:55
|
It's a bit easier to read this if we split it up into two for loops.
Signed-off-by: Dan Carpenter <dan...@or...>
diff --git a/security/integrity/ima/ima_policy.c b/security/integrity/ima/ima_policy.c
index d1eefb9..e86b58d 100644
--- a/security/integrity/ima/ima_policy.c
+++ b/security/integrity/ima/ima_policy.c
@@ -338,16 +338,12 @@ void __init ima_init_policy(void)
appraise_entries = ima_use_appraise_tcb ?
ARRAY_SIZE(default_appraise_rules) : 0;
- for (i = 0; i < measure_entries + appraise_entries; i++) {
- if (i < measure_entries)
- list_add_tail(&default_rules[i].list,
- &ima_default_rules);
- else {
- int j = i - measure_entries;
-
- list_add_tail(&default_appraise_rules[j].list,
- &ima_default_rules);
- }
+ for (i = 0; i < measure_entries; i++)
+ list_add_tail(&default_rules[i].list, &ima_default_rules);
+
+ for (i = 0; i < appraise_entries; i++) {
+ list_add_tail(&default_appraise_rules[i].list,
+ &ima_default_rules);
}
ima_rules = &ima_default_rules;
|
|
From: Mimi Z. <zo...@li...> - 2015-03-25 11:46:13
|
On Tue, 2015-03-24 at 15:35 +0200, Petko Manolov wrote: > On 15-03-23 18:47:43, Mimi Zohar wrote: > > On Mon, 2015-03-23 at 16:43 +0200, Petko Manolov wrote: > > > > > > I've gotten the above to work. The question is, does this make sense: > > > > > > local-CA ----> IMA_key_1 (signed certificate (eg. selfsigned/CA 1)) > > > | > > > |---> local-CA2 (on the .system keyring) ---> IMA_key_3 (signed cert/CA3) > > > > > > Here local-CA2 (that belongs to trusted entity) is used to sign > > > IMA_key_3 (and possibly others) which on turn IMA signs immutable > > > files. > > > > Assuming you trust all the keys on the system keyring, then any key on > > the system keyring can verify the certificate. Otherwise, use the > > "ca_keys=" boot command line option to specify the specific key. > > Another useful option, thanks. > > BTW, where can i download these (MOK related) kernel patches from? Are they public? The original patches were posted on LKML and are available from fedoraproject.org. Mimi |
|
From: Petko M. <pe...@mi...> - 2015-03-24 13:35:00
|
On 15-03-23 18:47:43, Mimi Zohar wrote: > On Mon, 2015-03-23 at 16:43 +0200, Petko Manolov wrote: > > > > I've gotten the above to work. The question is, does this make sense: > > > > local-CA ----> IMA_key_1 (signed certificate (eg. selfsigned/CA 1)) > > | > > |---> local-CA2 (on the .system keyring) ---> IMA_key_3 (signed cert/CA3) > > > > Here local-CA2 (that belongs to trusted entity) is used to sign > > IMA_key_3 (and possibly others) which on turn IMA signs immutable > > files. > > Assuming you trust all the keys on the system keyring, then any key on > the system keyring can verify the certificate. Otherwise, use the > "ca_keys=" boot command line option to specify the specific key. Another useful option, thanks. BTW, where can i download these (MOK related) kernel patches from? Are they public? Petko |
|
From: Mimi Z. <zo...@li...> - 2015-03-23 22:47:58
|
On Mon, 2015-03-23 at 16:43 +0200, Petko Manolov wrote: > On 15-03-23 07:00:13, Mimi Zohar wrote: > > Actually the diagram is a bit different than the one you showed. It > > would be: > > local-CA ----> IMA_key_1 (signed certificate (eg. selfsigned/CA 1)) > > | > > |---> IMA_key_2 (signed certificate (eg. selfsigned/CA 2)) > > I've gotten the above to work. The question is, does this make sense: > > local-CA ----> IMA_key_1 (signed certificate (eg. selfsigned/CA 1)) > | > |---> local-CA2 (on the .system keyring) ---> IMA_key_3 (signed cert/CA3) > > Here local-CA2 (that belongs to trusted entity) is used to sign > IMA_key_3 (and possibly others) which on turn IMA signs immutable > files. Assuming you trust all the keys on the system keyring, then any key on the system keyring can verify the certificate. Otherwise, use the "ca_keys=" boot command line option to specify the specific key. Mimi > > Right, once a key is signed by the local-CA and the local-CA key is > on the system keyring, use evmctl to load the key onto the .ima > keyring. > > Right. Can the .ima keyring handle CAs or just keys? If it can't then > i assume the only option is to get all CAs into the .system keyring > and use .ima for keys only. > > thanks, > Petko |
|
From: Petko M. <pe...@mi...> - 2015-03-23 14:42:49
|
On 15-03-23 07:00:13, Mimi Zohar wrote:
>
> All the keys in the top directory of the kernel build tree are added to
> the system keyring, nothing is added to the IMA keyring.
Makes sense.
> > > - KEYS: Add a system blacklist keyring
> >
> > This is, however, of interest to me. Does the kernel support CRLs or
> > "blacklist" has some different meaning here?
Can this blacklist keyring handle certificates as well?
> > > - MODSIGN: Import certificates from UEFI Secure Boot
> > > - Add EFI signature data tyeps
> > > - Add an EFI signature blob parser and key loader
> > These may come handy later on.
>
> These patches add the UEFI/MoK db keys to the system keyring. Without
> them, only the builtin keys are on the system keyring.
Is there a public repository i can checkout these patches from?
> Actually the diagram is a bit different than the one you showed. It
> would be:
> local-CA ----> IMA_key_1 (signed certificate (eg. selfsigned/CA 1))
> |
> |---> IMA_key_2 (signed certificate (eg. selfsigned/CA 2))
I've gotten the above to work. The question is, does this make sense:
local-CA ----> IMA_key_1 (signed certificate (eg. selfsigned/CA 1))
|
|---> local-CA2 (on the .system keyring) ---> IMA_key_3 (signed cert/CA3)
Here local-CA2 (that belongs to trusted entity) is used to sign IMA_key_3 (and possibly others) which on turn IMA signs immutable files.
> Right, once a key is signed by the local-CA and the local-CA key is on the system keyring, use evmctl to load the key onto the .ima keyring.
Right. Can the .ima keyring handle CAs or just keys? If it can't then i assume the only option is to get all CAs into the .system keyring and use .ima for keys only.
thanks,
Petko
|
|
From: Mimi Z. <zo...@li...> - 2015-03-23 11:09:25
|
On Sun, 2015-03-22 at 19:00 +0200, Petko Manolov wrote:
> On 15-03-20 08:45:25, Mimi Zohar wrote:
> >
> > The public CA key should be added to the system keyring, not the IMA
> > keyring. Currently the only upstreamed method for adding the public
> CA
> > key to the system keyring is by putting the public CA key, suffixed
> > with .x509, in the kernel's root directory and rebuilding the
> kernel.
> > Fedora has a couple of patches, which have not been upstreamed, that
> add
> > the UEFI/Machine Owner Key(MoK) database keys to the system keyring.
> > Listed below are the main patches, but might introduce some
> dependencies
> > depending on kernel version.
>
> If i read the above correctly the root CA public key must be present
> in the
> kernel's source root at build time.
No, the local-CA public key needs to be loaded on the system keyring,
not just any root CA public key.
> If this is the only restriction i'd rather avoid applying external
> patches to
> the kernel. BTW, is there a way to put various x509 suffixed keys into
> different keyrings when rebuilding the kernel? IOW some of them to go
> to .ima some to .system keyrings?
All the keys in the top directory of the kernel build tree are added to
the system keyring, nothing is added to the IMA keyring.
To view the system keyring, install a recent version of keyutils.
"keyctl show %keyring:.system_keyring"
> > - KEYS: Add a system blacklist keyring
>
> This is, however, of interest to me. Does the kernel support CRLs or
> "blacklist" has some different meaning here?
> > - MODSIGN: Import certificates from UEFI Secure Boot
> > - Add EFI signature data tyeps
> > - Add an EFI signature blob parser and key loader
> These may come handy later on.
These patches add the UEFI/MoK db keys to the system keyring. Without
them, only the builtin keys are on the system keyring.
> > > However, i would need to have CA hierarchy and i wonder whether
> the
> > > current Linux kernel supports it. IOW i need a root certificate to
> > > sign other certificate(s) that on turn will sign IMA keys.
> > > Is it possible to build something like:
> > >
> > >
> > > root CA ------> local CA 1 ------> IMA_key_1
> > > |
> > > +---> local CA 2 ------> IMA_key_2
> > >
> > > So stuff signed by IMA_key_1 and 2 would properly pass the
> appraisal
> > > tests?
> > >
> > >
> > > thanks a bunch,
> >
> > Yes, definitely! Either build the local CA's key into the kernel or
> > import the CA's public key into the MoK db (eg. using mokutil). Use
> > your public CA key to sign the other certificates containing the
> keys to
> > be loaded onto the IMA keyring.
Actually the diagram is a bit different than the one you showed. It
would be:
local-CA ----> IMA_key_1 (signed certificate (eg. selfsigned/CA 1))
|
|---> IMA_key_2 (signed certificate (eg. selfsigned/CA 2))
> Great, looks like we're all set. However, i thought keyctl/evmctl may
> also import certificates to the IMA keyring?
Right, once a key is signed by the local-CA and the local-CA key is on
the system keyring, use evmctl to load the key onto the .ima keyring.
Mimi
> > Most of the online documentation for signing certificates requires
> > creating a Certificate Signing Request(CSR), which requires the
> private
> > key. There is an OpenSSL option "--ss_cert" that allows signing the
> > certificates directly without access to the private key.
>
> Ah, the pleasure of dealing with openssl's command line parameters. :)
|
|
From: Petko M. <pe...@mi...> - 2015-03-22 17:00:33
|
On 15-03-20 08:45:25, Mimi Zohar wrote: > > The public CA key should be added to the system keyring, not the IMA > keyring. Currently the only upstreamed method for adding the public CA > key to the system keyring is by putting the public CA key, suffixed > with .x509, in the kernel's root directory and rebuilding the kernel. > Fedora has a couple of patches, which have not been upstreamed, that add > the UEFI/Machine Owner Key(MoK) database keys to the system keyring. > Listed below are the main patches, but might introduce some dependencies > depending on kernel version. If i read the above correctly the root CA public key must be present in the kernel's source root at build time. If this is the only restriction i'd rather avoid applying external patches to the kernel. BTW, is there a way to put various x509 suffixed keys into different keyrings when rebuilding the kernel? IOW some of them to go to .ima some to .system keyrings? > - KEYS: Add a system blacklist keyring This is, however, of interest to me. Does the kernel support CRLs or "blacklist" has some different meaning here? > - MODSIGN: Import certificates from UEFI Secure Boot > - Add EFI signature data tyeps > - Add an EFI signature blob parser and key loader These may come handy later on. > > However, i would need to have CA hierarchy and i wonder whether the > > current Linux kernel supports it. IOW i need a root certificate to > > sign other certificate(s) that on turn will sign IMA keys. > > Is it possible to build something like: > > > > > > root CA ------> local CA 1 ------> IMA_key_1 > > | > > +---> local CA 2 ------> IMA_key_2 > > > > So stuff signed by IMA_key_1 and 2 would properly pass the appraisal > > tests? > > > > > > thanks a bunch, > > Yes, definitely! Either build the local CA's key into the kernel or > import the CA's public key into the MoK db (eg. using mokutil). Use > your public CA key to sign the other certificates containing the keys to > be loaded onto the IMA keyring. Great, looks like we're all set. However, i thought keyctl/evmctl may also import certificates to the IMA keyring? > Most of the online documentation for signing certificates requires > creating a Certificate Signing Request(CSR), which requires the private > key. There is an OpenSSL option "--ss_cert" that allows signing the > certificates directly without access to the private key. Ah, the pleasure of dealing with openssl's command line parameters. :) Thank you very much, Petko |
|
From: Mimi Z. <zo...@li...> - 2015-03-20 12:51:12
|
On Fri, 2015-03-20 at 08:45 -0400, Mimi Zohar wrote:
>
> Yes, definitely! Either build the local CA's key into the kernel or
> import the CA's public key into the MoK db (eg. using mokutil). Use
> your public CA key to sign the other certificates containing the keys to
^^^^^^
> be loaded onto the IMA keyring.
That should have been: "Use the private CA key".
Mimi
|
|
From: Mimi Z. <zo...@li...> - 2015-03-20 12:46:29
|
On Fri, 2015-03-20 at 12:17 +0200, Petko Manolov wrote: > Hello guys, > > I am playing with local generated CA that sign public IMA keys. This > CA is in the trusted (.ima) keyring and stuff signed by public keys > (that are themselves properly signed) seem to work fine. The public CA key should be added to the system keyring, not the IMA keyring. Currently the only upstreamed method for adding the public CA key to the system keyring is by putting the public CA key, suffixed with .x509, in the kernel's root directory and rebuilding the kernel. Fedora has a couple of patches, which have not been upstreamed, that add the UEFI/Machine Owner Key(MoK) database keys to the system keyring. Listed below are the main patches, but might introduce some dependencies depending on kernel version. - KEYS: Add a system blacklist keyring - MODSIGN: Import certificates from UEFI Secure Boot - Add EFI signature data tyeps - Add an EFI signature blob parser and key loader > However, i would need to have CA hierarchy and i wonder whether the > current Linux kernel supports it. IOW i need a root certificate to > sign other certificate(s) that on turn will sign IMA keys. > Is it possible to build something like: > > > root CA ------> local CA 1 ------> IMA_key_1 > | > +---> local CA 2 ------> IMA_key_2 > > So stuff signed by IMA_key_1 and 2 would properly pass the appraisal > tests? > > > thanks a bunch, Yes, definitely! Either build the local CA's key into the kernel or import the CA's public key into the MoK db (eg. using mokutil). Use your public CA key to sign the other certificates containing the keys to be loaded onto the IMA keyring. Most of the online documentation for signing certificates requires creating a Certificate Signing Request(CSR), which requires the private key. There is an OpenSSL option "--ss_cert" that allows signing the certificates directly without access to the private key. Good luck! Mimi |
|
From: Petko M. <pe...@mi...> - 2015-03-20 11:00:17
|
Hello guys,
I am playing with local generated CA that sign public IMA keys. This CA is in the trusted (.ima) keyring and stuff signed by public keys (that are themselves properly signed) seem to work
fine.
However, i would need to have CA hierarchy and i wonder whether the current Linux kernel supports it. IOW i need a root certificate to sign other certificate(s) that on turn will sign IMA keys.
Is it possible to build something like:
root CA ------> local CA 1 ------> IMA_key_1
|
+---> local CA 2 ------> IMA_key_2
So stuff signed by IMA_key_1 and 2 would properly pass the appraisal tests?
thanks a bunch,
Petko
|
|
From: Paul B. <pe...@ti...> - 2015-01-30 08:37:52
|
Your commit dabd39cc2fb1 ("KEYS: Make /proc/keys unconditional if
CONFIG_KEYS=y") is included in today's linux-next (ie, next-20150130). I
noticed because a script I use to check linux-next spotted a minor
problem with it.
That commit removed the Kconfig symbol KEYS_DEBUG_PROC_KEYS. But it did
not remove a select for that symbol (see the entry for config
IMA_TRUSTED_KEYRING in security/integrity/ima/Kconfig). That select is
now a nop in linux-next. The commit suggests the trivial cleanup needed
here is to just remove that select. Is a patch to do that queued
somewhere?
Paul Bolle
|
|
From: Mimi Z. <zo...@li...> - 2015-01-28 03:40:59
|
On Tue, 2015-01-27 at 12:56 -0700, Curtis Veit wrote: > I have really appreciated help received on the user list. > I've now been about to get my appraisal functionality working well for > executables. (currently evm breaks it but I am putting that to the back burner) > > Most of the questions below may be able to be dealt with using LSM labels, > Is there a good reference somewhere to using LSM labels? > I currently have apparmor enabled and it does not appear to do much with labels. > Should I do something like adding Smack labels and use those or roll my own? Right, Apparmor does not label the file system using extended attributes (xattrs), like SElinux or Smack. Without LSM stacking, only one LSM can be active on a system per boot. > Any recommendations would be very welcome. > If there are no comments about the following I will assume that the > correct approach is to use LSM labels. Although there are actually > a couple items where clarification would be nice. > > I do have a few questions that affect the way the I will implement measurement > policy. Most important perhaps is wondering how policy rules that apply to a > subset of files work when there is also a rule that affects a superset? > A specific example is that I am signing and appraising all executables. > I would like to measure or appraise all config files using a hash. As there > are no path based rules, and my approach can be simple, I am looking > at using: action = (measure or appraise), mask = MAY_READ, fowner = root > (and I assume I want) func = FILE_CHECK. By default, files are appraised based on either a hash or signature. Requiring a file signature can be specified using the "appraise_type=imasig" option. For example, the following rules would require all files executed to be signed. For all other hooks, file integrity appraisal would be based on either a hash or signature. appraise fowner=0 func=BPRM_CHECK appraise_type=imasig appraise fowner=0 > Is there any way to obtain appraise actions based on a hash on the config files > while using appraise actions based on signatures on the executables? Identifying just the "config" files is the hard issue. > If not then I guess that means that I can only measure the config files? > > If I set a rule to measure these files the rule will also encompass the > root owned executables and they do not have a hash they only have a signature. > (When I create a hash for these it overwrites the signature.) > Is there a way to either provide both a hash and signature or to somehow exclude > the executables from a rule that catches the configuration files? Explanation above. > Is the use of the rules order dependent to allow masking a more general rule? The rules are order dependent. In the above example, the more specific "BPRM_CHECK" rule is specified first. > One more... > I was thinking of protecting some config files (that are essentially immutable > for these systems) with signatures but cannot see a good way to differentiate > between immutable configs and mutable configs. I was tempted to change the > group id to a "wheel" group but IMA only seems to only check fowner. Here's an opportunity to add "gid" support. :) > Is there a way to specify MAY_NOT_EXEC? > Can I just set an additional security xattr to flag this? Sorry, that is an access control(LSM) issue, not integrity. Mimi > Thanks and best regards, > Curtis |
|
From: Curtis V. <cr...@so...> - 2015-01-27 19:56:45
|
I have really appreciated help received on the user list. I've now been about to get my appraisal functionality working well for executables. (currently evm breaks it but I am putting that to the back burner) Most of the questions below may be able to be dealt with using LSM labels, Is there a good reference somewhere to using LSM labels? I currently have apparmor enabled and it does not appear to do much with labels. Should I do something like adding Smack labels and use those or roll my own? Any recommendations would be very welcome. If there are no comments about the following I will assume that the correct approach is to use LSM labels. Although there are actually a couple items where clarification would be nice. I do have a few questions that affect the way the I will implement measurement policy. Most important perhaps is wondering how policy rules that apply to a subset of files work when there is also a rule that affects a superset? A specific example is that I am signing and appraising all executables. I would like to measure or appraise all config files using a hash. As there are no path based rules, and my approach can be simple, I am looking at using: action = (measure or appraise), mask = MAY_READ, fowner = root (and I assume I want) func = FILE_CHECK. Is there any way to obtain appraise actions based on a hash on the config files while using appraise actions based on signatures on the executables? If not then I guess that means that I can only measure the config files? If I set a rule to measure these files the rule will also encompass the root owned executables and they do not have a hash they only have a signature. (When I create a hash for these it overwrites the signature.) Is there a way to either provide both a hash and signature or to somehow exclude the executables from a rule that catches the configuration files? Is the use of the rules order dependent to allow masking a more general rule? One more... I was thinking of protecting some config files (that are essentially immutable for these systems) with signatures but cannot see a good way to differentiate between immutable configs and mutable configs. I was tempted to change the group id to a "wheel" group but IMA only seems to only check fowner. Is there a way to specify MAY_NOT_EXEC? Can I just set an additional security xattr to flag this? Thanks and best regards, Curtis |
|
From: Curtis V. <cr...@so...> - 2015-01-27 19:48:19
|
I have pulled parts out of the evmctl(1) manual page into a script
and made a couple minor changes. Hope this is helpful for someone.
Also comments and suggestions are always welcome.
This could be added to the ima-evm-utils examples if desired.
- Curtis
diff -ruN oldexamples/load_keys.sh examples/load_keys.sh
--- oldexamples/load_keys.sh 1969-12-31 17:00:00.000000000 -0700
+++ examples/load_keys.sh 2015-01-27 12:36:52.857679097 -0700
@@ -0,0 +1,54 @@
+#!/bin/bash
+# Load the default keys from /etc/keys and then the policy
+# This is mostly taken from the evmctl(1) page with minor changes
+# and a few fixes. (No TPM so I use the encrypted key
+# not the trusted one.)
+#
+# Copyright 2012 Linux Integrity Project Free use of this software
+# is granted under the terms of the GNU Public License (GPL)
+# Author of this rough incarnation of the script: Curtis Veit
+# Original Author: Dmitry Kasatkin and possibly others
+
+ima_id="`awk '/\.ima/ { print "0x"$1 } ' /proc/keys`"
+ # printf syntax fails for me
+if [ -z "$ima_id" ]; then
+ ima_id=`keyctl search @u keyring _ima 2>/dev/null`
+ if [ -z "$ima_id" ]; then
+ ima_id=`keyctl newring _ima @u`
+ fi
+ dotIMAring="no"
+fi
+
+#import the default ima certificate.
+ima_key=`evmctl import /etc/keys/x509_ima.der $ima_id`
+
+# Now do evm
+evm_id=`keyctl search @u keyring _evm 2>/dev/null`
+if [ -z "$evm_id" ]; then
+ evm_id=`keyctl newring _evm @u`
+fi
+
+#import the evm x509 certificate
+evmctl import /etc/keys/x509_evm.der $evm_id
+
+# add the EVM symetric key to the kernel keyring
+cat /etc/keys/kmk | keyctl padd user kmk @u
+keyctl add encrypted evm-key "load `cat /etc/keys/evm-key`" @u
+
+# Do the following for locking down the keyrings.
+# Protect the EVM keyring
+keyctl setperm $evm_id 0x0b0b0000
+# protect _ima keyring
+# (The .ima keyring gives - keyctl_setperm: Permission denied)
+if [ "$dotIMAring" = "no" ]; then
+ keyctl setperm $ima_id 0x0b0b0000
+ # Protect IMA key from revoking (against DoS)
+ # use ima_key var from above. (the ima_key return value)
+ keyctl setperm $ima_key 0x0b0b0000
+fi
+
+# Turn everything on - not sure if there is a best order to the two line below...
+echo "1" > /sys/kernel/security/evm
+cat irms_policy > /sys/kernel/security/ima/policy
+
+exit 0
|
|
From: <fi...@li...> - 2015-01-27 15:06:12
|
This patch adds documentation for signing files. Signed-off-by: Fionnuala Gunter <fi...@li...> --- doc/rpmsign.8 | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/doc/rpmsign.8 b/doc/rpmsign.8 index 53f2d70..b19f172 100644 --- a/doc/rpmsign.8 +++ b/doc/rpmsign.8 @@ -2,11 +2,17 @@ .SH NAME rpmsign \- RPM Package Signing .SH SYNOPSIS +.SS "SIGNING PACKAGES:" +.PP -\fBrpm\fR \fB--addsign|--resign\fR \fB\fIPACKAGE_FILE\fB\fR\fI ...\fR +\fBrpm\fR \fB--addsign|--resign\fR [\fBrpmsign-options\fR] \fB\fIPACKAGE_FILE\fB\fR\fI ...\fR \fBrpm\fR \fB--delsign\fR \fB\fIPACKAGE_FILE\fB\fR\fI ...\fR +.SS "rpmsign-options" +.PP + \fB--fskpath \fIKEY\fB\fR] [\fB--signfiles\fR] + .SH DESCRIPTION .PP Both of the \fB--addsign\fR and \fB--resign\fR @@ -20,6 +26,19 @@ there is no difference in behavior currently. .PP Delete all signatures from each package \fIPACKAGE_FILE\fR given. +.SS "SIGN OPTIONS" +.PP +.TP +\fB--fskpath \fIKEY\fB\fR +Used with \fB--signfiles\fR, use file signing key \fIKEY\fR. +.TP +\fB--signfiles\fR +Sign package files. The macro \fB%_binary_filedigest_algorithm\fR must be set +before building the package, and the macro must be set to a supported algorithm: +2, 8, 9, or 10, which represent SHA1, SHA256, SHA384, and SHA512, respectively. +The file signing key (RSA private key) can be configured on the command line +with \fB--fskpath\fR or the macro \fB%_file_signing_key\fR. + .SS "USING GPG TO SIGN PACKAGES" .PP In order to sign packages using GPG, \fBrpm\fR @@ -78,4 +97,5 @@ Marc Ewing <ma...@re...> Jeff Johnson <jb...@re...> Erik Troan <ew...@re...> Panu Matilainen <pma...@re...> +Fionnuala Gunter <fi...@li...> .fi -- 2.1.0 |
|
From: <fi...@li...> - 2015-01-27 15:06:12
|
This plugin extract file signatures from rpmfiles and writes them to
security.ima xattr. Only non-config file signatures are installed.
Signed-off-by: Fionnnuala Gunter <fi...@li...>
---
macros.in | 1 +
plugins/Makefile.am | 4 ++++
plugins/ima.c | 60 +++++++++++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 65 insertions(+)
create mode 100644 plugins/ima.c
diff --git a/macros.in b/macros.in
index 1647104..0b62991 100644
--- a/macros.in
+++ b/macros.in
@@ -1043,6 +1043,7 @@ done \
%__transaction_systemd_inhibit %{__plugindir}/systemd_inhibit.so
%__transaction_selinux %{__plugindir}/selinux.so
%__transaction_syslog %{__plugindir}/syslog.so
+%__transaction_ima %{__plugindir}/ima.so
#------------------------------------------------------------------------------
# Macros for further automated spec %setup and patch application
diff --git a/plugins/Makefile.am b/plugins/Makefile.am
index 53b2450..5ddc174 100644
--- a/plugins/Makefile.am
+++ b/plugins/Makefile.am
@@ -31,3 +31,7 @@ endif
syslog_la_SOURCES = syslog.c
syslog_la_LIBADD = $(top_builddir)/lib/librpm.la $(top_builddir)/rpmio/librpmio.la
plugins_LTLIBRARIES += syslog.la
+
+ima_la_sources = ima.c
+ima_la_LIBADD = $(top_builddir)/lib/librpm.la $(top_builddir)/rpmio/librpmio.la
+plugins_LTLIBRARIES += ima.la
diff --git a/plugins/ima.c b/plugins/ima.c
new file mode 100644
index 0000000..c1d5607
--- /dev/null
+++ b/plugins/ima.c
@@ -0,0 +1,60 @@
+#include <sys/xattr.h>
+
+#include <rpm/rpmfi.h>
+#include <rpm/rpmte.h>
+#include <rpm/rpmfiles.h>
+#include <rpm/rpmtypes.h>
+#include <rpmio/rpmstring.h>
+
+#include "lib/rpmfs.h"
+#include "lib/rpmplugin.h"
+#include "lib/rpmte_internal.h"
+
+#define XATTR_NAME_IMA "security.ima"
+
+static char * fsmFsPath(rpmfi fi, const char * suffix)
+{
+ return rstrscat(NULL, rpmfiDN(fi), rpmfiBN(fi), suffix? suffix : "", NULL);
+}
+
+static rpmRC ima_psm_post(rpmPlugin plugin, rpmte te, int res)
+{
+ rpmfiles files = rpmteFiles(te);
+ rpmfi fi = rpmteFI(te);
+ int i;
+ char *fpath;
+ const unsigned char * fsig = NULL;
+ size_t len;
+ int rc = 0;
+
+ if (fi == NULL) {
+ rc = RPMERR_BAD_MAGIC;
+ goto exit;
+ }
+
+ while (!rc) {
+ rc = rpmfiNext(fi);
+ i = rpmfiFX(fi);
+
+ if (rc < 0) {
+ if (rc == RPMERR_ITER_END)
+ rc = 0;
+ break;
+ }
+
+ /* Don't install signatures for (mutable) config files */
+ if (!(rpmfilesFFlags(files, i) & RPMFILE_CONFIG)) {
+ fpath = fsmFsPath(fi, NULL);
+ fsig = rpmfilesFSignature(files, i, &len);
+ if (fsig) {
+ lsetxattr(fpath, XATTR_NAME_IMA, fsig, len, 0);
+ }
+ }
+ }
+exit:
+ return rc;
+}
+
+struct rpmPluginHooks_s ima_hooks = {
+ .psm_post = ima_psm_post,
+};
--
2.1.0
|
|
From: <fi...@li...> - 2015-01-27 15:06:09
|
This patch introduces rpmSignFiles, which extracts file digests from the
provided header and signs them using libimaevm and the provided key. The file
signatures are stored in the header as hex strings under the tag
RPM_FILESIGNATURES.
Signed-off-by: Fionnuala Gunter <fi...@li...>
---
lib/Makefile.am | 3 +-
lib/rpmsignfiles.c | 124 +++++++++++++++++++++++++++++++++++++++++++++++++++++
lib/rpmsignfiles.h | 20 +++++++++
3 files changed, 146 insertions(+), 1 deletion(-)
create mode 100644 lib/rpmsignfiles.c
create mode 100644 lib/rpmsignfiles.h
diff --git a/lib/Makefile.am b/lib/Makefile.am
index a65eb80..f80a47a 100644
--- a/lib/Makefile.am
+++ b/lib/Makefile.am
@@ -38,7 +38,8 @@ librpm_la_SOURCES = \
verify.c rpmlock.c rpmlock.h misc.h relocation.c \
rpmscript.h rpmscript.c legacy.c \
rpmchroot.c rpmchroot.h \
- rpmplugins.c rpmplugins.h rpmplugin.h rpmug.c rpmug.h
+ rpmplugins.c rpmplugins.h rpmplugin.h rpmug.c rpmug.h \
+ rpmsignfiles.c rpmsignfiles.h
librpm_la_LDFLAGS = -version-info $(rpm_version_info)
diff --git a/lib/rpmsignfiles.c b/lib/rpmsignfiles.c
new file mode 100644
index 0000000..3a1b96a
--- /dev/null
+++ b/lib/rpmsignfiles.c
@@ -0,0 +1,124 @@
+/**
+ * Copyright (C) 2014 IBM Corporation
+ *
+ * Author: Fionnuala Gunter <fi...@li...>
+ */
+
+#include "system.h"
+#include "imaevm.h"
+
+#include <rpm/rpmlog.h> /* rpmlog */
+#include <rpm/rpmstring.h> /* rnibble */
+#include <rpm/rpmpgp.h> /* rpmDigestLength */
+#include "lib/header.h" /* HEADERGET_MINMEM */
+#include "lib/rpmtypes.h" /* rpmRC */
+
+#include "lib/rpmsignfiles.h"
+
+#define MAX_SIGNATURE_LENGTH 1024
+
+static const char *hash_algo_name[] = {
+ [PGPHASHALGO_MD5] = "md5",
+ [PGPHASHALGO_SHA1] = "sha1",
+ [PGPHASHALGO_RIPEMD160] = "rmd160",
+ [PGPHASHALGO_MD2] = "md2",
+ [PGPHASHALGO_TIGER192] = "tgr192",
+ [PGPHASHALGO_HAVAL_5_160] = "haval5160",
+ [PGPHASHALGO_SHA256] = "sha256",
+ [PGPHASHALGO_SHA384] = "sha384",
+ [PGPHASHALGO_SHA512] = "sha512",
+ [PGPHASHALGO_SHA224] = "sha224",
+};
+
+static char *signFile(const char *algo, const char *fdigest, int diglen, const char *key)
+{
+ char *fsignature;
+ unsigned char digest[diglen];
+ unsigned char signature[MAX_SIGNATURE_LENGTH];
+ int siglen;
+
+#ifndef IMAEVM
+ rpmlog(RPMLOG_ERR, _("missing libimaevm\n"));
+ return NULL;
+#endif
+
+ /* convert file digest hex to binary */
+ memset(digest, 0, diglen);
+ for (int i = 0; i < diglen; ++i, fdigest += 2)
+ digest[i] = (rnibble(fdigest[0]) << 4) | rnibble(fdigest[1]);
+
+ /* prepare file signature */
+ memset(signature, 0, MAX_SIGNATURE_LENGTH);
+ signature[0] = '\x03';
+
+ /* calculate file signature */
+ siglen = sign_hash(algo, digest, diglen, key, signature+1);
+ if (siglen < 0) {
+ rpmlog(RPMLOG_ERR, _("sign_hash failed\n"));
+ return NULL;
+ }
+
+ /* convert file signature binary to hex */
+ fsignature = pgpHexStr(signature, siglen+1);
+ return fsignature;
+}
+
+static uint32_t signatureLength(const char *algo, int diglen, const char *key)
+{
+ unsigned char digest[diglen];
+ unsigned char signature[MAX_SIGNATURE_LENGTH];
+
+ memset(digest, 0, diglen);
+ memset(signature, 0, MAX_SIGNATURE_LENGTH);
+ signature[0] = '\x03';
+
+ uint32_t siglen = sign_hash(algo, digest, diglen, key, signature+1);
+ return siglen;
+}
+
+rpmRC rpmSignFiles(Header h, const char *key)
+{
+ struct rpmtd_s digests;
+ int algo;
+ int diglen;
+ uint32_t siglen;
+ const char *algoname;
+ const char *digest;
+ char *signature;
+ rpmRC rc = RPMRC_OK;
+
+ algo = headerGetNumber(h, RPMTAG_FILEDIGESTALGO);
+ if (!algo) {
+ rpmlog(RPMLOG_ERR, _("missing RPMTAG_FILEDIGESTALGO\n"));
+ return RPMRC_FAIL;
+ }
+
+ diglen = rpmDigestLength(algo);
+ algoname = hash_algo_name[algo];
+ if (!algoname) {
+ rpmlog(RPMLOG_ERR, _("hash_algo_name failed\n"));
+ return RPMRC_FAIL;
+ }
+
+ siglen = signatureLength(algoname, diglen, key);
+ headerPutUint32(h, RPMTAG_FILESIGNATURELENGTH, &siglen, 1);
+
+ headerGet(h, RPMTAG_FILEDIGESTS, &digests, HEADERGET_MINMEM);
+ while ((digest = rpmtdNextString(&digests))) {
+ signature = signFile(algoname, digest, diglen, key);
+ if (!signature) {
+ rpmlog(RPMLOG_ERR, _("signFile failed\n"));
+ rc = RPMRC_FAIL;
+ goto exit;
+ }
+ if (!headerPutString(h, RPMTAG_FILESIGNATURES, signature)) {
+ rpmlog(RPMLOG_ERR, _("headerPutString failed\n"));
+ rc = RPMRC_FAIL;
+ goto exit;
+ }
+ }
+
+exit:
+ rpmtdFreeData(&digests);
+ return rc;
+}
diff --git a/lib/rpmsignfiles.h b/lib/rpmsignfiles.h
new file mode 100644
index 0000000..70a5b9f
--- /dev/null
+++ b/lib/rpmsignfiles.h
@@ -0,0 +1,20 @@
+#ifndef H_RPMSIGNFILES
+#define H_RPMSIGNFILES
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * Sign file digests in header and store the signatures in header
+ * @param h package header
+ * @param key signing key
+ * @return RPMRC_OK on success
+ */
+rpmRC rpmSignFiles(Header h, const char *key);
+
+#ifdef _cplusplus
+}
+#endif
+
+#endif /* H_RPMSIGNFILES */
--
2.1.0
|
|
From: <fi...@li...> - 2015-01-27 15:06:07
|
This patch modifies rpmSign to include file signatures in the header. Since the
header is altered, the package digest and package+archive digest are
recalculated and updated in the signature header.
I haven't updated this code since submitting v3, my next task is to improve this
patch. Perhaps there is a better way to calculate the package digets, or maybe
I can reorganize the patch so there isn't redundant file i/o. Any suggestions
are welcome.
Signed-off-by: Fionnuala Gunter <fi...@li...>
---
sign/rpmgensig.c | 148 +++++++++++++++++++++++++++++++++++++++++++++++++++++--
1 file changed, 145 insertions(+), 3 deletions(-)
diff --git a/sign/rpmgensig.c b/sign/rpmgensig.c
index a48b4dd..848942c 100644
--- a/sign/rpmgensig.c
+++ b/sign/rpmgensig.c
@@ -16,9 +16,11 @@
#include <rpm/rpmfileutil.h> /* rpmMkTemp() */
#include <rpm/rpmlog.h>
#include <rpm/rpmstring.h>
+#include <rpmio/rpmio_internal.h>
#include "lib/rpmlead.h"
#include "lib/signature.h"
+#include "lib/rpmsignfiles.h"
#include "debug.h"
@@ -487,14 +489,150 @@ static void unloadImmutableRegion(Header *hdrp, rpmTagVal tag, rpmtd utd)
}
}
+static rpmRC includeFileSignatures(FD_t fd, const char *rpm,
+ Header *sigp, Header *hdrp,
+ off_t sigStart, off_t headerStart)
+{
+ FD_t ofd = NULL;
+ struct rpmtd_s td;
+ char *trpm = NULL;
+ const char *key;
+ char *SHA1 = NULL;
+ uint8_t *MD5 = NULL;
+ unsigned char buf[32*BUFSIZ];
+ size_t sha1len;
+ size_t md5len;
+ off_t headerSize;
+ off_t archiveSize;
+ rpmRC rc = RPMRC_OK;
+
+ unloadImmutableRegion(hdrp, RPMTAG_HEADERIMMUTABLE, &td);
+
+ key = rpmExpand("%{?_file_signing_key}", NULL);
+
+ rc = rpmSignFiles(*hdrp, key);
+ if (rc != RPMRC_OK) {
+ goto exit;
+ }
+
+ *hdrp = headerReload(*hdrp, RPMTAG_HEADERIMMUTABLE);
+ if (*hdrp == NULL) {
+ rc = RPMRC_FAIL;
+ rpmlog(RPMLOG_ERR, _("headerReload failed\n"));
+ goto exit;
+ }
+
+ ofd = rpmMkTempFile(NULL, &trpm);
+ if (ofd == NULL || Ferror(ofd)) {
+ rc = RPMRC_FAIL;
+ rpmlog(RPMLOG_ERR, _("rpmMkTemp failed\n"));
+ goto exit;
+ }
+
+ /* Copy archive to temp file */
+ if (copyFile(&fd, rpm, &ofd, trpm)) {
+ rc = RPMRC_FAIL;
+ rpmlog(RPMLOG_ERR, _("copyFile failed\n"));
+ goto exit;
+ }
+
+ if (Fseek(fd, headerStart, SEEK_SET) < 0) {
+ rc = RPMRC_FAIL;
+ rpmlog(RPMLOG_ERR, _("Could not seek in file %s: %s\n"),
+ rpm, Fstrerror(fd));
+ goto exit;
+ }
+
+ /* Write header to rpm and recalculate SHA1 */
+ fdInitDigest(fd, PGPHASHALGO_SHA1, 0);
+ rc = headerWrite(fd, *hdrp, HEADER_MAGIC_YES);
+ if (rc != RPMRC_OK) {
+ rpmlog(RPMLOG_ERR, _("headerWrite failed\n"));
+ goto exit;
+ }
+ fdFiniDigest(fd, PGPHASHALGO_SHA1, (void **)&SHA1, &sha1len, 1);
+ headerSize = Ftell(fd) - headerStart;
+
+ /* Copy archive from temp file */
+ if (Fseek(ofd, 0, SEEK_SET) < 0) {
+ rc = RPMRC_FAIL;
+ rpmlog(RPMLOG_ERR, _("Could not seek in file %s: %s\n"),
+ rpm, Fstrerror(fd));
+ goto exit;
+ }
+ if (copyFile(&ofd, trpm, &fd, rpm)) {
+ rc = RPMRC_FAIL;
+ rpmlog(RPMLOG_ERR, _("copyFile failed\n"));
+ goto exit;
+ }
+ unlink(trpm);
+
+ /* Recalculate MD5 digest of header+archive */
+ if (Fseek(fd, headerStart, SEEK_SET) < 0) {
+ rc = RPMRC_FAIL;
+ rpmlog(RPMLOG_ERR, _("Could not seek in file %s: %s\n"),
+ rpm, Fstrerror(fd));
+ goto exit;
+ }
+ fdInitDigest(fd, PGPHASHALGO_MD5, 0);
+
+ while (Fread(buf, sizeof(buf[0]), sizeof(buf), fd) > 0);
+ ;
+ if (Ferror(fd)) {
+ rc = RPMRC_FAIL;
+ rpmlog(RPMLOG_ERR, _("Fread failed in file %s: %s\n"),
+ rpm, Fstrerror(fd));
+ goto exit;
+ }
+ fdFiniDigest(fd, PGPHASHALGO_MD5, (void **)&MD5, &md5len, 0);
+
+ if (Fseek(fd, sigStart, SEEK_SET) < 0) {
+ rc = RPMRC_FAIL;
+ rpmlog(RPMLOG_ERR, _("Could not seek in file %s: %s\n"),
+ rpm, Fstrerror(fd));
+ goto exit;
+ }
+
+ /* Get payload size from signature tag */
+ archiveSize = headerGetNumber(*sigp, RPMSIGTAG_PAYLOADSIZE);
+ if (!archiveSize) {
+ archiveSize = headerGetNumber(*sigp, RPMSIGTAG_LONGARCHIVESIZE);
+ }
+
+ /* Replace old digests in sigh */
+ rc = rpmGenerateSignature(SHA1, MD5, headerSize, archiveSize, fd);
+ if (rc != RPMRC_OK) {
+ rpmlog(RPMLOG_ERR, _("generateSignature failed\n"));
+ goto exit;
+ }
+
+ if (Fseek(fd, sigStart, SEEK_SET) < 0) {
+ rc = RPMRC_FAIL;
+ rpmlog(RPMLOG_ERR, _("Could not seek in file %s: %s\n"),
+ rpm, Fstrerror(fd));
+ goto exit;
+ }
+
+ rc = rpmReadSignature(fd, sigp, RPMSIGTYPE_HEADERSIG, NULL);
+ if (rc != RPMRC_OK) {
+ rpmlog(RPMLOG_ERR, _("rpmReadSignature failed\n"));
+ goto exit;
+ }
+exit:
+if (ofd) (void) closeFile(&ofd);
+ return rc;
+}
+
/** \ingroup rpmcli
* Create/modify elements in signature header.
* @param rpm path to package
* @param deleting adding or deleting signature?
+ * @param signfiles sign files if non-zero
* @param passPhrase passPhrase (ignored when deleting)
* @return 0 on success, -1 on error
*/
-static int rpmSign(const char *rpm, int deleting, const char *passPhrase)
+static int rpmSign(const char *rpm, int deleting, int signfiles,
+ const char *passPhrase)
{
FD_t fd = NULL;
FD_t ofd = NULL;
@@ -545,6 +683,10 @@ static int rpmSign(const char *rpm, int deleting, const char *passPhrase)
goto exit;
}
+ if (signfiles) {
+ includeFileSignatures(fd, rpm, &sigh, &h, sigStart, headerStart);
+ }
+
unloadImmutableRegion(&sigh, RPMTAG_HEADERSIGNATURES, &utd);
origSigSize = headerSizeof(sigh, HEADER_MAGIC_YES);
@@ -695,7 +837,7 @@ int rpmPkgSign(const char *path,
}
}
- rc = rpmSign(path, 0, passPhrase);
+ rc = rpmSign(path, 0, args->signfiles, passPhrase);
if (args) {
if (args->hashalgo) {
@@ -711,5 +853,5 @@ int rpmPkgSign(const char *path,
int rpmPkgDelSign(const char *path)
{
- return rpmSign(path, 1, NULL);
+ return rpmSign(path, 1, 0, NULL);
}
--
2.1.0
|
|
From: <fi...@li...> - 2015-01-27 15:06:01
|
This patch extends the rpmsign tool to sign package files. It adds new options
to rpmsign - signfiles and fskpath.
rpm --addsign [--signfiles [--fskpath <file-signing-key>]] PACKAGE
Signfiles signs all the file digests included in the package and stores the
signatures in the package header. The file signing key can be provided with
the new option fskpath, or in a macro file with %_file_signing_key. After
including file signatures, the package is signed normally.
The package needs to be built with SHA-1 or SHA-2 digests before package files
are signed, this prerequisite is noted in rpmsign man page.
Signed-off-by: Fionnuala Gunter <fi...@li...>
---
rpmpopt.in | 1 +
rpmsign.c | 24 +++++++++++++++++++++++-
sign/rpmsign.h | 1 +
3 files changed, 25 insertions(+), 1 deletion(-)
diff --git a/rpmpopt.in b/rpmpopt.in
index 036ab4e..df5e2ec 100644
--- a/rpmpopt.in
+++ b/rpmpopt.in
@@ -162,6 +162,7 @@ rpm alias --httpproxy --define '_httpproxy !#:+'
rpm exec --addsign rpmsign --addsign
rpm exec --delsign rpmsign --delsign
rpm exec --resign rpmsign --resign
+#rpm exec --signfiles rpmsign --signfiles
rpm exec --checksig rpmkeys --checksig
rpm exec -K rpmkeys --checksig
rpm exec --import rpmkeys --import
diff --git a/rpmsign.c b/rpmsign.c
index b8e5598..2e03de8 100644
--- a/rpmsign.c
+++ b/rpmsign.c
@@ -20,6 +20,9 @@ enum modes {
static int mode = 0;
+static int signfiles = 0;
+static char * fileSigningKey = NULL;
+
static struct poptOption signOptsTable[] = {
{ "addsign", '\0', (POPT_ARG_VAL|POPT_ARGFLAG_OR), &mode, MODE_ADDSIGN,
N_("sign package(s)"), NULL },
@@ -27,6 +30,11 @@ static struct poptOption signOptsTable[] = {
N_("sign package(s) (identical to --addsign)"), NULL },
{ "delsign", '\0', (POPT_ARG_VAL|POPT_ARGFLAG_OR), &mode, MODE_DELSIGN,
N_("delete package signatures"), NULL },
+ { "signfiles", '\0', POPT_ARG_NONE, &signfiles, 0,
+ N_("sign package(s) files"), NULL},
+ { "fskpath", '\0', POPT_ARG_STRING, &fileSigningKey, 0,
+ N_("use file signing key <key>"),
+ N_("<key>") },
POPT_TABLEEND
};
@@ -113,12 +121,26 @@ static int doSign(poptContext optCon)
int rc = EXIT_FAILURE;
char * passPhrase = NULL;
char * name = rpmExpand("%{?_gpg_name}", NULL);
+ struct rpmSignArgs sig = {NULL, 0, 0};
if (rstreq(name, "")) {
fprintf(stderr, _("You must set \"%%_gpg_name\" in your macro file\n"));
goto exit;
}
+ if (fileSigningKey) {
+ addMacro(NULL, "_file_signing_key", NULL, fileSigningKey, RMIL_GLOBAL);
+ }
+
+ if (signfiles) {
+ const char *key = rpmExpand("%{?_file_signing_key}", NULL);
+ if (rstreq(key, "")) {
+ fprintf(stderr, _("You must set \"$$_file_signing_key\" in your macro file or on the command line with --fskpath\n"));
+ goto exit;
+ }
+ sig.signfiles = 1;
+ }
+
/* XXX FIXME: eliminate obsolete getpass() usage */
passPhrase = getpass(_("Enter pass phrase: "));
passPhrase = (passPhrase != NULL) ? rstrdup(passPhrase) : NULL;
@@ -127,7 +149,7 @@ static int doSign(poptContext optCon)
fprintf(stderr, _("Pass phrase is good.\n"));
rc = 0;
while ((arg = poptGetArg(optCon)) != NULL) {
- rc += rpmPkgSign(arg, NULL, passPhrase);
+ rc += rpmPkgSign(arg, &sig, passPhrase);
}
} else {
fprintf(stderr, _("Pass phrase check failed or gpg key expired\n"));
diff --git a/sign/rpmsign.h b/sign/rpmsign.h
index 15b3e0f..7a1b8e1 100644
--- a/sign/rpmsign.h
+++ b/sign/rpmsign.h
@@ -11,6 +11,7 @@ extern "C" {
struct rpmSignArgs {
char *keyid;
pgpHashAlgo hashalgo;
+ int signfiles;
/* ... what else? */
};
--
2.1.0
|
|
From: <fi...@li...> - 2015-01-27 15:05:56
|
This patch adds a config option to build with libimaevm which is needed for file signing. Signed-off-by: Fionnuala Gunter <fi...@li...> --- configure.ac | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/configure.ac b/configure.ac index cbb869f..21a6a95 100644 --- a/configure.ac +++ b/configure.ac @@ -658,6 +658,14 @@ AC_SUBST(WITH_SELINUX_LIB) AC_SUBST(WITH_SEMANAGE_LIB) AM_CONDITIONAL(SELINUX,[test "$with_selinux" = yes]) +# libimaevm +with_iamevm=no +AC_ARG_WITH(imaevm, [AS_HELP_STRING([--with-imaevm],[build with imaevm support])]) +if test "$with_imaevm" = yes ; then + AC_DEFINE(IMAEVM, 1, [Build with imaevm support?]) + LIBS="$LIBS -limaevm" +fi + # libcap WITH_CAP_LIB= AC_ARG_WITH(cap, [AS_HELP_STRING([--with-cap],[build with capability support])], -- 2.1.0 |
|
From: <fi...@li...> - 2015-01-27 15:05:54
|
This patch adds rpmtags for file signatures and their length, so they can be
stored in the package header.
Signed-off-by: Fionnuala Gunter <fi...@li...>
---
lib/rpmtag.h | 2 ++
1 file changed, 2 insertions(+)
diff --git a/lib/rpmtag.h b/lib/rpmtag.h
index 58b2479..319fdcf 100644
--- a/lib/rpmtag.h
+++ b/lib/rpmtag.h
@@ -329,6 +329,8 @@ typedef enum rpmTag_e {
RPMTAG_SUPPLEMENTNEVRS = 5060, /* s[] extension */
RPMTAG_ENHANCENEVRS = 5061, /* s[] extension */
RPMTAG_ENCODING = 5062, /* s */
+ RPMTAG_FILESIGNATURES = 5063, /* s[] */
+ RPMTAG_FILESIGNATURELENGTH = 5064, /* i */
RPMTAG_FIRSTFREE_TAG /*!< internal */
} rpmTag;
--
2.1.0
|
|
From: <fi...@li...> - 2015-01-27 15:05:53
|
This patch adds file signatures and file signature length to rpmfiles. These
new members are set in rpmfilesPopulate, and they can be accessed with
rpmfiFSignature.
Signed-off-by: Fionnuala Gunter <fi...@li...>
---
lib/rpmfi.c | 45 ++++++++++++++++++++++++++++++++++++++++++++-
lib/rpmfi.h | 8 ++++++++
lib/rpmfiles.h | 10 ++++++++++
3 files changed, 62 insertions(+), 1 deletion(-)
diff --git a/lib/rpmfi.c b/lib/rpmfi.c
index 2fba707..26e8866 100644
--- a/lib/rpmfi.c
+++ b/lib/rpmfi.c
@@ -111,7 +111,9 @@ struct rpmfiles_s {
struct fingerPrint_s * fps; /*!< File fingerprint(s). */
int digestalgo; /*!< File digest algorithm */
+ int signaturelength; /*!< File signature length */
unsigned char * digests; /*!< File digests in binary. */
+ unsigned char * signatures; /*!< File signatures in binary. */
struct nlinkHash_s * nlinks;/*!< Files connected by hardlinks */
rpm_off_t * replacedSizes; /*!< (TR_ADDED) */
@@ -560,6 +562,19 @@ char * rpmfiFDigestHex(rpmfi fi, int *algo)
return fdigest;
}
+const unsigned char * rpmfilesFSignature(rpmfiles fi, int ix, size_t *len)
+{
+ const unsigned char *signature = NULL;
+
+ if (fi != NULL && ix >= 0 && ix < rpmfilesFC(fi)) {
+ if (fi->signatures != NULL)
+ signature = fi->signatures + (fi->signaturelength * ix);
+ if (len)
+ *len = fi->signaturelength;
+ }
+ return signature;
+}
+
const char * rpmfilesFLink(rpmfiles fi, int ix)
{
const char * flink = NULL;
@@ -1146,6 +1161,7 @@ rpmfiles rpmfilesFree(rpmfiles fi)
fi->flinks = _free(fi->flinks);
fi->flangs = _free(fi->flangs);
fi->digests = _free(fi->digests);
+ fi->signatures = _free(fi->signatures);
fi->fcaps = _free(fi->fcaps);
fi->cdict = _free(fi->cdict);
@@ -1360,7 +1376,7 @@ static int rpmfilesPopulate(rpmfiles fi, Header h, rpmfiFlags flags)
headerGetFlags scareFlags = (flags & RPMFI_KEEPHEADER) ?
HEADERGET_MINMEM : HEADERGET_ALLOC;
headerGetFlags defFlags = HEADERGET_ALLOC;
- struct rpmtd_s fdigests, digalgo, td;
+ struct rpmtd_s fdigests, fsignatures, digalgo, td;
unsigned char * t;
/* XXX TODO: all these should be sanity checked, ugh... */
@@ -1411,6 +1427,8 @@ static int rpmfilesPopulate(rpmfiles fi, Header h, rpmfiFlags flags)
}
}
+ fi->signaturelength = headerGetNumber(h, RPMTAG_FILESIGNATURELENGTH);
+
fi->digests = NULL;
/* grab hex digests from header and store in binary format */
if (!(flags & RPMFI_NOFILEDIGESTS) &&
@@ -1431,10 +1449,30 @@ static int rpmfilesPopulate(rpmfiles fi, Header h, rpmfiFlags flags)
rpmtdFreeData(&fdigests);
}
+ fi->signatures = NULL;
+ /* grab hex signatures from header and store in binary format */
+ if (! (flags & RPMFI_NOFILESIGNATURES) &&
+ headerGet(h, RPMTAG_FILESIGNATURES, &fsignatures, HEADERGET_MINMEM)) {
+ const char *fsignature;
+ fi->signatures = t = xmalloc(rpmtdCount(&fsignatures) * fi->signaturelength);
+
+ while ((fsignature = rpmtdNextString(&fsignatures))) {
+ if (!(fsignature && *fsignature != '\0')) {
+ memset(t, 0, fi->signaturelength);
+ t += fi->signaturelength;
+ continue;
+ }
+ for (int j = 0; j < fi->signaturelength; j++, t++, fsignature += 2)
+ *t = (rnibble(fsignature[0]) << 4) | rnibble(fsignature[1]);
+ }
+ rpmtdFreeData(&fsignatures);
+ }
+
/* XXX TR_REMOVED doesn;t need fmtimes, frdevs, finodes */
if (!(flags & RPMFI_NOFILEMTIMES))
_hgfi(h, RPMTAG_FILEMTIMES, &td, scareFlags, fi->fmtimes);
if (!(flags & RPMFI_NOFILERDEVS))
+
_hgfi(h, RPMTAG_FILERDEVS, &td, scareFlags, fi->frdevs);
if (!(flags & RPMFI_NOFILEINODES)) {
_hgfi(h, RPMTAG_FILEINODES, &td, scareFlags, fi->finodes);
@@ -1662,6 +1700,11 @@ const unsigned char * rpmfiFDigest(rpmfi fi, int *algo, size_t *len)
return rpmfilesFDigest(fi->files, fi ? fi->i : -1, algo, len);
}
+const unsigned char * rpmfiFSignature(rpmfi fi, size_t *len)
+{
+ return rpmfilesFSignature(fi->files, fi ? fi->i : -1, len);
+}
+
uint32_t rpmfiFDepends(rpmfi fi, const uint32_t ** fddictp)
{
return rpmfilesFDepends(fi->files, fi ? fi->i : -1, fddictp);
diff --git a/lib/rpmfi.h b/lib/rpmfi.h
index dd44451..09127c3 100644
--- a/lib/rpmfi.h
+++ b/lib/rpmfi.h
@@ -181,6 +181,14 @@ const unsigned char * rpmfiFDigest(rpmfi fi, int *algo, size_t *diglen);
char * rpmfiFDigestHex(rpmfi fi, int *algo);
/** \ingroup rpmfi
+ * Return current file (binary) signature of file info set iterator.
+ * @param fi file info set iterator
+ * @retval siglen signature length (pass NULL to ignore)
+ * @return current file signature, NULL on invalid
+ */
+const unsigned char * rpmfiFSignature(rpmfi fi, size_t *siglen);
+
+/** \ingroup rpmfi
* Return current file (binary) md5 digest from file info set iterator.
* @deprecated Use rpmfiFDigest() instead
* @param fi file info set iterator
diff --git a/lib/rpmfiles.h b/lib/rpmfiles.h
index 928c420..d966590 100644
--- a/lib/rpmfiles.h
+++ b/lib/rpmfiles.h
@@ -116,6 +116,7 @@ enum rpmfiFlags_e {
RPMFI_NOFILECOLORS = (1 << 15),
RPMFI_NOFILEVERIFYFLAGS = (1 << 16),
RPMFI_NOFILEFLAGS = (1 << 17),
+ RPMFI_NOFILESIGNATURES = (1 << 18),
};
typedef rpmFlags rpmfiFlags;
@@ -417,6 +418,15 @@ rpm_mode_t rpmfilesFMode(rpmfiles fi, int ix);
const unsigned char * rpmfilesFDigest(rpmfiles fi, int ix, int *algo, size_t *len);
/** \ingroup rpmfiles
+ * Return file (binary) digest of file info set.
+ * @param fi file info set
+ * @param ix file index
+ * @retval siglen signature length (pass NULL to ignore)
+ * @return file signature, NULL on invalid
+ */
+const unsigned char * rpmfilesFSignature(rpmfiles fi, int ix, size_t *len);
+
+/** \ingroup rpmfiles
* Return file rdev from file info set.
* @param fi file info set
* @param ix file index
--
2.1.0
|
|
From: <fi...@li...> - 2015-01-27 15:05:52
|
This patch exports generateSignature under the new name rpmGenerateSignature so
that includeFileSignatures can call it.
Signed-off-by: Fionnuala Gunter <fi...@li...>
---
build/pack.c | 90 ++-------------------------------------------------------
lib/signature.c | 87 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
lib/signature.h | 11 +++++++
3 files changed, 100 insertions(+), 88 deletions(-)
diff --git a/build/pack.c b/build/pack.c
index 15f005a..d1cabfa 100644
--- a/build/pack.c
+++ b/build/pack.c
@@ -268,92 +268,6 @@ static rpm_loff_t estimateCpioSize(Package pkg)
return size;
}
-static rpmRC generateSignature(char *SHA1, uint8_t *MD5, rpm_loff_t size,
- rpm_loff_t payloadSize, FD_t fd)
-{
- Header sig = NULL;
- struct rpmtd_s td;
- rpmRC rc = RPMRC_OK;
- char *reservedSpace;
- int spaceSize = 0;
-
- /* Prepare signature */
- sig = rpmNewSignature();
-
- rpmtdReset(&td);
- td.tag = RPMSIGTAG_SHA1;
- td.count = 1;
- td.type = RPM_STRING_TYPE;
- td.data = SHA1;
- headerPut(sig, &td, HEADERPUT_DEFAULT);
-
- rpmtdReset(&td);
- td.tag = RPMSIGTAG_MD5;
- td.count = 16;
- td.type = RPM_BIN_TYPE;
- td.data = MD5;
- headerPut(sig, &td, HEADERPUT_DEFAULT);
-
- rpmtdReset(&td);
- td.count = 1;
- if (payloadSize < UINT32_MAX) {
- rpm_off_t p = payloadSize;
- rpm_off_t s = size;
- td.type = RPM_INT32_TYPE;
-
- td.tag = RPMSIGTAG_PAYLOADSIZE;
- td.data = &p;
- headerPut(sig, &td, HEADERPUT_DEFAULT);
-
- td.tag = RPMSIGTAG_SIZE;
- td.data = &s;
- headerPut(sig, &td, HEADERPUT_DEFAULT);
- } else {
- rpm_loff_t p = payloadSize;
- rpm_loff_t s = size;
- td.type = RPM_INT64_TYPE;
-
- td.tag = RPMSIGTAG_LONGARCHIVESIZE;
- td.data = &p;
- headerPut(sig, &td, HEADERPUT_DEFAULT);
-
- td.tag = RPMSIGTAG_LONGSIZE;
- td.data = &s;
- headerPut(sig, &td, HEADERPUT_DEFAULT);
- }
-
- spaceSize = rpmExpandNumeric("%{__gpg_reserved_space}");
- if(spaceSize > 0) {
- reservedSpace = xcalloc(spaceSize, sizeof(char));
- rpmtdReset(&td);
- td.tag = RPMSIGTAG_RESERVEDSPACE;
- td.count = spaceSize;
- td.type = RPM_BIN_TYPE;
- td.data = reservedSpace;
- headerPut(sig, &td, HEADERPUT_DEFAULT);
- free(reservedSpace);
- }
-
- /* Reallocate the signature into one contiguous region. */
- sig = headerReload(sig, RPMTAG_HEADERSIGNATURES);
- if (sig == NULL) { /* XXX can't happen */
- rpmlog(RPMLOG_ERR, _("Unable to reload signature header.\n"));
- rc = RPMRC_FAIL;
- goto exit;
- }
-
- /* Write the signature section into the package. */
- if (rpmWriteSignature(fd, sig)) {
- rc = RPMRC_FAIL;
- goto exit;
- }
-
-exit:
- rpmFreeSignature(sig);
- return rc;
-}
-
-
static rpmRC writeRPM(Package pkg, unsigned char ** pkgidp,
const char *fileName, char **cookie)
{
@@ -492,7 +406,7 @@ static rpmRC writeRPM(Package pkg, unsigned char ** pkgidp,
sigStart = Ftell(fd);
/* Generate and write a placeholder signature header */
- rc = generateSignature(zerosS, zeros, 0, estimatedCpioSize, fd);
+ rc = rpmGenerateSignature(zerosS, zeros, 0, estimatedCpioSize, fd);
if (rc != RPMRC_OK) {
rc = RPMRC_FAIL;
goto exit;
@@ -548,7 +462,7 @@ static rpmRC writeRPM(Package pkg, unsigned char ** pkgidp,
}
/* Generate the signature. Now with right values */
- rc = generateSignature(SHA1, MD5, sigTargetSize, pkg->cpioArchiveSize, fd);
+ rc = rpmGenerateSignature(SHA1, MD5, sigTargetSize, pkg->cpioArchiveSize, fd);
if (rc != RPMRC_OK) {
rc = RPMRC_FAIL;
goto exit;
diff --git a/lib/signature.c b/lib/signature.c
index 0defc81..972c0d5 100644
--- a/lib/signature.c
+++ b/lib/signature.c
@@ -12,6 +12,7 @@
#include <rpm/rpmfileutil.h>
#include <rpm/rpmlog.h>
#include <rpm/rpmkeyring.h>
+#include <rpm/rpmmacro.h>
#include "lib/rpmlead.h"
#include "lib/signature.h"
@@ -296,6 +297,92 @@ Header rpmFreeSignature(Header sigh)
return headerFree(sigh);
}
+rpmRC rpmGenerateSignature(char *SHA1, uint8_t *MD5, rpm_loff_t size,
+ rpm_loff_t payloadSize, FD_t fd)
+{
+ Header sig = NULL;
+ struct rpmtd_s td;
+ rpmRC rc = RPMRC_OK;
+ char *reservedSpace;
+ int spaceSize = 0;
+
+ /* Prepare signature */
+ sig = rpmNewSignature();
+
+ rpmtdReset(&td);
+ td.tag = RPMSIGTAG_SHA1;
+ td.count = 1;
+ td.type = RPM_STRING_TYPE;
+ td.data = SHA1;
+ headerPut(sig, &td, HEADERPUT_DEFAULT);
+
+ rpmtdReset(&td);
+ td.tag = RPMSIGTAG_MD5;
+ td.count = 16;
+ td.type = RPM_BIN_TYPE;
+ td.data = MD5;
+ headerPut(sig, &td, HEADERPUT_DEFAULT);
+
+ rpmtdReset(&td);
+ td.count = 1;
+ if (payloadSize < UINT32_MAX) {
+ rpm_off_t p = payloadSize;
+ rpm_off_t s = size;
+ td.type = RPM_INT32_TYPE;
+
+ td.tag = RPMSIGTAG_PAYLOADSIZE;
+ td.data = &p;
+ headerPut(sig, &td, HEADERPUT_DEFAULT);
+
+ td.tag = RPMSIGTAG_SIZE;
+ td.data = &s;
+ headerPut(sig, &td, HEADERPUT_DEFAULT);
+ } else {
+ rpm_loff_t p = payloadSize;
+ rpm_loff_t s = size;
+ td.type = RPM_INT64_TYPE;
+
+ td.tag = RPMSIGTAG_LONGARCHIVESIZE;
+ td.data = &p;
+ headerPut(sig, &td, HEADERPUT_DEFAULT);
+
+ td.tag = RPMSIGTAG_LONGSIZE;
+ td.data = &s;
+ headerPut(sig, &td, HEADERPUT_DEFAULT);
+ }
+
+ spaceSize = rpmExpandNumeric("%{__gpg_reserved_space}");
+ if(spaceSize > 0) {
+ reservedSpace = xcalloc(spaceSize, sizeof(char));
+ rpmtdReset(&td);
+ td.tag = RPMSIGTAG_RESERVEDSPACE;
+ td.count = spaceSize;
+ td.type = RPM_BIN_TYPE;
+ td.data = reservedSpace;
+ headerPut(sig, &td, HEADERPUT_DEFAULT);
+ free(reservedSpace);
+ }
+
+ /* Reallocate the signature into one contiguous region. */
+ sig = headerReload(sig, RPMTAG_HEADERSIGNATURES);
+ if (sig == NULL) { /* XXX can't happen */
+ rpmlog(RPMLOG_ERR, _("Unable to reload signature header.\n"));
+ rc = RPMRC_FAIL;
+ goto exit;
+ }
+
+ /* Write the signature section into the package. */
+ if (rpmWriteSignature(fd, sig)) {
+ rc = RPMRC_FAIL;
+ goto exit;
+ }
+
+exit:
+ rpmFreeSignature(sig);
+ return rc;
+}
+
+
static const char * rpmSigString(rpmRC res)
{
const char * str;
diff --git a/lib/signature.h b/lib/signature.h
index e2db8fb..44a8b52 100644
--- a/lib/signature.h
+++ b/lib/signature.h
@@ -77,6 +77,17 @@ rpmRC rpmVerifySignature(rpmKeyring keyring, rpmtd sigtd, pgpDigParams sig,
*/
Header rpmFreeSignature(Header h);
+/** \ingroup signature
+ * Generate signature and write to file
+ * @param SHA1 SHA1 digest
+ * @param MD5 MD5 digest
+ * @param size size of header
+ * @param payloadSize size of archive
+ * @param fd output file
+ */
+rpmRC rpmGenerateSignature(char *SHA1, uint8_t *MD5, rpm_loff_t size,
+ rpm_loff_t payloadSize, FD_t fd);
+
RPM_GNUC_INTERNAL
rpmRC rpmSigInfoParse(rpmtd td, const char *origin,
struct sigtInfo_s *sigt, pgpDigParams *sigp, char **msg);
--
2.1.0
|
|
From: <fi...@li...> - 2015-01-27 15:05:52
|
This patch creates a subroutine for dumping the immutable region of a header.
It copies the header sections into a new header that can be altered.
Signed-off-by: Fionnuala Gunter <fi...@li...>
---
sign/rpmgensig.c | 47 ++++++++++++++++++++++++++++-------------------
1 file changed, 28 insertions(+), 19 deletions(-)
diff --git a/sign/rpmgensig.c b/sign/rpmgensig.c
index 983a2f7..a48b4dd 100644
--- a/sign/rpmgensig.c
+++ b/sign/rpmgensig.c
@@ -460,6 +460,33 @@ static int replaceSignature(Header sigh, sigTarget sigt1, sigTarget sigt2,
return rc;
}
+static void unloadImmutableRegion(Header *hdrp, rpmTagVal tag, rpmtd utd)
+{
+ struct rpmtd_s copytd;
+ Header nh;
+ Header oh;
+ HeaderIterator hi;
+
+ if (headerGet(*hdrp, tag, utd, HEADERGET_DEFAULT)) {
+ nh = headerNew();
+ oh = headerCopyLoad(utd->data);
+ hi = headerInitIterator(oh);
+
+ while (headerNext(hi, ©td)) {
+ if (copytd.data)
+ headerPut(nh, ©td, HEADERPUT_DEFAULT);
+ rpmtdFreeData(©td);
+ }
+
+ headerFreeIterator(hi);
+ headerFree(oh);
+ rpmtdFreeData(utd);
+
+ *hdrp = headerLink(nh);
+ headerFree(nh);
+ }
+}
+
/** \ingroup rpmcli
* Create/modify elements in signature header.
* @param rpm path to package
@@ -518,25 +545,7 @@ static int rpmSign(const char *rpm, int deleting, const char *passPhrase)
goto exit;
}
- /* Dump the immutable region (if present). */
- if (headerGet(sigh, RPMTAG_HEADERSIGNATURES, &utd, HEADERGET_DEFAULT)) {
- struct rpmtd_s copytd;
- Header nh = headerNew();
- Header oh = headerCopyLoad(utd.data);
- HeaderIterator hi = headerInitIterator(oh);
- while (headerNext(hi, ©td)) {
- if (copytd.data)
- headerPut(nh, ©td, HEADERPUT_DEFAULT);
- rpmtdFreeData(©td);
- }
- headerFreeIterator(hi);
- headerFree(oh);
- rpmtdFreeData(&utd);
-
- headerFree(sigh);
- sigh = headerLink(nh);
- headerFree(nh);
- }
+ unloadImmutableRegion(&sigh, RPMTAG_HEADERSIGNATURES, &utd);
origSigSize = headerSizeof(sigh, HEADER_MAGIC_YES);
if (deleting) { /* Nuke all the signature tags. */
--
2.1.0
|
|
From: <fi...@li...> - 2015-01-27 15:05:47
|
This patch refactors copyFile so that it doesn't close sfdp and tfdp, since
copyFile didn't open those files. Also, the caller to copyFile closes these
files. This patch also adds descriptions of copyFile parameters.
Signed-off-by: Fionnuala Gunter <fi...@li...>
---
sign/rpmgensig.c | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/sign/rpmgensig.c b/sign/rpmgensig.c
index 0bd14e3..983a2f7 100644
--- a/sign/rpmgensig.c
+++ b/sign/rpmgensig.c
@@ -88,6 +88,10 @@ static int manageFile(FD_t *fdp, const char *fn, int flags)
/**
* Copy header+payload, calculating digest(s) on the fly.
+ * @param sfdp source file
+ * @param sfnp source path
+ * @param tfdp destination file
+ * @param tfnp destination path
*/
static int copyFile(FD_t *sfdp, const char *sfnp,
FD_t *tfdp, const char *tfnp)
@@ -121,8 +125,6 @@ static int copyFile(FD_t *sfdp, const char *sfnp,
rc = 0;
exit:
- if (*sfdp) (void) closeFile(sfdp);
- if (*tfdp) (void) closeFile(tfdp);
return rc;
}
--
2.1.0
|