#!/opt/thinlinc/libexec/python3
# -*-mode: python; coding: utf-8 -*-
#
# Copyright 2002-2014 Cendio AB.
# For more information, see http://www.cendio.com
#
# action: Mounting local drives
#
if 82 - 82: Iii1i
import sys
import threading
import os
import getopt
import stat
import base64
import hashlib
import subprocess
import time
import locale
if 87 - 87: Ii % i1i1i1111I . Oo / OooOoo * I1Ii1I1 - I1I
from thinlinc import hiveconf
import warnings
if 81 - 81: i1 + ooOOO / oOo0O00 * i1iiIII111 * IiIIii11Ii
if 84 - 84: ooo000 - Ooo0Ooo + iI1iII1I1I1i . IIiIIiIi11I1
warnings . filterwarnings ( "ignore" , ".*gssapi.*" , ImportWarning )
from thinlinc import rpc
from thinlinc . rpc import security
from thinlinc . mountclient import mount_const , mount_pack
if 98 - 98: I11iiIi11i1I % oOO
from thinlinc import sessioninfo
from thinlinc import prefix
if 31 - 31: i1I
i1I1 = 10
if 22 - 22: o00o0OO00O % I11iiIi11i1I - iI1iII1I1I1i
iiIi1 = False
if 71 - 71: i1 % Iii1i
class iiiIi ( rpc . ConnectionHandler ) :
 if 66 - 66: IIiIIiIi11I1 + I1I
 def __init__ ( self ) :
  super ( ) . __init__ ( )
  if 70 - 70: i1I * i1I
  oOooo0OOO = threading . Thread ( target = self . start , name = 'PollingThread' )
  oOooo0OOO . setDaemon ( True )
  oOooo0OOO . start ( )
  if 53 - 53: Ii * Oo * ooo000 . i1iiIII111
  self . default_cred = security . CredInfo ( )
  if 14 - 14: I1I / oOO
 def connect ( self , host , port ) :
  self . pipe = super ( ) . connect ( ( host , port ) )
  if 58 - 58: I1Ii1I1 - ooOOO
 def make_call ( self , proc , arg = b'' , arg_type = '' , result_type = '' ) :
  if arg and arg_type :
   oO0 = mount_pack . MOUNTPacker ( )
   i1iiiiIIIiIi = getattr ( oO0 , 'pack_%s' % arg_type )
   i1iiiiIIIiIi ( arg )
   arg = oO0 . get_buffer ( )
   if 22 - 22: ooo000 . iI1iII1I1I1i + Ooo0Ooo + oOO
  oOoo0 = self . pipe . send_call ( mount_const . MOUNT_PROGRAM ,
 mount_const . MOUNT_V3 ,
 proc , arg , self . default_cred )
  Iio0 , i1i = self . pipe . listen ( oOoo0 )
  if 87 - 87: Oo - i1I
  if i1i and result_type :
   iiI1111IIi1 = mount_pack . MOUNTUnpacker ( i1i )
   oOo00O = getattr ( iiI1111IIi1 , 'unpack_%s' % result_type )
   return oOo00O ( )
  else :
   return i1i
   if 59 - 59: Iii1i . o00o0OO00O - i1I
 def null ( self ) :
  self . make_call ( mount_const . MOUNTPROC3_NULL )
  if 13 - 13: oOO
 def mnt ( self , dirpath ) :
  return self . make_call ( mount_const . MOUNTPROC3_MNT ,
 arg = dirpath , arg_type = 'dirpath' ,
 result_type = 'mountres3' )
  if 28 - 28: OooOoo + i1i1i1111I + IiIIii11Ii / I1Ii1I1 + iI1iII1I1I1i
 def export ( self ) :
  return self . make_call ( mount_const . MOUNTPROC3_EXPORT ,
 result_type = 'exports' )
  if 70 - 70: o00o0OO00O + I11iiIi11i1I * oOO . Oo + ooOOO / Oo
  if 14 - 14: OooOoo % oOo0O00 + I1I % i1iiIII111 * ooOOO / I11iiIi11i1I
