
    VhF                        d dl mZ dZdZdZd dlZd dlmZ d dlm	Z	 d dl
mZ d d	lmZ d d
lmZ dadadZd Zd Zd Zd ZddZd Zd Zd ZddZd Zd ZddZd Zd Z e!dk(  r e         yy)    )annotationsa
  
---
module: apt_key
author:
- Jayson Vantuyl (@jvantuyl)
version_added: "1.0"
short_description: Add or remove an apt key
description:
    - Add or remove an I(apt) key, optionally downloading it.
extends_documentation_fragment: action_common_attributes
attributes:
    check_mode:
        support: full
    diff_mode:
        support: none
    platform:
        platforms: debian
notes:
    - The C(apt-key) command used by this module has been deprecated. See the L(Debian wiki,https://wiki.debian.org/DebianRepository/UseThirdParty) for details.
      This module is kept for backwards compatibility for systems that still use C(apt-key) as the main way to manage apt repository keys.
    - As a sanity check, downloaded key id must match the one specified.
    - "Use full fingerprint (40 characters) key ids to avoid key collisions.
      To generate a full-fingerprint imported key: C(apt-key adv --list-public-keys --with-fingerprint --with-colons)."
    - If you specify both the key O(id) and the O(url) with O(state=present), the task can verify or add the key as needed.
    - Adding a new key requires an apt cache update (e.g. using the M(ansible.builtin.apt) module's C(update_cache) option).
requirements:
    - gpg
seealso:
  - module: ansible.builtin.deb822_repository
options:
    id:
        description:
            - The identifier of the key.
            - Including this allows check mode to correctly report the changed state.
            - If specifying a subkey's id be aware that apt-key does not understand how to remove keys via a subkey id. Specify the primary key's id instead.
            - This parameter is required when O(state) is set to V(absent).
        type: str
    data:
        description:
            - The keyfile contents to add to the keyring.
        type: str
    file:
        description:
            - The path to a keyfile on the remote server to add to the keyring.
        type: path
    keyring:
        description:
            - The full path to specific keyring file in C(/etc/apt/trusted.gpg.d/).
        type: path
        version_added: "1.3"
    url:
        description:
            - The URL to retrieve key from.
        type: str
    keyserver:
        description:
            - The keyserver to retrieve key from.
        type: str
        version_added: "1.6"
    state:
        description:
            - Ensures that the key is present (added) or absent (revoked).
        type: str
        choices: [ absent, present ]
        default: present
    validate_certs:
        description:
            - If V(false), SSL certificates for the target url will not be validated. This should only be used
              on personally controlled sites using self-signed certificates.
        type: bool
        default: 'yes'
a*  
- name: One way to avoid apt_key once it is removed from your distro, armored keys should use .asc extension, binary should use .gpg
  block:
    - name: somerepo | no apt key
      ansible.builtin.get_url:
        url: https://keyserver.ubuntu.com/pks/lookup?op=get&search=0x36a1d7869245c8950f966e92d8576a8ba88d21e9
        dest: /etc/apt/keyrings/myrepo.asc
        checksum: sha256:bb42f0db45d46bab5f9ec619e1a47360b94c27142e57aa71f7050d08672309e0

    - name: somerepo | apt source
      ansible.builtin.apt_repository:
        repo: "deb [arch=amd64 signed-by=/etc/apt/keyrings/myrepo.asc] https://download.example.com/linux/ubuntu {{ ansible_distribution_release }} stable"
        state: present

- name: Add an apt key by id from a keyserver
  ansible.builtin.apt_key:
    keyserver: keyserver.ubuntu.com
    id: 36A1D7869245C8950F966E92D8576A8BA88D21E9

- name: Add an Apt signing key, uses whichever key is at the URL
  ansible.builtin.apt_key:
    url: https://ftp-master.debian.org/keys/archive-key-6.0.asc
    state: present

- name: Add an Apt signing key, will not download if present
  ansible.builtin.apt_key:
    id: 9FED2BCBDCD29CDF762678CBAED4B06F473041FA
    url: https://ftp-master.debian.org/keys/archive-key-6.0.asc
    state: present

- name: Remove a Apt specific signing key, leading 0x is valid
  ansible.builtin.apt_key:
    id: 0x9FED2BCBDCD29CDF762678CBAED4B06F473041FA
    state: absent

# Use armored file since utf-8 string is expected. Must be of "PGP PUBLIC KEY BLOCK" type.
- name: Add a key from a file on the Ansible server
  ansible.builtin.apt_key:
    data: "{{ lookup('ansible.builtin.file', 'apt.asc') }}"
    state: present

- name: Add an Apt signing key to a specific keyring file
  ansible.builtin.apt_key:
    id: 9FED2BCBDCD29CDF762678CBAED4B06F473041FA
    url: https://ftp-master.debian.org/keys/archive-key-6.0.asc
    keyring: /etc/apt/trusted.gpg.d/debian.gpg

- name: Add Apt signing key on remote server to keyring
  ansible.builtin.apt_key:
    id: 9FED2BCBDCD29CDF762678CBAED4B06F473041FA
    file: /tmp/apt.gpg
    state: present
a  
after:
    description: List of apt key ids or fingerprints after any modification
    returned: on change
    type: list
    sample: ["D8576A8BA88D21E9", "3B4FE6ACC0B21F32", "D94AA3F0EFE21092", "871920D1991BC93C"]
before:
    description: List of apt key ids or fingprints before any modifications
    returned: always
    type: list
    sample: ["3B4FE6ACC0B21F32", "D94AA3F0EFE21092", "871920D1991BC93C"]
fp:
    description: Fingerprint of the key to import
    returned: always
    type: str
    sample: "D8576A8BA88D21E9"
id:
    description: key id from source
    returned: always
    type: str
    sample: "36A1D7869245C8950F966E92D8576A8BA88D21E9"
key_id:
    description: calculated key id, it should be same as 'id', but can be different
    returned: always
    type: str
    sample: "36A1D7869245C8950F966E92D8576A8BA88D21E9"
short_id:
    description: calculated short key id
    returned: always
    type: str
    sample: "A88D21E9"
N)
format_exc)	to_native)AnsibleModule)get_best_parsable_locale)	fetch_urlc                    t        t        d      s#t        |       }t        ||||      t        _        t        j                  S )Nresult)LANGLC_ALLLC_MESSAGESLANGUAGE)hasattrlang_envr   dictr
   )modulelocales     G/home/dcms/DCMS/lib/python3.12/site-packages/ansible/modules/apt_key.pyr   r      s3    8X&)&1F6vX^_??    c                P    | j                  dd      a| j                  dd      ay )Nzapt-keyT)requiredgpg)get_bin_pathapt_key_bingpg_bin)r   s    r   find_needed_binariesr      s.     %%i$%?K!!%$!7Gr   c                n    dD ]%  }t         j                  j                  |      }|s% n r| d|z  z  } | S )N)HTTPS_PROXYhttps_proxy
