+
    \4i:5  ã                   ó^  € ^ RI t ^ RIt^ RIt ^ RIHt ^ RIt^ RIt^ RI	t	^ RI
t
^ RIt^ RIt^ RIHt ^ RIHt ^ RIHtHt ^ RIt^RIHt RtRt]P4                  ! R	]P6                  R
7       ] P8                  ! RRR7      t]P=                  RRRRR7       ]P=                  RRRRRR7       ]P=                  RRRRRR7       ]P=                  RR R!R"R#7       R]n        . t R$t!R% t"R& t#R' t$R7R( lt%R) t&R* t'R+ t(R8R, lt)R- t*R. t+R/ t,R0 t-R1 t.R9R2 lt/R3 t0R4 t1R5 t2R6 t3R#   ] d    ]t ELi ; i):é    N)ÚJSONDecodeError)Ú	Launchpad)Ú
quote_plus)ÚRequestÚurlopen)ÚVERSIONg      .@Úlpz%%(asctime)s %(levelname)s %(message)s)ÚformatÚlevelz9Authorize SSH public keys from trusted online identities.ússh-import-id)ÚdescriptionÚprogz-oz--outputÚFILEz5Write output to file (default ~/.ssh/authorized_keys))ÚmetavarÚhelpz-rz--removeÚ
store_trueFz&Remove a key from authorized keys file)ÚactionÚdefaultr   z-uz--useragentÚ	USERAGENTÚ z$Append to the http user agent string)r   r   r   ÚuseridsÚ+ÚUSERIDzUser IDs to import)Únargsr   r   z"https://launchpad.net/~%s/+sshkeysc                 óš   € \          F@  p \        P                  P                  V 4      '       g   K*  \        P                  ! V 4       KB  	  R# )z
Cleanup tempfiles
N)Ú	TEMPFILESÚosÚpathÚexistsÚunlink)Úfs    Ú8/usr/lib/python3/dist-packages/ssh_import_id/__init__.pyÚcleanupr#   E   s,   € ÷ ˆÜ�7‰7�>‰>˜!×ÔÜ�IŠI�aŽLó ó    c                ór   € \         P                  ! V 4       \        4        \        P                  ! ^4       R# )z&
The only thing in Perl worth keeping
N)ÚloggingÚerrorr#   ÚsysÚexit)Úmsgs   &r"   Údier+   N   s    € ô ‡M‚M�#ÔÜ„IÜ‡H‚HˆQ†Kr$   c                ó6  € V '       g   R# \        V 4      ^8  d   R# \        P                  ! RRR7      w  r\        P	                  V4       \
        P                  ! VR4      ;_uu_ 4       pVP                  RP                  V 4      4       VP                  R4       RRR4       \        P                  ! RR	R
V.\        P                  R7      pVP                  R4      w  rVVP                  '       d   R# \
        P                  ! V4       VP                  4       pV'       d   \        V4      ^8  d   R# . pVP                  4        F:  p	VP	                  \!        V	P#                  R4      P%                  4       4      4       K<  	  V#   + '       g   i     Ló; i)zR
Get the fingerprint for an SSH public key
Returns None if not valid key material
Nzssh-auth-key-checkz.pub)ÚprefixÚsuffixÚwÚ Ú
z
ssh-keygenz-lz-f)Ústdoutúutf-8)ÚlenÚtempfileÚmkstempr   Úappendr   ÚfdopenÚwriteÚjoinÚ
subprocessÚPopenÚPIPEÚcommunicateÚ
returncoder    ÚsplitÚstrÚdecodeÚstrip)
ÚfieldsÚtempfdÚtempnameÚtempfÚkeygen_procÚ
keygen_outÚ_Úkeygen_fieldsÚoutÚks
   &         r"   Úkey_fingerprintrN   W   s2  € ÷
 ÙÜ