class OoOo :
 def __init__ ( self , host , port ) :
  if 43 - 43: ooOOO * I1Ii1I1
  if 95 - 95: Ooo0Ooo % Iii1i % i1i1i1111I . OooOoo
  if 70 - 70: IiIIii11Ii
  if 75 - 75: Ooo0Ooo / Ii / IiIIii11Ii + IiIIii11Ii . I1I
  if 88 - 88: Oo * IiIIii11Ii
  oooOo = None
  for I11iIi1i in range ( i1I1 ) :
   if iiIi1 :
    print ( "Connecting to %s:%d..." % ( host , port ) , file = sys . stderr )
   try :
    self . mountcl = iiiIi ( )
    self . mountcl . connect ( host , port )
    self . mountcl . null ( )
    if 49 - 49: IIiIIiIi11I1
    return
   except ( EOFError , OSError ) as iIIiii1iI :
    oooOo = iIIiii1iI
    if 43 - 43: ooOOO . I11iiIi11i1I + ooo000
   time . sleep ( 1 )
   if 87 - 87: Iii1i + ooOOO . i1I / Ii + Oo
   if 77 - 77: i1iiIII111 + o00o0OO00O - Oo % ooo000
  I1 = "Cannot connect to client: " + str ( oooOo ) + "\n"
  I1 += "This might be a client older than 1.3.2."
  sys . exit ( I1 )
  if 56 - 56: I11iiIi11i1I
 def get_otp ( self , password ) :
  Ii1I1I1i = self . mountcl . mnt ( b"@getnonce" )
  if 93 - 93: oOo0O00 % Ooo0Ooo * i1iiIII111
  if Ii1I1I1i . fhs_status != mount_const . MNT3_OK :
   print ( "Failed to get nonce:" , mount_const . mountstat3_id [ Ii1I1I1i . fhs_status ] , file = sys . stderr )
   sys . exit ( 1 )
   if 52 - 52: oOO + I1I / ooo000 - I1Ii1I1 * i1I % oOo0O00
  oOoO00 = Ii1I1I1i . mountinfo . fhandle
  OO0o0O0o0 = hashlib . md5 ( oOoO00 + password ) . hexdigest ( )
  return OO0o0O0o0
  if 11 - 11: o00o0OO00O % i1i1i1111I + i1
 def get_exports ( self ) :
  Ii1I1I1i = [ ]
  if 87 - 87: I1I / Iii1i / Ii
  if 32 - 32: i1i1i1111I % Ooo0Ooo - i1I * I1I
  if 92 - 92: IIiIIiIi11I1 - i1 - Iii1i / Ooo0Ooo . I1Ii1I1 / I11iiIi11i1I
  oooOoO0000 = self . mountcl . export ( )
  if 41 - 41: I11iiIi11i1I % oOO - I1Ii1I1 - IIiIIiIi11I1
  while oooOoO0000 :
   O0O0O = oooOoO0000 [ 0 ]
   Ii1IiIII1 = O0O0O . ex_dir
   Ii1I1I1i . append ( Ii1IiIII1 )
   oooOoO0000 = O0O0O . ex_next
   if 11 - 11: i1 / ooo000
  return Ii1I1I1i
  if 89 - 89: I1I * i1i1i1111I
  if 54 - 54: oOO + Ooo0Ooo - I1I . Ooo0Ooo
 def gen_drive_names ( self , exports ) :
  Ii1I1I1i = { }
  if 50 - 50: Iii1i * ooo000 % Iii1i - oOo0O00 + ooo000
  if 54 - 54: oOO * i1 % i1 - Ooo0Ooo + IIiIIiIi11I1
  if 4 - 4: ooo000 + I1Ii1I1 * OooOoo - o00o0OO00O
  if 69 - 69: ooo000
  if 76 - 76: Iii1i * Ooo0Ooo . iI1iII1I1I1i / Ii / ooOOO
  OOOOO = 0
  for Ii1IiIII1 in exports :
   if 36 - 36: i1i1i1111I + Iii1i - oOO * Ii
   if Ii1IiIII1 . endswith ( b"/" ) :
    Ii1IiIII1 = Ii1IiIII1 [ : - 1 ]
    if 45 - 45: i1i1i1111I * Ii
    if 97 - 97: i1
    if 26 - 26: o00o0OO00O
    if 20 - 20: IIiIIiIi11I1 / Oo
    if 73 - 73: ooOOO - IiIIii11Ii
   iIi1 = Ii1IiIII1 . decode ( 'utf-8' , errors = 'replace' ) . encode ( sys . getfilesystemencoding ( ) ,
   # oOo0O00
 errors = 'replace' ) . decode ( sys . getfilesystemencoding ( ) )
   if 74 - 74: ooo000 - I1I * i1I . i1 * oOo0O00 . o00o0OO00O
   if 16 - 16: IiIIii11Ii . Ooo0Ooo % IiIIii11Ii * I11iiIi11i1I . i1iiIII111
   if 2 - 2: Oo - IiIIii11Ii - iI1iII1I1I1i * OooOoo
   o00O00OOO00OO , iIiI11 = os . path . split ( iIi1 )
   OO = iIiI11
   if OO not in Ii1I1I1i :
    if 42 - 42: I1I - IiIIii11Ii
    Ii1I1I1i [ OO ] = Ii1IiIII1
    continue
    if 34 - 34: o00o0OO00O + ooOOO * oOO
    if 2 - 2: i1i1i1111I / Ooo0Ooo / oOO - IIiIIiIi11I1 / IIiIIiIi11I1
   o00O00OOO00OO , iIiI11 = os . path . split ( o00O00OOO00OO )
   OO = iIiI11 + "_" + OO
   if OO not in Ii1I1I1i :
    Ii1I1I1i [ OO ] = Ii1IiIII1
    continue
    if 58 - 58: i1i1i1111I
    if 38 - 38: i1 - oOo0O00
   OO += str ( OOOOO )
   OOOOO += 1
   assert ( OO not in Ii1I1I1i )
   Ii1I1I1i [ OO ] = Ii1IiIII1
   if 85 - 85: IIiIIiIi11I1 + I11iiIi11i1I % Ooo0Ooo + oOO * i1iiIII111
  return Ii1I1I1i
  if 46 - 46: ooOOO - ooOOO + Oo / I1I * Oo + oOO
  if 98 - 98: I1I / IIiIIiIi11I1 / i1I + o00o0OO00O % Oo + I1I
