+
    \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,     77>>!IIaL     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      MM#IHHQKr$   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	63		5CHHV$%D 
  ""	tT8,Z__FK++D1MJIIh$$&MC.2
C

3qxx(..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    
 #~	wwwWW__W-

77>>*%%
J&
	ww}}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     &..//0G#~RWW^^G44 L	Ggs##r $
 L $#
 L  	G9W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     fnn334Kc!Dt

  &

  ( " 	

	;	'	'+$$%::<<GGDMGGFO & %$ 
($$$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77%%cGOO,=&=>Dww||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&     88RUBqE2b6*++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KK()  MM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 %sN   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M05x@N5I6<<TBzz|n% (6:-+VBZ&+-EGf%$$SXXf%56f%0&*vbc{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BNLG==(($TZZ\2FLL16":rs3KLNN4 %  ,$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     '0M 0 0 6 68H8H8N8N"P PF&3356J((*Q--A
1FE,fj%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     
	$	$_lG	TB 99T?D<<<|$$ *.6v{{G6 99WMW6mF6WMNQUUD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
?
LR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)iit$;277>>)44A	?//1Dzz(+ ((5$'C;CZ%&I!67		B6!02 25=}}--g62 MMDcJ)$: K  KK  A 3i ?@@A
 # D6BD DD2 2 ||%% 	B5Cvv}1/1664.@@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	?	LR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
48HII!67	B6!02 259yy2 F%==$tMMD 
 K!2 2 ||%% 	B2Cvv}>E12c9O!"/1664.@@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
**,nn,,F ,,s+K;1$"-x[!Q&"/x+v67~~$$$%eX6G$"%8V^^%=%=?G$%7f%% -& 	)3t9f= I-0@@AHHQK  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,