diff options
Diffstat (limited to 'lib')
| -rw-r--r-- | lib/libalpm/alpm.h | 22 | ||||
| -rw-r--r-- | lib/libalpm/signing.c | 122 | 
2 files changed, 96 insertions, 48 deletions
| diff --git a/lib/libalpm/alpm.h b/lib/libalpm/alpm.h index d9f3504c..a91b00f0 100644 --- a/lib/libalpm/alpm.h +++ b/lib/libalpm/alpm.h @@ -104,15 +104,26 @@ typedef enum _alpm_siglevel_t {  } alpm_siglevel_t;  /** - * PGP signature verification return codes + * PGP signature verification status return codes   */  typedef enum _alpm_sigstatus_t { -	ALPM_SIGSTATUS_VALID = 0, -	ALPM_SIGSTATUS_MARGINAL, -	ALPM_SIGSTATUS_UNKNOWN, -	ALPM_SIGSTATUS_BAD +	ALPM_SIGSTATUS_VALID, +	ALPM_SIGSTATUS_KEY_EXPIRED, +	ALPM_SIGSTATUS_SIG_EXPIRED, +	ALPM_SIGSTATUS_KEY_UNKNOWN, +	ALPM_SIGSTATUS_INVALID  } alpm_sigstatus_t; +/** + * PGP signature verification status return codes + */ +typedef enum _alpm_sigvalidity_t { +	ALPM_SIGVALIDITY_FULL, +	ALPM_SIGVALIDITY_MARGINAL, +	ALPM_SIGVALIDITY_NEVER, +	ALPM_SIGVALIDITY_UNKNOWN +} alpm_sigvalidity_t; +  /*   * Structures   */ @@ -202,6 +213,7 @@ typedef struct _alpm_backup_t {  typedef struct _alpm_sigresult_t {  	int count;  	alpm_sigstatus_t *status; +	alpm_sigvalidity_t *validity;  	char **uid;  } alpm_sigresult_t; diff --git a/lib/libalpm/signing.c b/lib/libalpm/signing.c index 275851c2..78e6264b 100644 --- a/lib/libalpm/signing.c +++ b/lib/libalpm/signing.c @@ -305,8 +305,9 @@ int _alpm_gpgme_checksig(alpm_handle_t *handle, const char *path,  	_alpm_log(handle, ALPM_LOG_DEBUG, "%d signatures returned\n", sigcount);  	result->status = calloc(sigcount, sizeof(alpm_sigstatus_t)); +	result->validity = calloc(sigcount, sizeof(alpm_sigvalidity_t));  	result->uid = calloc(sigcount, sizeof(char*)); -	if(!result->status || !result->uid) { +	if(!result->status || !result->validity || !result->uid) {  		handle->pm_errno = ALPM_ERR_MEMORY;  		goto error;  	} @@ -316,6 +317,7 @@ int _alpm_gpgme_checksig(alpm_handle_t *handle, const char *path,  			gpgsig = gpgsig->next, sigcount++) {  		alpm_list_t *summary_list, *summary;  		alpm_sigstatus_t status; +		alpm_sigvalidity_t validity;  		gpgme_key_t key;  		_alpm_log(handle, ALPM_LOG_DEBUG, "fingerprint: %s\n", gpgsig->fpr); @@ -335,6 +337,8 @@ int _alpm_gpgme_checksig(alpm_handle_t *handle, const char *path,  		if(gpg_err_code(err) == GPG_ERR_EOF) {  			_alpm_log(handle, ALPM_LOG_DEBUG, "key lookup failed, unknown key\n");  			err = GPG_ERR_NO_ERROR; +			STRDUP(result->uid[sigcount], gpgsig->fpr, +					handle->pm_errno = ALPM_ERR_MEMORY; goto error);  		} else {  			CHECK_ERR();  			if(key->uids) { @@ -346,34 +350,52 @@ int _alpm_gpgme_checksig(alpm_handle_t *handle, const char *path,  			gpgme_key_unref(key);  		} -		if(gpgsig->summary & GPGME_SIGSUM_VALID) { -			/* definite good signature */ -			_alpm_log(handle, ALPM_LOG_DEBUG, "result: valid signature\n"); -			status = ALPM_SIGSTATUS_VALID; -		} else if(gpgsig->summary & GPGME_SIGSUM_GREEN) { -			/* good signature */ -			_alpm_log(handle, ALPM_LOG_DEBUG, "result: green signature\n"); -			status = ALPM_SIGSTATUS_VALID; -		} else if(gpgsig->summary & GPGME_SIGSUM_RED) { -			/* definite bad signature, error */ -			_alpm_log(handle, ALPM_LOG_DEBUG, "result: red signature\n"); -			status = ALPM_SIGSTATUS_BAD; -		} else if(gpgsig->summary & GPGME_SIGSUM_KEY_MISSING) { -			_alpm_log(handle, ALPM_LOG_DEBUG, "result: signature from unknown key\n"); -			status = ALPM_SIGSTATUS_UNKNOWN; -		} else if(gpgsig->summary & GPGME_SIGSUM_KEY_EXPIRED) { -			_alpm_log(handle, ALPM_LOG_DEBUG, "result: key expired\n"); -			status = ALPM_SIGSTATUS_BAD; -		} else if(gpgsig->summary & GPGME_SIGSUM_SIG_EXPIRED) { -			_alpm_log(handle, ALPM_LOG_DEBUG, "result: signature expired\n"); -			status = ALPM_SIGSTATUS_BAD; +		switch(gpg_err_code(gpgsig->status)) { +			/* good cases */ +			case GPG_ERR_NO_ERROR: +				status = ALPM_SIGSTATUS_VALID; +				break; +			case GPG_ERR_KEY_EXPIRED: +				status = ALPM_SIGSTATUS_KEY_EXPIRED; +				break; +			/* bad cases */ +			case GPG_ERR_SIG_EXPIRED: +				status = ALPM_SIGSTATUS_SIG_EXPIRED; +				break; +			case GPG_ERR_NO_PUBKEY: +				status = ALPM_SIGSTATUS_KEY_UNKNOWN; +				break; +			case GPG_ERR_BAD_SIGNATURE: +			default: +				status = ALPM_SIGSTATUS_INVALID; +				break; +		} + +		if(status == ALPM_SIGSTATUS_VALID +				|| status == ALPM_SIGSTATUS_KEY_EXPIRED) { +			switch(gpgsig->validity) { +				case GPGME_VALIDITY_ULTIMATE: +				case GPGME_VALIDITY_FULL: +					validity = ALPM_SIGVALIDITY_FULL; +					break; +				case GPGME_VALIDITY_MARGINAL: +					validity = ALPM_SIGVALIDITY_MARGINAL; +					break; +				case GPGME_VALIDITY_NEVER: +					validity = ALPM_SIGVALIDITY_NEVER; +					break; +				case GPGME_VALIDITY_UNKNOWN: +				case GPGME_VALIDITY_UNDEFINED: +				default: +					validity = ALPM_SIGVALIDITY_UNKNOWN; +					break; +			}  		} else { -			/* we'll capture everything else here */ -			_alpm_log(handle, ALPM_LOG_DEBUG, "result: invalid signature\n"); -			status = ALPM_SIGSTATUS_BAD; +			validity = ALPM_SIGVALIDITY_NEVER;  		}  		result->status[sigcount] = status; +		result->validity[sigcount] = validity;  	}  	ret = 0; @@ -429,31 +451,45 @@ int _alpm_check_pgp_helper(alpm_handle_t *handle, const char *path,  		/* ret will already be -1 */  	} else {  		int num; -		for(num = 0; num < result.count; num++) { -			/* fallthrough in this case block is on purpose. if one allows unknown -			 * signatures, then a marginal signature should be allowed as well, and -			 * if neither of these are allowed we fall all the way through to bad. */ +		for(num = 0; !ret && num < result.count; num++) {  			switch(result.status[num]) {  				case ALPM_SIGSTATUS_VALID: +				case ALPM_SIGSTATUS_KEY_EXPIRED:  					_alpm_log(handle, ALPM_LOG_DEBUG, "signature is valid\n"); -					break; -				case ALPM_SIGSTATUS_MARGINAL: -					if(marginal) { -						_alpm_log(handle, ALPM_LOG_DEBUG, "allowing marginal signature\n"); -						break; -					} -				case ALPM_SIGSTATUS_UNKNOWN: -					if(unknown) { -						_alpm_log(handle, ALPM_LOG_DEBUG, "allowing unknown signature\n"); -						break; +					switch(result.validity[num]) { +						case ALPM_SIGVALIDITY_FULL: +							_alpm_log(handle, ALPM_LOG_DEBUG, "signature is fully trusted\n"); +							break; +						case ALPM_SIGVALIDITY_MARGINAL: +							_alpm_log(handle, ALPM_LOG_DEBUG, "signature is marginal trust\n"); +							if(!marginal) { +								ret = -1; +							} +							break; +						case ALPM_SIGVALIDITY_UNKNOWN: +							_alpm_log(handle, ALPM_LOG_DEBUG, "signature is unknown trust\n"); +							if(!unknown) { +								ret = -1; +							} +							break; +						case ALPM_SIGVALIDITY_NEVER: +							_alpm_log(handle, ALPM_LOG_DEBUG, "signature should never be trusted\n"); +							ret = -1; +							break;  					} -				case ALPM_SIGSTATUS_BAD: -				default: -					_alpm_log(handle, ALPM_LOG_DEBUG, "signature is invalid\n"); -					handle->pm_errno = invalid_err; +					break; +				case ALPM_SIGSTATUS_SIG_EXPIRED: +				case ALPM_SIGSTATUS_KEY_UNKNOWN: +				case ALPM_SIGSTATUS_INVALID: +					_alpm_log(handle, ALPM_LOG_DEBUG, "signature is not valid\n");  					ret = -1; +					break;  			}  		} + +		if(ret) { +			handle->pm_errno = invalid_err; +		}  	}  	alpm_sigresult_cleanup(&result); | 