def ooOo00o ( hive ) :
 try :
  if 36 - 36: Ii
  if 71 - 71: OooOoo * IIiIIiIi11I1 * Oo
  if 2 - 2: IIiIIiIi11I1 + iI1iII1I1I1i - I1Ii1I1 + ooOOO . IIiIIiIi11I1
  iIi111ii = sessioninfo . get_public_sessioninfo ( hive )
 except sessioninfo . GPSConnectionError as iIIiii1iI :
  print ( iIIiii1iI , file = sys . stderr )
  print ( "Trying to mount anyway" , file = sys . stderr )
  return { }
  if 20 - 20: i1i1i1111I + Oo / Ooo0Ooo % o00o0OO00O % o00o0OO00O
  if 29 - 29: iI1iII1I1I1i - oOo0O00 - Ooo0Ooo % i1I + o00o0OO00O
  if 8 - 8: Oo * I1I / i1i1i1111I + i1 / I1Ii1I1
 if 0 == len ( iIi111ii ) :
  print ( "No session information matching current environment." , file = sys . stderr )
  print ( "Trying to mount anyway" , file = sys . stderr )
  return { }
 elif 1 < len ( iIi111ii ) :
  print ( "Multiple sessions matching current information. Should not happen!" , file = sys . stderr )
  print ( "Trying to mount anyway" , file = sys . stderr )
  return { }
  if 71 - 71: I1Ii1I1
 iIi111ii = iIi111ii [ 0 ]
 if 1 - 1: o00o0OO00O - oOo0O00 - i1 . oOo0O00
 if "client_params" not in iIi111ii :
  print ( "No client_params found" , file = sys . stderr )
  return { }
  if 91 - 91: iI1iII1I1I1i * i1 . ooOOO
 I1i = iIi111ii [ "client_params" ]
 if "capabilities" not in I1i :
  if iiIi1 :
   print ( "Client doesn't support capabilities" , file = sys . stderr )
  return { }
  if 83 - 83: OooOoo + i1i1i1111I
 i111II = I1i [ "capabilities" ]
 if "localdrives" not in i111II :
  if iiIi1 :
   print ( "Client has no localdrives capability, exiting." , file = sys . stderr )
  sys . exit ( 1 )
  if 16 - 16: oOo0O00 * ooo000 * I11iiIi11i1I + oOO
 O0o = i111II [ "localdrives" ]
 if not isinstance ( O0o , dict ) :
  return { }
  if 56 - 56: o00o0OO00O + Iii1i + i1 . i1I * Iii1i % ooOOO
 return O0o . get ( "aliases" , { } )
 if 74 - 74: I1Ii1I1
 if 61 - 61: iI1iII1I1I1i * I1Ii1I1 + Ooo0Ooo % IIiIIiIi11I1 * i1i1i1111I
