JFIFxxC      C  " }!1AQa"q2#BR$3br %&'()*456789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz w!1AQaq"2B #3Rbr Fc LddlmZddlZddlZddlZddlZddlZddlZddl Z dZ iZ dZ d%dZ d%dZdZdZd Zd Zd Zd Zd&d Zd&dZd'dZdZd(dZdZdZdZd(dZd%dZd%dZd(dZ d)dZ!ddddddgfdZ"dddddddgfdZ#dZ$d*dZ%dZ&d Z'd!Z(d%d"Z)d#Z*d$Z+y)+)print_functionNicrtj|d}|tj|xt|<}|S)N) statcachegetoslstat)pathrets /usr/share/jailkit/jk_lib.py cachedlstatr 0s2}}T4 K((4.()D/C c t|}tj dddk(ro|t jdk7s3|t jtjdjk7rxtjj d|zd zy|t jdk7s|t jdk7r&tjj d|zd zy|t jt jzs$|t jt jzrLt j|t js&tjj d|zd zy t j |t jst j|t jrdt#j$|}t't)|t)|z|dd dk7r&tjj d|zdzyytjj d|zdzyy#t$r-|dk(r%tjj d|zdzYywxYw)NrzERROR: cannot lstat()  bsdwheelzERROR: z is not owned by root:wheel! z is not owned by root:root! z is writable by group or others!zusr/z2 is a symlink, please point to the real directory z is not a directory! )r OSErrorsysstderrwriteplatformstatST_UIDST_GIDgrpgetgrnamgr_gidST_MODES_IWOTHS_IWGRPS_ISLNKS_ISDIRrreadlinkprintstr)r failquietstatbuftargets r path_is_safer.Bs  '  \\"#% dkka74;;#73<<;P;W;W#W::IdN#CCD  dkka74;;#71#<::IdN#BBC  dlldll*gdll.Cdll.R[_[g[ghoptp|p|h}[~**9T>"DDE gdll+ , ll74<<() KK 6Vs4y ! bqzVJJYt^$YYZ  ::IdN#;;<  7  1n::,T1$67  s I3JJcdtjj|}t||}|dkr|SdD]}t|dz|zd}|dks|cStjj |}|dk7r8t|d}|dk7r|Stjj |}|dk7r8y)z]tests if path is a safe jail, not writable, no writable /etc/ and /lib, return 1 if all is OKr)etcusrvarbindevprocsbinr/rr)rr abspathr.dirname)r r+retvalsubdnpaths r chroot_is_safer=bs  tI & b[ - >T S a (& rk =    a & k = ''//% %   r ct|}|tjtjtjzzryy)zAreturns 1 if the file is setuid or setgid, returns 0 if it is notrr)r rr#S_ISUIDS_ISGID)r r,s r test_suid_sgidrAvs0 t  T\\dllT\\9:  r ctjdddk(r*t|dddddtjd|zyy)Nlinuxz/etcrcopy_permissions allow_suidcopy_ownershipz ldconfig -r )rrcreate_parent_pathrsystem)jails r gen_library_cacherL}s>\\"1 T&!aAVWX))N4  !r cg}tjd|zdtjtjtjd}|jj }t j dkDr"t|tr|jdd}t|dkDr|j}t|dkDr|ddk(r |d d k(r|S|dd k(r|d d k(r |ddk(r|S|ddk(s|ddk(rnt|dk(r|d d k(r |ddk(rnt|dk\rDtjj|d r ||d gz }ntd|d zdz|znzt|d k\rI|dddk(r>tjj|dr ||dgz }n5td|dzn#td|ddzntd|ddz|jj }t j dkDr"t|tr|jdd}t|dkDr|S);returns a list of libraries that the executable depends on ldd Tshellstdinstdoutr close_fdsrutf-8replacer staticallyrlinkednotdynamicrV executablezlinux-gate.so.1zlinux-vdso.so.1rfound!ldd returns non existing library z for r7$WARNING: failed to parse ldd output Nr subprocessPopenPIPErSreadliner version_info isinstancebytesdecodelensplitrr existsr)r^r:plinesubls r lddlist_libraries_linuxrrs/ fZ't:??S]SbSbkukzkzGKL v*T5"9 Wi ($ D ! $ $ik Aw,47h#6 M aE d1g2tAw,7N M a% %a4E)E TA$q'U*tAw'/A TA tAw QyV .tAw 6w >z IJ TA$q'!*+ tAw QyV .tAw 67 0cr :; /Sb 9:    $:dE#: ++gy )4= D ! > r c4g}d}tjd|zdtjtjtjd}|jj }t j dkDr"t|tr|jdd}t|dkDrm|j}t|dkDr|d|d zk(rn|dd k(rt|d k(r |d d k(rd}nt|dk\r|dk(r>tjj|dr ||dgz }ntd|dznr|dk(r>tjj|d r ||d gz }nAtd|d zn/tdn#td|ddzntd|ddz|jj }t j dkDr"t|tr|jdd}t|dkDrm|S)rNrVrOTrPrUrWrXr:StartNamerrCr`z1unknown mode, please report this bug in jk_lib.pyraNrrb)r^r:moderorprqs r lddlist_libraries_openbsdrzs  fZ't:??S]SbSbkukzkzGKL v*T5"9 Wi ($ D ! $ $ik Aw*S.  aG  D 1 aF* T TA  Q  a f /Q 78 !) Q  a f /Q 78 >? 0cr :; /Sb 9:    $:dE#: ++gy )4; D ! < r cg}tjd|zdtjtjtjd}|jj }t j dkDr"t|tr|jdd}t|dkDrS|j}t|dkDrt|dk(r|dd t|dz|d zk(rnt|d k\r|d d k(r |ddk(r|St|dk\r>tjj|d r ||d gz }nStd|d znAtd|d dzdzn,|d t|dz|d zk(rntd|d dzdz|jj }t j dkDr"t|tr|jdd}t|dkDrS|S)rNrOTrPrUrWrXrrNrtrwr\r[rr]r`z%WARNING: failed to parse ldd output "r"rbrns r lddlist_libraries_freebsdr}s fZ't:??S]SbSbkukzkzGKL v*T5"9 Wi ($ D ! $ $ik 4y!|Q 2Z!23z#~E TA$q'U*tAw)/C M TA tAw QyV .tAw 67 1$s) ;C ?@ c*oa JsN2 0cr :3 >?    $:dE#: ++gy )4+ D ! , r cBtjdddk(r t|Stjdddk(r t|Stjdddk(r t |Stjdddk(rt|}|dgz }|St|}|gdz }|S) NrCrDrvopenbsdfreebsdsunosz /lib/ld.so.1)z/usr/libexec/ld.soz/usr/libexec/ld-elf.so.1z/libexec/ld-elf.so.1)rrrrrzr})r^r:s r lddlist_librariesrs\\"1  ,, ||BQ9$ ": .. ||BQ9$ ": .. ||BQ7" ": .&^ & - ": .& TT& -r c|dk(ryt|}d}|s |d}|dd}d}d}|D]>}tjj||}t |}t j |jsO|dz }tj|} | ddk(r#tjj|| z}tjjtjjtjj|| } t|dkDrA| dt||k7r0tjjd| zdztd| }Atjj||S) Nr7rrrERROR: symlink  points outside jail, ABORT Symlink points outside jail) split_pathrr joinr rr&st_moder(normpathr9rkrrr Exception) r chroot include_filespathbasenamer doscounterentrysbrealpathtmps r resolve_realpathrsG 3Y D    2Y( *%  U  S#3" ll2:: q=:kk#8{C ''  6(? +C ''  277<<(tjj|}tjj |}d}|dk7rQ|dk7rKt |}t j|jr|dz }tj|}|ddk(r||z}|dddk(r|dd}ntjjtjjtjj ||} |dkDr8| d||k7r0tjjd| zd ztd | }nDtjj|dz|z}tjj |}d}|dk7r|dk7rKd|zS) zNwill return the same path that contains not a single symlink directory elementrrr7drrNrrr)rkrr rr9r rr&rr(rrrrrr) r rr chrootlendonepathtodopathrrrrs r OLDresolve_realpathr&st v; ( ( WW  d #( WW__T "( CJ#-8" ll2:: ?:kk(#8{ChH s" X ''  277<<(A(K LC! JY/ZZ'+,KKL 2 33 Hggx(,X58ggooh'8 "' CJ#-( H r cDtj|}tj|tj}|sX|tjtj zzr4t d|z|tjztj z}tj||tj|tjf|r9tj||tj|tjtj||y)Nz,removing setuid and setgid permissions from )rrS_IMODEr#r?r@r)utimeST_ATIMEST_MTIMEchownrrchmod)srcdst be_verboserGrHsbufrys r copy_time_and_permissionsrFs   T$,,'(  dllT\\)* 7 ;< 4<<- DLL= 04#T]]#T$--%89:((3T[[!4 #45#tr c|}tjj|sS|dk(sN|dk(sItjj|}tjj|s |dk(s|dk(sI|S)zsThis function tests if a directory exists, if not tries the parent etc. etc. until it finds a directory that existsr7r)rr rmr9)r rs r !OLDreturn_existing_base_directoryr[sX  GGNN3 sBw # GGNN3 sBw r rcf|}|dddk(r|dd} t||z|}tjj|ry t ||z}t |t |z } |jd| dz} | dk(r t |} | dk7r| dz| k(r| } nC t|d| } tj| jrtj |d| }t||d| z|}|rt#d|zd z|z tj$|||d dk(rt'||||||nt)j*|d| d}t'||d|dz|z||||nptj,| jrQt||d| z|}|rt#d |ztj.|t0|r t3|d| ||||| } | t |k(rd} n%|jd| dz} | dk(r t |} | dk7ryy#t$rYwxYw#t$rG} | j\} }tjjd|d| zdz|zdzYd} ~ yd} ~ wwxYw#t$rK} | j\}} |d k(rn+tjjd |z|d| zdzYd} ~ d} ~ wwxYw#t$rN} | j\} }tjjd|d| zd z|zdz|zdzYd} ~ Md} ~ wwxYw)zucreates the directory and all its parents id needed. copy_ownership can only be used if copy permissions is also usedrNr7rERROR: failed to lstat():rCreating symlink  to z ERROR: failed to create symlink rzCreating directory 2ERROR: failed to copy time/permissions/owner from : )rrr rmrreturn_existing_base_directoryrkfindr argsrrrrr&rr(r)symlinkrIstringrfindr'mkdirdir_moder)rr rrFrGrH directorychrootdirectoryroldindxindxre_strerrorrealfile chrootnameerrnoindx2s r OLD_create_parent_pathrbsd rs^sn)$VI%5f=/ggnn_% &&fY&67 s8CK s719% RZ 9~$   qjD 7 Yu% &B  ||BJJ{{9Ud+,H!&5D)9"9&AJ z )& 0 9:YZZ*%  S*6F Tbc \\)ET*3 /U (57 3H 93h 5 5   r c g}ttjj|}|dk7rT|j dtjj |tjj |}|dk7rT|S)Nr7r)rrr rinsertrr9)r r nexts r rrsf ))$/0  **Qrww%& wwt$   r cFt|dk(ryd}|D] }|d|zz } |S)Nrr7r)rk)rr rs r join_pathrs7Z]  UU# r ct|}|}d}|t|krtjj |||} tjj | snCt | |d} tjj | sn| }|dz }|t|kr|t|krt|d|dz} tjj |||} t| } tj| j r?|rt#d| ztj$| t&|rS t)| | |||nAtj0| j r!tj2| }|rt#d | zdz|ztj4|| |dd k(rt7||||||} ntjj9tjj tjj;| |} t|dkDrA| dt||k7r0tjjd | zd zt=d| t|d}t7||||||} | }|dz }|t|kr|S#t$rD}|j\}}tjjd| zdz|zdzYd}~yd}~wwxYw#t$rY}|j\}}tjjdt*dt,zdzt.zd z|zdzYd}~d}~wwxYw)NrrrrrzCreate directory rrrrr7rrr)rrkrr rrmrrr rrrrrrr'rr)rrrrrrr&r(rrIrr9r)rr rrFrGrHr existpathrtmp1rorigpathjailpathrrrrrs r rIrIs D   #e* ia )$  fQ'#  )Q$! #e*  #e* uQqs| $( WW\\)E!H -(H2  ll2:: h &'88HhBx:z>Z RZZ kk(#8 h &v -h 67::hx {C!&(:?OQ[]klH ''  277<<(A(K LC F A #ls6{+V3ZZ'+,KKL 2 333v;< H!&(:?OQ[]klH)Q$!K #e* L A ;1h::-h6t;HDTIJ  B66[QZZJ9UZVZK[[\bbcmmnrrs{{}AABBBs1( J+K;+ K84:K33K8; MAMMc H |rtd|ztj|t|||ddtj|D]\}}}|D]c} |r td |zd z| zdz|zd z| z tj|d z| z|d z| zt|d z| z|d z| z|dde|D]} t|d z| z|d z| z|y#tt f$rJ}|j \}}tjjd|zdz|zdz|zdzYd}~yd}~wwxYw#tt f$rX}|j \}}tjjd |zd z| zdz|zd z| zdz|zdzYd}~yd}~wwxYw) NzCreating directoryrrrGrHz)ERROR: copying directory and permissions rrrCopying r7$ERROR: copying file and permissions )r)rrrIOErrorrrrrrwalkshutilcopyfile#move_dir_with_permissions_and_owner) srcdirdstdirrrrrrootdirsfilesnames r #copy_dir_with_permissions_and_ownerrs  f $%((6FFJ1UVW ''&/ QT4  d *T/# d "6 )& 0 4T 9:  OODHTM&*T/2d3htmVCZ_jUVghi  Qd&tCx}VCZ_ZPQ Q # ' +!X**>vEfLVSTXXYaabffg   7  &&KAxJJ;D@DTI&PQWWX[[\``aeefnnosst  s15C;>D:D7-AD22D7:F! A FF!cPt|||}|dk(r*|dk(rtd|z tj|ytd|zdz|zy#tt f$rD}|j \}}tjjd|zdz|zdzYd}~yd}~wwxYw)Nrz!Removing original home directory zERROR: failed to remove rrzNot everything was copied to z, keeping the old directory ) rr)rrmtreerrrrrr)rrrr:rrrs r rrs -fVJ G q[!m ,V 34J == './MMfTU 7 J;1h::.v5d:8CDHIIJsAB%!:B  B%cd}|dk(r tj||d}|dk(r( tj||t |||||y y #td|zdz|zdzYIxYw#t tf$rJ}|j\}} tjjd|zdz|zdz| zd zYd }~y d }~wwxYw) zXcopies/links the file and the permissions (and possibly ownership and setuid/setgid bitsrrzLinking rz failed, will revert to copyingrrrrN) rlinkr)rrrrrrrrr) rrr try_hardlinkrG retain_ownerdo_normal_copyrrrs r copy_with_permissionsr)s1_773s>q^ ??3sS#zjYefC s "#D DE 7 ^;1h:::3>vEcI$NxWX\\]]^s#A&A-A*-Cc "d} tj|D]} tjj|| } t | } t j | jr%t|| |d||t|| ||||||| }n$| tjj|| fz } t|| ||||||| }|S#t$r?} tjjd| zdz| jzdzYd} ~ d} ~ wwxYw)zbcopies a directory and the permissions recursively, possibly with ownership and setuid/setgid bitsrr)rrFrGrH)ERROR: failed to investigate source file rrN)rlistdirr rr rr'rrIcopy_dir_recursiverrrrrcopy_binaries_and_libs)rdirforce_overwriter check_libsrrGr handledfilesfiles2rrrrs r rrcs* jjo ZU  S% #Z c 4 ||DLL!vszAZdvBC%fS*jZfhruACOPL bggll3&''F Z'vf_jR\^jlvyEGST Z::?CDHSTXXYYZsA3C D5D  Dc  |ddk(r|dd}|D]e} | | vr t| } t|tjj| |d||ttjj!|dz| z|} t|}d}|dk(r6r4t#j$j&s|st d|zdzr|rzt#j(j&r*|rt d|zdz tj*|nft#j$|j&rGt d|zdzn5t#j$j&rn|rt d|zdznt|tjj| |d||t#j,| j&rtj.| }|r)|rt d|zdz tj*| t d|zdz|ztj0||| j3| |ddk7rZtjj!tjj5tjj| |}t ||g||||||| } nt#j$| j&rt7|| ||||||| } nt#j(| j&rM|rt d| zdz|znt d| zdz|zt9| |||||| j3| nrt#j:| j&st#j<| j&rt?|| ||n%tjjd| zdzt#j@| t"jB}|s| jEd dk7sK| jEd!dk7s7|t"jFt"jHzt"jJzzsItM| }t ||||d|| "} h| S#t$r} | jdk(re|dk(rLtj| } t | dkDrt || |||||d|  } n]|r[t d| zd znI|rGt d | zd zn5tjjd | zd z| jzdzYd} ~ #d} ~ wwxYw#t$rU} | jdk(rd}n8tjjd|z| zd z| jzdzYd} ~ d} ~ wwxYw#t$rF} tjjd|zd z| jzdz|zdzYd} ~ hd} ~ wwxYw#t$rF} tjjd|zd z| jzdz|zdzYd} ~ -d} ~ wwxYw#t$rYwxYw)#z>copies a list of executables and their libraries to the chrootrr7Nr\rr)rrtry_glob_matchingrzSource file(s) z do not existz Source file z does not existrrrrEz.ERROR: failed to investigate destination file rz" already exists, will not touch itzDestination file z$ exists, will delete to force updatezERROR: failed to delete z cannot force update zDestination dir z existszDestination symlink rrzTrying to link rzFailed to find how to copy z= into a chroot jail, please report to the Jailkit developers libz.so)r)'r rrglobrkrr)rrrrrIrr r9rrrr'rS_ISREGunlinkr&r(rappendrrrrrrrr#rS_IXUSRS_IXGRPS_IXOTHr)r binarieslistrrrrrGrr rfilerrr chrootrfilechrootsbchrootfile_existsrrylibss r rrs BZ3 #2;& aAT l  D2VBGGOOD1:PQ^hzFG !1!1&*T/!B6J+h+&8!!24<<HXHX;Y "[.= => h&& '   ,-S STz yy <<(( ) { *9 45 h&& '    ,Y 67fRWW__T2JQR_i{GH ||BJJ{{4 H  "; ./U UVyii   { *6 1( :;ZZ+&  s  bggood.CH!MNX)&8*oz[egsuBNP\]L bjj !%fT/:z[gisvBDPQL bjj ! T !& ( 45 :d?6 !+ -.${:|ZQ]^ bjj !T\\"**%=j,7JJ2478xxy ,,r$,,' (4tyy'2-51AR1GDTXT`T`cgcocoTorvr~r~T~L T "D)&$UVXdsALCaAD y   ww!|Q 99T?S S!+FC*V`o{KWkl{GHl  d "? 23  >$ 0 01JJ@EdJ1::UVZZ[   ( hww!|JJEfLTQRVVWXWaWaabffg h"z zz2;>tCAJJNOgghsstxxyyz. y jj1+=dB1::MNffgrrswwxxy    ss Q; T;V6W. *Y; T8B)T33T8; VA VV W+%;W&&W+. X=7;X88X= Y  Y cg}|j||r<|j||}|jdD]}||jgz }|S)zretrieves a comma separated option from the configparser and splits it into a list, returning an empty list if it does not exist,) has_optionrrlstrip) cfgparser sectionname optionnamer:inputstrrs r config_get_option_as_listr"sV +j1 ]];z 2( ^^C c ciik]6r cttdt|dz|z|tj|y)Nrr)r)rexit)exitnomessage usagefunctypes r clean_exitr)s+rtDy &r c t|d}|j}tjdkDr"t |t r|j dd}t|dkDr|jd}t||kDr|||k(r|jy|j}tjdkDr"t |t r|j dd}t|dkDry#YyxYw)NrrrUrWrXrtr) openrfrrgrhrirjrkrlclose)itemnumfilenamefdrppwstructs r test_numitem_existr3s  HS" v*T5"9 Wi ($ D ! ZZ_( (mchsmt388: $:dE#: ++gy )4 D !   s C..C2ct|d|SNrr3)user passwdfiles r test_user_existr9s4*--r ct|d|Sr5r6)group groupfiles r test_group_existr=s59--r c |ddk(r|dd}t|d|dddtjdddk(rvt|d zd j t|d zd j t|d zd j t|d zd j nt j j|d zst|d zd}n;t|d zd}|j}tjdkDr"t|tr|jdd}t|dkDr|jd}t|dk\rT|d|vs|d|vrF|rtd|dzdz|zd z |j!|d |j!|d|j}tjdkDr"t|tr|jdd}t|dkDr|j%ddt|dkDr-td d}|j}tjdkDr"t|tr|jdd}t|dkDr|jd}t|dk\rK|d|vs|d|vr=|j'||rtd|dzdz|zd z|d|vr ||dgz }|j}tjdkDr"t|tr|jdd}t|dkDr|j |j t j j|dzst|dzd}n;t|dzd}|j}tjdkDr"t|tr|jdd}t|dkDr|jd}t|dk\rT|d|vs|d|vrF|rtd|dzdz|zdz |j!|d |j!|d|j}tjdkDr"t|tr|jdd}t|dkDr|j%ddt|dkDrtdd}|j}tjdkDr"t|tr|jdd}t|dkDr|jd}t|dk\r;|d|vs|d|vr-|j'||rtd|dzdz|zdz|j}tjdkDr"t|tr|jdd}t|dkDr|j |j y#t"$rY~wxYw#t"$rYywxYw#t"$rYwxYw#t"$rYwxYw)Nrr7z/etc/rrErrvrz /etc/passwdaz /etc/spwd.dbz /etc/pwd.dbz/etc/master.passwdwzr+rUrWrXrtrVr\zuser z exists in r+z writing user rz /etc/groupzgroup zwriting group )rIrrr,r-rr isfilerfrgrhrirjrkrlr)remove ValueErrorseekr) rusersgroupsrfd2rpr2r1 groupstructs r init_passwd_and_grouprIs BZ3 #2;&F7Jqabc\\!A%vmC &&(vnS!'')vmC &&(v""3'--/ ''.. - . f]"3 '3 f]"4 (3 ,,.4 JtU$; ;;w *D d)A+zz#H H  1+ HQK5$8  WXa[  .v 5m CD  ||HQK   ||HQK  <<>D & Ze%< KK +T! d)A+"88Aa= %j1n ]32 ++-4 JtU$; ;;w *D d)A+zz#H H  1+ HQK5$8 iio  _Xa[ ( / 6} DEqkV# (1+v ;;=D & Ze%< KK +T d)A+88:))+ |+ , VL %# VL &# $:dE#: ++gy )4 T1C; ;! Q6 !{1~'?  H[^ #M 1& 8 EF  mmKN#  mmKN# ,,.4 JtU$; ;;w *D! T1"((1Q-[1_ L" $:dE#: ++gy )4 T1C; ;! Q6 !{1~'?YYt_  [^ +F 26 9, FG ++-4 JtU$; ;;w *D T1((*O      R        sH XX X0Y XX X-,X-0 X=<X= Y  Y ctjd}|jd}|D]b}tjj ||}tjj |sCtjj |cSy)NPATHrt)rgetenvrlr rrmr8)r0 search_pathpathsr joineds r find_file_in_pathrPxskyy    3  "T 77<<h '&WW^^F ''//& !!" r cg}|D];}|ddk(r|j|t|}|s+|j|=|S)Nrr7)rrP)rNpaths2rtmp2s r find_files_in_pathrTsM  S !fm == C 4  MM$  r )r)rr)rrr)rrrr)rr)ERROR), __future__ros.pathrrrrrr rcrrr r.r=rArLrrrzr}rrrrrrrrrrIrrrrrrr"r)r3r9r=rIrPrTrr r rXs@&     $ @ ( ! (T(TB #<@* BH   <| 6 V^$&HP34a^_lm|}MOBBCq]^mn{|LMabqsfP  (..a F  r