ˆ6ƒ{�Q„ÙÜ×'Ò'Ø#¨Fô4Ñ€Fä×Ñ�XÔÜ	�Š�6˜3×	Ô	 5Ø�‰�C—H‘H˜VÓ$Ô%Ø�‰�DÔ÷ 
 ô ×"Ò"Ø	�t˜T 8Ð,´Z·_±_ôF€Kà×+Ñ+¨DÓ1�M€JØ××ÐáÜ‡I‚IˆhÔØ×$Ñ$Ó&€MßœC Ó.°Ô2áØ
€CØ×ÑÖˆØ�
‰
”3�q—x‘x Ó(×.Ñ.Ó0Ó1Ö2ñ  à€J÷# 
 ×	ús   Á+2FÆF	c                ó*   € V R8X  d   R# \        W4      # )zA
Open output for writing, supporting either stdout or a filename
Ú-F)Úopen)ÚnameÚmodes   &&r"   Úopen_outputrT   w   s   € ð ˆs„{ÙÜ�ÓÐr$   c                óè  € V R8X  d   R# \         P                  P                  V 4      '       d!   \         P                  P                  V 4      pMRp\         P                  P                  V4      '       gD   \         P                  ! ^?4      p\         P
                  ! VR4       \         P                  ! V4       \         P                  P                  V4      '       d   R# \        RV ,          4       R# )z1
Ensure that the keyfile parent directory exists
rP   TÚ.iÀ  z*Parent directory not found for output [%s]N)r   r   Údirnamer   ÚumaskÚmakedirsÚisdirr+   )ÚkeyfileÚ
parent_dirrX   s   &  r"   Úassert_parent_dirr]   €   s•   € ð
 �#„~Ùä	‡w�w‡��w×ÒÜ—W‘W—_‘_ WÓ-‰
àˆ
ä�7‰7�>‰>˜*×%Ò%Ü—’˜“ˆÜ
�Š�J Ô&Ü
�Š�ŒÜ	‡w�w‡}�}�Z× Ò ÙÜÐ4¸Õ@ÖAr$   c                 óx  € \        \        P                  P                  4      p V R8X  g&   \        P
                  P                  V 4      '       g   . pV#  \        V R4      ;_uu_ 4       pVP                  4       pRRR4       V#   + '       g   i     X# ; i  \         d    \        RT ,          4        X# i ; i)zA
Locate key file, read the current state, return lines in a list
rP   ÚrNz'Could not read authorized key file [%s])Úget_keyfileÚparserÚoptionsÚoutputr   r   r   rQ   Ú	readlinesÚOSErrorr+   )r[   ÚlinesÚfps      r"   Úread_keyfilerh   –   sž   € ô œ&Ÿ.™.×/Ñ/Ó0€GØ�#„~œRŸW™WŸ^™^¨G×4Ò4Øˆð €Lð	GÜ�g˜s×#Ô# rØŸ™›�÷ $ð
 €L÷ $Ö#ð
 €Lûô ô 	GÜÐ9¸WÕEÕFà€Lð	Gús0   ÁB Á)BÁ:B ÂB	ÂB ÂB ÂB9Â8B9c                óH  € \        \        P                  P                  4      pVR8X  dr   V  FK  pV'       g   K  \        P
                  P                  V4       \        P
                  P                  R4       KM  	  \        P
                  P                  4        R# \        V4      '       db   \        W!4      ;_uu_ 4       pV  F=  pVP                  4       '       g   K  VP                  V4       VP                  R4       K?  	  RRR4       R# R#   + '       g   i     R# ; i)z$
Locate key file, write lines to it
rP   z