HTTP_PROXY
http_proxyz" --keyserver-options http-proxy=%s)osenvironget)cmdenvvarproxys      r   add_http_proxyr(      sC    L 

v&
 3e;;Jr   c                    t        t        |       d       | j                         } | j                  d      r| dd } t	        |       }|dk7  r|dk7  r|dk  rt        d      | dd }| }|dkD  r| dd }||| fS )	a  validate the key_id and break it into segments

    :arg key_id: The key_id as supplied by the user.  A valid key_id will be
        8, 16, or more hexadecimal chars with an optional leading ``0x``.
    :returns: The portion of key_id suitable for apt-key del, the portion
        suitable for comparisons with --list-public-keys, and the portion that
        can be used with --recv-key.  If key_id is long enough, these will be
        the last 8 characters of key_id, the last 16 characters, and all of
        key_id.  If key_id is not long enough, some of the values will be the
        same.

    * apt-key del <= 1.10 has a bug with key_id != 8 chars
    * apt-key adv --list-public-keys prints 16 chars
    * apt-key adv --recv-key can take more chars

       0X   N   z=key_id must be 8, 16, or 16+ hexadecimal characters in lengthi)intr   upper
startswithlen
ValueError)key_id
key_id_lenshort_key_idfingerprints       r   parse_key_idr8      s    $ 	&2\\^FVJaJ",*2BXYY"#;LKBSTlf,,r   c                   g }t        |       j                  d      }|D ]e  }|j                  d      s|j                  d      s&d|vs+	 |j                         }|d   }|j                  d      \  }}|j                  |       g |r|rt        |      }|S # t        t        f$ r1 	 |j                  d      }|d   }n# t        t        f$ r Y Y w xY wY cw xY w)	N
pubsubexpired   /:   )r   splitr1   
IndexErrorr3   appendshorten_key_ids)	outputshort_formatfoundlineslinetokenscodelen_type	real_codes	            r   parse_output_for_keysrO      s    Ef##D)E $OOE"dooe&<)SWBWay(,