def OOO0ooOO ( ) :
 print ( "Usage:" , sys . argv [ 0 ] , "[-h] [-v]" , file = sys . stderr )
 print ( """
    -h    Display this help
    -v    Verbose mode
""" , file = sys . stderr )
 sys . exit ( 1 )
 if 89 - 89: ooo000 + Ii % i1i1i1111I - i1iiIII111
 if 33 - 33: ooo000 . Iii1i % oOO
def OoOOooO0oOO0Oo ( ) :
 locale . setlocale ( locale . LC_ALL , "" )
 if 4 - 4: i1 % I1Ii1I1 * oOO + oOO . i1i1i1111I - i1
 global TLPREFIX
 TLPREFIX = prefix . get_tl_prefix ( )
 if 15 - 15: OooOoo . oOo0O00 - ooOOO % Ooo0Ooo
 if 62 - 62: iI1iII1I1I1i / OooOoo % I1I - o00o0OO00O
 try :
  iII1Ii , O00OoO0OOO0 = getopt . getopt ( sys . argv [ 1 : ] , "hv" )
 except getopt . GetoptError :
  if 98 - 98: iI1iII1I1I1i - I1I + i1 * ooo000 % i1
  OOO0ooOO ( )
 for o0O0OO0 , Iioo0Oo0oO0 in iII1Ii :
  if o0O0OO0 == "-h" :
   OOO0ooOO ( )
  if o0O0OO0 == "-v" :
   global iiIi1
   iiIi1 = True
 if O00OoO0OOO0 :
  OOO0ooOO ( )
  if 20 - 20: IIiIIiIi11I1
  if 34 - 34: ooo000 % i1i1i1111I * i1iiIII111
 prefix . assert_in_session ( )
 O0O0o0oo00Oo = prefix . get_tl_session_dir ( )
 if 96 - 96: Ooo0Ooo
 ii1IiiIiI = [ os . path . join ( TLPREFIX , "bin" , "tl-umount-localdrives" ) ]
 ii1IiiIiI . append ( "-l" )
 if iiIi1 :
  ii1IiiIiI . append ( "-v" )
  if 46 - 46: OooOoo - I11iiIi11i1I / Ooo0Ooo
 if iiIi1 :
  print ( "Calling tl-umount-localdrives to remove any stale mounts" , file = sys . stderr )
 subprocess . call ( ii1IiiIiI )
 if 73 - 73: I1Ii1I1 / i1i1i1111I / ooo000 % i1 % i1I - OooOoo
 if 30 - 30: ooOOO * ooOOO - Iii1i * iI1iII1I1I1i
 oOOOOOOoOOooO0O0 = hiveconf . open_hive ( os . path . join ( TLPREFIX , "etc" , "thinlinc.hconf" ) )
 if 38 - 38: Iii1i + ooo000 * Iii1i + Ii % IIiIIiIi11I1 % oOo0O00
 I1i1I = prefix . get_tl_sessnum ( O0O0o0oo00Oo )
 i1iIIi1I1iiI = sessioninfo . get_tunnel_port ( oOOOOOOoOOooO0O0 , I1i1I , "nfs" )
 if 42 - 42: I1Ii1I1 - OooOoo / IiIIii11Ii % I11iiIi11i1I % I1Ii1I1 + ooOOO
 if 62 - 62: i1iiIII111 * iI1iII1I1I1i . i1i1i1111I
 if not os . path . exists ( O0O0o0oo00Oo ) :
  sys . exit ( O0O0o0oo00Oo + " does not exist. Quitting." )
  if 19 - 19: ooo000 * oOO
 if os . stat ( O0O0o0oo00Oo ) [ stat . ST_UID ] != os . getuid ( ) :
  sys . exit ( O0O0o0oo00Oo + " is not owned by you. Quitting." )
  if 47 - 47: ooo000
  if 2 - 2: Oo % IiIIii11Ii - ooOOO
 O0oo0O0o0o0O0O = ooOo00o ( oOOOOOOoOOooO0O0 )
 if 84 - 84: OooOoo . Ii . IIiIIiIi11I1 + Oo
 if 13 - 13: OooOoo % ooo000
 if 59 - 59: oOO * i1I - OooOoo
 if 54 - 54: IIiIIiIi11I1 . Ooo0Ooo % Ii + IiIIii11Ii * iI1iII1I1I1i / iI1iII1I1I1i
 if 31 - 31: IiIIii11Ii . IiIIii11Ii % Ii
 OoOo0 = os . path . join ( O0O0o0oo00Oo , "vncpasswd" )
 with open ( OoOo0 , 'rb' ) as iI :
  iii1i1iiIi1 = base64 . encodebytes ( iI . read ( ) [ : 8 ] )
  if 1 - 1: OooOoo / ooOOO % I1Ii1I1
 iii1i1iiIi1 = iii1i1iiIi1 [ : - 1 ]
 del OoOo0
 if 15 - 15: OooOoo . IiIIii11Ii . i1I / Iii1i + ooOOO / Ii
 if 17 - 17: I11iiIi11i1I - i1i1i1111I . iI1iII1I1I1i - I11iiIi11i1I + Oo % iI1iII1I1I1i
 if 65 - 65: Ii % I11iiIi11i1I
 if 39 - 39: Iii1i * IIiIIiIi11I1 . Ooo0Ooo - Oo
 OoO = os . path . join ( O0O0o0oo00Oo , "drives" )
 if not os . path . exists ( OoO ) :
  if iiIi1 :
   print ( "Creating" , OoO , file = sys . stderr )
  os . mkdir ( OoO , 0o755 )
  if 78 - 78: OooOoo . ooOOO
  if 80 - 80: oOO % i1iiIII111 * o00o0OO00O - oOo0O00 % I11iiIi11i1I - o00o0OO00O
 oo0000oOOoOOO = os . path . join ( os . path . expanduser ( "~" ) , "thindrives" )
 if os . path . islink ( oo0000oOOoOOO ) :
  os . unlink ( oo0000oOOoOOO )
  os . symlink ( OoO , oo0000oOOoOOO )
 elif os . path . exists ( oo0000oOOoOOO ) :
  print ( "Cannot create link" , oo0000oOOoOOO , file = sys . stderr )
 else :
  if 52 - 52: Oo * Ooo0Ooo + ooOOO + IiIIii11Ii
  os . symlink ( OoO , oo0000oOOoOOO )
  if 20 - 20: i1i1i1111I - i1i1i1111I . Ooo0Ooo . IiIIii11Ii . oOO / Ii
  if 76 - 76: i1iiIII111 % Oo * IiIIii11Ii - Ooo0Ooo * Ii
 Oo00oo0 = oOOOOOOoOOooO0O0 . get_string_list ( "/utils/tl-mount-localdrives/mount_args" ,
 [ "-o" , "soft,intr,actimeo=2,rsize=524288,wsize=524288,timeo=50,retrans=1" ] )
 if 62 - 62: IiIIii11Ii . oOO
 if 48 - 48: ooOOO
 if 74 - 74: oOO - o00o0OO00O
 if 79 - 79: oOO * o00o0OO00O . ooOOO * I1Ii1I1 . oOo0O00 + i1iiIII111
 oo00 = OoOo ( "127.0.0.1" , i1iIIi1I1iiI )
 if 52 - 52: OooOoo
 i1iIIIIiII1I1 = oo00 . gen_drive_names ( oo00 . get_exports ( ) )
 for ( OO , Ii1IiIII1 ) in i1iIIIIiII1I1 . items ( ) :
  OO = O0oo0O0o0o0O0O . get ( OO , OO )
  ii1i = os . path . join ( OoO , OO )
  if not os . path . exists ( ii1i ) :
   if iiIi1 :
    print ( "Creating" , ii1i , file = sys . stderr )
   try :
    os . mkdir ( ii1i , 0o755 )
   except FileExistsError :
    pass
   except OSError as iIIiii1iI :
    sys . exit ( "Unable to create %s: %s, exiting" % ( ii1i , str ( iIIiii1iI ) ) )
    if 87 - 87: ooOOO
    if 57 - 57: IIiIIiIi11I1 - iI1iII1I1I1i % ooOOO - I11iiIi11i1I / IiIIii11Ii . Ooo0Ooo
  I11I11IiiI1i = [ ]
  I11I11IiiI1i . append ( os . path . join ( TLPREFIX , "libexec" , "tl-mount-personal" ) )
  if 1 - 1: I1I + OooOoo
  if 98 - 98: i1iiIII111 + Iii1i . IIiIIiIi11I1
  oO00 = "mountport=%d,port=%d" % ( i1iIIi1I1iiI , i1iIIi1I1iiI )
  I11I11IiiI1i . append ( "-o" )
  I11I11IiiI1i . append ( oO00 )
  if 30 - 30: IiIIii11Ii % ooo000 . Ii * Iii1i - iI1iII1I1I1i
  if 10 - 10: Ooo0Ooo % ooo000 % Ooo0Ooo
  I11I11IiiI1i . extend ( Oo00oo0 )
  if 38 - 38: ooo000
  if 3 - 3: o00o0OO00O / IiIIii11Ii - i1i1i1111I
  oO0O0 = oo00 . get_otp ( iii1i1iiIi1 ) . encode ( 'utf-8' )
  I11I11IiiI1i . append ( b"localhost:@otp:" + oO0O0 + Ii1IiIII1 )
  if 11 - 11: i1iiIII111 + i1iiIII111 / i1i1i1111I / I11iiIi11i1I
  if 82 - 82: I11iiIi11i1I
  I11I11IiiI1i . append ( ii1i )
  if 66 - 66: IiIIii11Ii + OooOoo
  if iiIi1 :
   print ( "Running" , I11I11IiiI1i , file = sys . stderr )
   if 31 - 31: OooOoo
  with subprocess . Popen ( I11I11IiiI1i , universal_newlines = True ,
 stdin = subprocess . PIPE ,
 stdout = subprocess . PIPE ,
 stderr = subprocess . STDOUT ) as o0o0 :
   o0o0 . wait ( )
   iII11I11111I = o0o0 . stdout . read ( )
   if 81 - 81: iI1iII1I1I1i / IIiIIiIi11I1 . iI1iII1I1I1i
  if iII11I11111I :
   print ( iII11I11111I , file = sys . stderr )
   if 81 - 81: i1I + IiIIii11Ii . I11iiIi11i1I
   if 10 - 10: iI1iII1I1I1i - Ii . IiIIii11Ii
if __name__ == "__main__" :
 OoOOooO0oOO0Oo ( )
# dd678faae9ac167bc83abf78e5cb2f3f0688d3a3