N)r`   ra   rb   rc   r(   r2   r9   Úflushr]   rQ   rC   )Úkeyfile_linesrS   Úoutput_fileÚliner!   s   &&   r"   Úwrite_keyfilern   §   s¿   € ô œfŸn™n×3Ñ3Ó4€KØ�cÔÛ!ˆDß‰tÜ—
‘
× Ñ  Ô&Ü—
‘
× Ñ  Ö(ñ "ô 	�
‰
×ÑÖÜ	˜;×	'Ò	'Ü�+×$Ô$¨Û%�Ø—:‘:—<”<Ø—G‘G˜D”MØ—G‘G˜F–Oñ &÷ %Ñ$ñ 
(ß$×$Ð$ús   Ã DÃ&DÄD!	c                óD  € V '       g˜   \         P                  P                  R4      '       d   \         P                  R,          pM9\         P                  P	                  R\
        P                  ! 4       ,           4      p\         P                  P                  VRR4      p V # )zEReturn 'path' if true, else a path to current user's authorized_keys.ÚHOMEÚ~z.sshÚauthorized_keys)r   ÚenvironÚgetr   Ú
expanduserÚgetpassÚgetuserr:   )r   Úhomes   & r"   r`   r`   º   sb   € çÜ�:‰:�>‰>˜&×!Ò!Ü—:‘:˜fÕ%‰Dä—7‘7×%Ñ% c¬G¯OªOÓ,=Õ&=Ó>ˆDä�w‰w�|‰|˜D &Ð*;Ó<ˆØ€Kr$   c                óT   € RP                  V ^ ,          V ^,          V R,          .4      # )z/
Build a string that uniquely identifies a key
r0   éÿÿÿÿ)r:   )rg   s   &r"   Úfp_tupler{   Æ   s&   € ð �8‰8�R˜•U˜B˜q�E 2 b¥6Ð*Ó+Ð+r$   c                óâ   € . pV  F@  p\        VP                  4       4      pV'       g   K&  VP                  \        V4      4       KB  	  \        P
                  ! RRP                  V4      4       V# )z+
Return a list of uniquely identified keys
z"Already have SSH public keys: [%s]r0   )rN   r@   r7   r{   r&   Údebugr:   )rk   Úkeysrm   Ússh_fps   &   r"   Úkey_listr€   Ð   sW   € ð
 €DÛˆÜ  §¡£Ó.ˆß‰6Ø�K‰Kœ Ó(Ö)ñ ô ‡M‚MÐ6¸¿¹À»ÔGØ€Kr$   c                ór   € V R8X  d   \        W4      # V R8X  d   \        W4      # \        RV ,          4       R# )zH
Call out to a subcommand to handle the specified protocol and username
r	   Úghz>ssh-import-id protocol handler %s: not found or cannot executeN)Úfetch_keys_lpÚfetch_keys_ghr+   )ÚprotoÚusernameÚ	useragents   &&&r"   Ú
fetch_keysrˆ   Þ   s;   € ð �„}Ü˜XÓ1Ð1Ø�„}Ü˜XÓ1Ð1äÐHØ	õ	ö r$   c                óx  € \        \        4       4      p. p. pRV : RV: 2p\        WV4      P                  R4       Fí  pVP	                  4       pVP                  4       pVP                  V4       \        V4      p	V	'       g   KI  \        V	4      V9   d<   \        P                  ! RV	R,          V	R
R ,           4       VP                  V4       K”  VP                  RP                  V4      4       VP                  V4       \        P                  ! RV	R,          V	R
R ,           4       Kï  	  \        VR	4       V# )zN
Import keys from service at 'proto' for 'username', appending to output
file
ú# ssh-import-id Ú:r1   zAlready authorized %sºNé   NNr0   zAuthorized key %súa+rz   )r€   rh   rˆ   r@   rC   r7   rN   r{   r&   Úinfor:   rn   )
r…   r†   r‡   Ú
local_keysÚresultrk   Úcomment_stringrm   rD   r   s
   &&&       r"   Úimport_keysr“   ë   sþ   € ô œ,›.Ó)€Jà€FØ�MÛ05²xÐ@€NÜ˜5¨IÓ6×<Ñ<¸TÖBˆà�z‰z‹|ˆØ—‘“ˆØ�‰�nÔ%Ü  Ó(ˆß‰6Ü˜Ó :Ô-Ü—’Ø+¨V°B­Z¸&ÀÀ¸+Õ-EôGà—‘˜fÖ%à×$Ñ$ S§X¡X¨fÓ%5Ô6Ø—‘˜fÔ%Ü—’Ð0°&¸µ*¸vÀbÀc¸{Õ2JÖKñ Cô �- Ô&Ø€Mr$   c                óV  € RV : RV: R2p. p. p\        4        F  pVP                  V4      '       dU   \        VP                  4       4      p\        P
                  ! RVR,          VRR ,           4       VP                  V4       Kn  VP                  V4       K�  	  \        VR4       V# )	zF
Remove keys from the output file, if they were inserted by this tool
rŠ   r‹   r1   zRemoved labeled key %srŒ   Nr/   rz   )rh   ÚendswithrN   r@   r&   r�   r7   rn   )r…   r†   r’   Úupdate_linesÚremovedrm   r   s   &&     r"   Úremove_keysr˜   	  sŒ   � ó
 38»ÐB€NØ€LØ€GÜ–ˆØ�=‰=˜×(Ò(Ü$ T§Z¡Z£\Ó2ˆFÜ�LŠLÐ1°6¸"µ:ÀÀrÀsÀÕ3KÔLØ�N‰N˜4Ö à×Ñ Ö%ñ ô �, Ô$Ø€Nr$   c           	     óì  € R\         ,          pR\        P                  P                  \        P                  P                  \        P                  P
                  3,          pRP                  \        P                  ! 4       4      p\        P                  ! 4       ^ ,          : R\        P                  ! 4       ^,          : R\        P                  ! 4       ^,          : 2pV: RV: RV: RV: RV : 2	# )z'"
Construct a useful user agent string
zssh-import-id/%szpython/%d.%d.%dÚ/r0   )r   r(   Úversion_infoÚmajorÚminorÚmicror:   ÚdistroÚlinux_distributionr   Úuname)ÚextraÚssh_import_idÚpythonÚ
linux_distr¡   s   &    r"   Ú
user_agentr¦     s    € ð '¬Õ0€MØÜ×Ñ×Ñ¤× 0Ñ 0× 6Ñ 6¼×8HÑ8H×8NÑ8Nð"Põ P€Fà—‘œ&×3Ò3Ó5Ó6€JÜŸ(š(›* QŸ-˜-¬¯ª«°A¯¨¼¿º»
À1¿ÐF€EÛ,«f³jÃ%ÊÐOÐOr$   c           	     óV  € \         P                  ! RRRR7      pVP                  V ,          pVP                  '       g   \	        R4      hVP
                   Uu0 uF  qDP                  kK  	  ppRP                  V Uu. uF  p\        WA4      NK  	  up4      R,           pV# u upi u upi )ay  Fetch keys for all users in team 'lpid'.
Walk through the json response objects and recursively read sub-groups.

Uses public launchpad api described at
   https://launchpad.net/+apidoc/devel.html#team
devel is used so that 'account_status' attribute can be respected.
   to read https://api.launchpad.net/devel/~TEAM/members

If group does not exist a KeyError will be raised.r   Ú
productionÚdevel)Úversionz
Not a teamr1   )	r   Úlogin_anonymouslyÚpeopleÚis_teamÚKeyErrorÚmembersrR   r:   rƒ   )Úlpidr‡   r	   ÚteamÚmemberr¯   r~   s   &&     r"   Úfetch_keys_lp_teamr³   (  s‘   € ô 
×	$Ò	$ _°lÈGÔ	T€Bð �9‰9�T�?€DØ�<�<ˆ<Ü�|Ó$Ð$ð *.¯ªÓ6©˜v�{Œ{©€GÐ6ð �9‰9ÁWÓMÁW¸6”m FÖ6ÁWÑMÓNÐQUÕU€Dà€Kùò 7ùò Ns   ÁB!Á=B&c                 ó†  € R p\         p \        P                  ! RR4      pVfi   \        P                  P	                  V4      '       dD    \        V4      P                  4       p \        P                  ! T4      pTP                  RR4      pVf   TpV\        V 4      ,          pR\        V4      /p \        \!        WGR7      \"        R7      ;_uu_ 4       pVP                  4       P%                  R4      p	RRR4       X	'       g&   \0        P2                  ! RT4        \5        Y4      p	T	#  T	#   \         d    \        RT,          4      hi ; i  \         d    \        RT,          4      hi ; i  + '       g   i     L‚; i  \&        P(                  P*                   dE   p
R	pT
P,                  R
8X  d   Rp\/        TRT
P,                  T 3,          ,           4        Rp
?
LãRp
?
ii ; i  \6         d    p
\/        \9        T
4      4        Rp
?
T	# Rp
?
ii ; i  \         d    p
\/        \9        T
4      4        Rp
?
X	# Rp
?
ii ; i)z/etc/ssh/ssh_import_idÚURLNzFailed to read %sz File %s did not have valid JSON.ú
User-Agent©Úheaders©Útimeoutr3   z!Requesting Launchpad keys failed.é”  zLaunchpad user not found.ú status_code=%d user=%sz(ssh keys not found at %s, checking team.)ÚLAUNCHPAD_SSH_KEYS_URL_TMPLr   Úgetenvr   r   rQ   Úreadre   Ú	ExceptionÚjsonÚloadsr   rt   r   r¦   r   r   ÚDEFAULT_TIMEOUTrB   Úurllibr'   Ú	HTTPErrorÚcoder+   r&   r}   r³   r®   rA   )r°   r‡   Ú	conf_fileÚdef_tmplÚurlÚcontentsÚconfr¸   Úresponser~   Úer*   s   &&          r"   rƒ   rƒ   D  s   € Ø(€IÜ*€Hð)Ü�iŠi˜˜tÓ$ˆØŠ;œ2Ÿ7™7Ÿ>™>¨)×4Ò4ðAÜ 	›?×/Ñ/Ó1�ðDÜ—z’z (Ó+�ð —(‘(˜5 $Ó'ˆCàŠ;ØˆCà”Z Ó%Õ&ˆØ¤¨IÓ!6Ð7ˆð		BÜœ Ô6Ü!0÷2õ 2Ø5=Ø—}‘}“×-Ñ-¨gÓ6�÷2÷ Ü�MŠMÐDÀcÔJðÜ)¨$Ó:�ð €Kð ð €KøôK ô AÜÐ 3°iÕ ?Ó@Ð@ðAûô
 #ô DÜØ6¸ÕBóDð DðDú÷2÷ 2ûô �|‰|×%Ñ%ô 	BØ5ˆCà�v‰v˜Œ}Ø1�Ü�Ð/°1·6±6¸4°.Õ@Õ@×AÑAûð	Bûô ô Ü”C˜“F—�ð
 €Kûðûô ô ÜŒC�‹F�ˆØ€Kûðús¹   Š?H ÁD. Á%E Á;7H Â3#F Ã E0Ã6F Ã>H ÄH ÄG) Ä.EÅH ÅE-Å-H Å0F 	Å;F Å?H Æ F ÆG&Æ":G!ÇH Ç!G&Ç&H Ç)HÇ4HÈH ÈHÈH ÈI È!H;È;I c                 óÜ  € R pRpRp R\        V 4      ,          pR\        V4      /p \        \        WVR7      \        R7      ;_uu_ 4       p\
        P                  ! V4      pRRR4       X F%  pYKR,          : RT : RTR,          : R2,          pK'  	  T#   + '       g   i     L=; i  \        P                  P                   dv   p	Rp
T	P                  R	8X  d   R
T ,          p
M)T	P                  P                  T4      R8X  d
   RT,          p
\        T
RT	P                  T 3,          ,           4        Rp	?	LÏRp	?	ii ; i  \         d    p	\        \        T	4      4        Rp	?	T# Rp	?	ii ; i)zx-ratelimit-remainingz.https://developer.github.com/v3/#rate-limitingr   z$https://api.github.com/users/%s/keysr¶   r·   r¹   NzRequesting GitHub keys failed.r»   z&Username "%s" not found at GitHub API.Ú0z6GitHub REST API rate-limited this IP address. See %s .r¼   Úkeyr0   z@github/Úidr1   )r   r¦   r   r   rÃ   rÁ   ÚloadrÄ   r'   rÅ   rÆ   Úhdrsrt   r+   rÀ   rA   )Úghidr‡   Úx_ratelimit_remainingÚhelp_urlr~   rÉ   r¸   ÚrespÚdatarÍ   r*   Úkeyobjs   &&          r"   r„   r„   t  s;  € Ø3ÐØ?€HØ€DðØ4¼
À4Ó8HÕIˆØ¤¨IÓ!6Ð7ˆð	BÜœ Ô6Ü!0÷2õ 2Ø59Ü—y’y “�÷2ó ˆFØ°%¯=¨=»$ÀÀtÇÀÐMÕMŠDñ ð
 €K÷!2÷ 2ûô �|‰|×%Ñ%ô 	BØ2ˆCØ�v‰v˜Œ}Ø>ÀÕE‘Ø—‘—‘Ð1Ó2°cÔ9ØOØ!õ"�ä�Ð/°1·6±6¸4°.Õ@Õ@×AÑAûð	Bûô ô ÜŒC�‹F�ˆØ€Kûðúse   ˆE ¨#B* ÁBÁ"B* Á*+E ÂB'	Â"B* Â&E Â'B* Â*D>Ã	A+D9Ä4E Ä9D>Ä>E ÅE+ÅE&Å&E+c                  óª  € . p  \         P                  ! ^4       \        P                  4       \        n        . p\        P                  P
                   Fæ  pVP                  R4      p\        V4      ^8X  d   Vw  rEM*\        V4      ^8X  d	   \        TrTM\        RV,          4       \        P                  P                  '       d!   \        XX4      pVP                  V4       RpM8\        XX\        P                  P                  4      pVP                  V4       RpV'       d   KÕ  V P                  V4       Kè  	  \         P"                  ! R\        V4      X4       \)        4        V '       d"   \        RRP+                  V 4      ,          4       \,        P.                  ! ^ 4       R#   \$         d   p\        \'        T4      4        Rp?LoRp?ii ; i)	é   r‹   zInvalid user ID: [%s]ÚRemovedÚ
Authorizedz[%d] SSH keys [%s]NzNo matching keys found for [%s]Ú,)r   rX   ra   Ú
parse_argsrb   r   r@   r4   ÚDEFAULT_PROTOr+   Úremover˜   Úextendr“   r‡   r7   r&   r�   rÀ   rA   r#   r:   r(   r)   )	Úerrorsr~   ÚuseridÚuser_piecesr…   r†   Úchangesr   rÍ   s	            r"   Úmainrç   �  sR  € Ø€FðÜ
�Š�ŒÜ×*Ñ*Ó,ŒŒØˆÜ—n‘n×,Ô,ˆFØ Ÿ,™, sÓ+ˆKÜ�;Ó 1Ô$Ø"-‘��xÜ�[Ó! QÔ&Ü"/°‘xäÐ+¨vÕ6Ô7Ü�~‰~×$×$Ð$Ü% e¨XÓ6�Ø—‘˜GÔ$Ø"‘ä%Ø˜8¤V§^¡^×%=Ñ%=ó?�à—‘˜GÔ$Ø%�ß‘7Ø—‘˜fÖ%ñ% -ô& 	�ŠÐ)¬3¨t«9°fÔ=ô „IßÜÐ-°·±¸Ó0@Õ@ÔAÜ‡H‚HˆQ†Køô ô ÜŒC�‹F�‰ûðús%   „CF) ÃAF) Ä(6F) Æ)GÆ4GÇG)rŽ   )N)r   )4Úargparserv   rÁ   Újson.decoderr   ÚImportErrorÚ
ValueErrorr&   r   r;   r(   r5   Úurllib.errorrÄ   Úlaunchpadlib.launchpadr   Úurllib.parser   Úurllib.requestr   r   rŸ   rª   r   rÃ   rà   ÚbasicConfigÚINFOÚArgumentParserra   Úadd_argumentrb   r   r½   r#   r+   rN   rT   r]   rh   rn   r`   r{   r€   rˆ   r“   r˜   r¦   r³   rƒ   r„   rç   © r$   r"   Ú<module>rõ      s�  ðó( Û Û ð!Ý,ó Û 	Û Û 
Û Û Ý ,Ý #ß +ã å ð €ð €Ø × Ò ÐBØ!Ÿ,™,õ(à	×	 Ò	 ØKØ	ô
€ð × Ñ Øˆ*˜fØ	@ð ô Bð × Ñ Øˆ*˜\°5Ø	1ð ô 3ð × Ñ Øˆ- °bØ	/ð ô 1ð × Ñ Ø�S (Ø	ð ô ð €„Ø€	àBÐ òòòô@òBò,ò"$ô&	ò,òò
òò<ô&	Pòò8-ò`ô6 øðm ô !Ø ƒOð!ús   ŽD Ä	D,Ä+D,