3%9 LL#$" &L 
+ !ZZ_F &q	I"J/  	s6   )BC(B?>C?CCCCCc                    |t         d|d}n	dt         z  }| j                  |      \  }}}|dk7  r| j                  d||||       t        ||      S )N --keyring z+ adv --list-public-keys --keyid-format=longz-%s adv --list-public-keys --keyid-format=longr   zUnable to list public keysmsgr%   rcstdoutstderr)r   run_command	fail_jsonrO   )r   keyringrG   r%   rT   outerrs          r   all_keysr\     sc    NY[bc=K'',NRc	Qw9srRU^ab l33r   c                @    g }| D ]  }|j                  |dd         |S )z|
    Takes a list of key ids, and converts them to the 'short' format,
    by reducing them to their last 8 characters.
    r.   N)rD   )key_id_listshortkeys      r   rE   rE   $  s/    
 E SXLr   c                    	 t        | |d      \  }}|d   dk7  r| j                  d|d|d          |j                         S # t        $ r! | j                  d	|z  t	               
       Y y w xY w)NT)	use_proxystatus   zFailed to download key at z: rS   rS   z!error getting key id from url: %s)rS   	traceback)r   rX   read	Exceptionr   )r   urlrspinfos       r   download_keyrl   /  s{    `fcT:	T>S sDQVK!XYxxz `@3FR\R^_`s   AA 'A0/A0c                   t        |      }|j                  d      dk\  }d }t        d|g}| j                  |t	        |       |r|n||       \  }}}	|dk7  r| j                  d|dn|z  ||	       t        |      }
|
r|
d   }|S )Nz$-----BEGIN PGP PUBLIC KEY BLOCK-----r   z--with-colons)environ_updatedatabinary_datazUnable to extract key from '%s'zinline data)rS   rU   rV   )r   findr   rW   r   rX   rO   )r   filenamero   native_data
is_armoredr`   r%   rT   rZ   r[   keyss              r   get_key_id_from_filerv   <  s    D/K!!"HIQNJ
COX
.C''HV<LcmT_sw  KU  GU'  VNRc	Qw>SWSc-iqr{~  HK  	L %D1gJr   c                    t        | d|      S )N-)rv   )r   ro   s     r   get_key_id_from_datary   Q  s    T22r   c                |   |rt         d|d|}nt         d|}t        |      }|d|}t        d      D ])  }| j                  |t	        |             \  }}}|dk(  s) y dk(  r*dv r&d	|d
|}	| j                  ||	t	        |              yd|d|}	| j                  ||	t	        |       |       y)NrQ   z adv --no-tty --keyserver z --recv    )rn   r   r,   znot found on keyserverzKey z not found on keyserver )r%   rS   forced_environmentzError fetching key z from keyserver: )r%   rS   r|   rT   rU   rV   T)r   r(   rangerW   r   rX   )
r   rY   	keyserverr4   r%   retryrT   rZ   r[   rS   s
             r   
import_keyr   U  s    ?JGU^_2=yI 
C  
(Cq s++C@P+QS#7 s 7/368>	JC#(6BRS  AG	RC#(6BRWYbenqrr   c                @   |L|rt         d|d}n	dt         z  }| j                  ||d      \  }}}|dk7  r| j                  d||||       y|rt         d|d	|}nt         d	|}| j                  |      \  }}}|dk7  r| j                  d
|z  |||||       y)NrQ   z add -z%s add -T)ro   rp   r   z$Unable to add a key from binary datarR   z add z Unable to add a key from file %s)rS   r%   rT   keyfilerU   rV   r   rW   rX   )r   r   rY   ro   r%   rT   rZ   r[   s           r   add_keyr   q  s    -8'BC{*C++Cd+MS#7:  ,  .97GLC!,g6C++C0S#76'B   r   c                    |rt         d|d|}nt         d|}| j                  |      \  }}}|dk7  r| j                  d|z  |||||       y)NrQ   z del r   z!Unable to remove a key with id %s)rS   r%   rT   r4   rU   rV   Tr   )r   r4   rY   r%   rT   rZ   r[   s          r   
remove_keyr     sg    *5wG(&1'',NRc	Qw3v> 	 	
 r   c                    t        t        t        d      t        d      t        d      t        d      t        d      t        dd      t        d      t        ddddg	      
      dd      } | j                  d   }| j                  d   }| j                  d   }| j                  d   }| j                  d   }| j                  d   }| j                  d   }d}d }	d }
d}t        |        ddi}|s?|r| j	                  d       |rt        | |      }|rt        | |      }n|rt        | |      }||d<   	 t        |      \  }	}
}|	|d<   |
|d<   ||d<   |
s | j                  d(ddi| t        |      dk(  rd}t        | ||      x|d <   }g }|dk(  r|r|	|vs|s1|
|vr,d|d<   | j                  s|rt        | ||       nS|rt        | |||       nB|rt        | d!||       n1|rt        | |      }t        | d!||       n | j                  d(dd"i| t        | ||      x|d#<   }|r|	|vs|s|
|vr | j                  d(d|d$z  i| n|dk(  r||s | j                  d(dd%i| |
|v rbd|d<   | j                  sQ|	;t        | |	|      r.t        | ||      x|d#<   }|
|v r, | j                  d(d|d&z  i| n | j                  d(dd'i|  | j                   d(i | y # t        $ r  | j                  d(ddi| Y w xY w))Nstr)typepathboolT)r   defaultpresentabsent)r   r   choices)idri   ro   filerY   validate_certsr~   state))ro   r   r~   ri   )argument_specsupports_check_modemutually_exclusiver   ri   ro   r   rY   r   r~   FzYapt-key did not return an error, but %s (check that the id is correct and *not* a subkey)changedz(Missing key_id, required with keyserver.re   short_idfpr4   rS   zInvalid key_idz`Unable to continue as we could not extract a valid fingerprint to compare against existing keys.r-   beforerx   z(No key to add ... how did i get here?!?!afterzfailed to add the keyzkey is required to remove a keyzthe key was not removedzerror removing key_id )r   r   paramsr   rX   rl   rv   ry   r8   r3   r2   r\   
check_moder   r   r   	exit_json)r   r4   ri   ro   rr   rY   r   r~   rG   r6   r7   error_no_errorrru   keys2s                  r   mainr     s   % 5!6"f%VT:&E9x>ST	
 !BF  ]]4 F
--
C== D}}V$HmmI&GMM'"Ek*I LLKpN   
EA!KL,D)&(;F)&$7FAdG4,8,@)k6$*$(   	F  	F  DE  	F
6{a "&'<@@AhK$E	\5|P[cgPgAiL$$FHg6vw	6BFC$7'4DFC$7$F$$Y)SYWXY &.fg|%LL'
U \%>YdlqYq$F$$W:Q)QWUVW	(	FH!BHaH$AiL$$  +
6<QX0Y)1&'<)PPAgJ"e+(((]^>W-W][\]$F$$F)@FAFFqi  43-334s   <K& &LL__main__)F)N)"
__future__r   DOCUMENTATIONEXAMPLESRETURNr"   rf   r   +ansible.module_utils.common.text.convertersr   ansible.module_utils.basicr   "ansible.module_utils.common.localer   ansible.module_utils.urlsr   r   r   r   r   r   r(   r8   rO   r\   rE   rl   rv   ry   r   r   r   r   __name__r   r   r   <module>r      s    #GR4l
B 
 ! A 4 G / 
	8
"-J6	4
`*38B$l^ zF r   