U ¨Ãq`”Lã@sddZddlZddlZddlZddlmZmZddlmZddl m Z m Z m Z m Z mZddlmZddlmZddlmZdd lmZmZmZmZdd lmZdd l mZmZmZmZm Z m!Z!m"Z"m#Z#m$Z$m%Z%m&Z&m'Z'm(Z(m)Z)m*Z*m+Z+m,Z,m-Z-m.Z.m/Z/m0Z0m1Z1m2Z2m3Z3m4Z4m5Z5m6Z6m7Z7m8Z8m9Z9m:Z:m;Z;mZ>m?Z?m@Z@eed œZAGd d„de eƒZBddlCmDZDdS)z Server-mode SFTP support. éN)Úmd5Úsha1)Úutil)ÚBaseSFTPÚMessageÚ SFTP_FAILUREÚSFTP_PERMISSION_DENIEDÚSFTP_NO_SUCH_FILE)ÚSFTPServerInterface)ÚSFTPAttributes)ÚDEBUG)ÚlongÚ string_typesÚ bytes_typesÚb)ÚSubsystemHandler)%Ú CMD_HANDLEÚ SFTP_DESCÚ CMD_STATUSÚSFTP_EOFÚCMD_NAMEÚSFTP_BAD_MESSAGEÚCMD_EXTENDED_REPLYÚSFTP_FLAG_READÚSFTP_FLAG_WRITEÚSFTP_FLAG_APPENDÚSFTP_FLAG_CREATEÚSFTP_FLAG_TRUNCÚSFTP_FLAG_EXCLÚ CMD_NAMESÚCMD_OPENÚ CMD_CLOSEÚSFTP_OKÚCMD_READÚCMD_DATAÚ CMD_WRITEÚ CMD_REMOVEÚ CMD_RENAMEÚ CMD_MKDIRÚ CMD_RMDIRÚ CMD_OPENDIRÚ CMD_READDIRÚCMD_STATÚ CMD_ATTRSÚ CMD_LSTATÚ CMD_FSTATÚ CMD_SETSTATÚ CMD_FSETSTATÚ CMD_READLINKÚ CMD_SYMLINKÚ CMD_REALPATHÚ CMD_EXTENDEDÚSFTP_OP_UNSUPPORTED)rrcsœeZdZdZefdd„Z‡fdd„Zdd„Z‡fdd „Ze d d „ƒZ e d d „ƒZ dd„Z d dd„Z d!dd„Zdd„Zdd„Zdd„Zdd„Zdd„Z‡ZS)"Ú SFTPServerzå Server-side SFTP subsystem support. Since this is a `.SubsystemHandler`, it can be (and is meant to be) set as the handler for ``"sftp"`` requests. Use `.Transport.set_subsystem_handler` to activate this class. cOsht |¡t ||||¡| ¡}t | ¡d¡|_| ¡|_ d|_ i|_ i|_ ||f|ž|Ž|_ dS)a The constructor for SFTPServer is meant to be called from within the `.Transport` as a subsystem handler. ``server`` and any additional parameters or keyword parameters are passed from the original call to `.Transport.set_subsystem_handler`. :param .Channel channel: channel passed from the `.Transport`. :param str name: name of the requested subsystem. :param .ServerInterface server: the server object associated with this channel and subsystem :param sftp_si: a subclass of `.SFTPServerInterface` to use for handling individual requests. z.sftpéN)rÚ__init__rZ get_transportrZ get_loggerZget_log_channelÚloggerZ get_hexdumpZ ultra_debugÚ next_handleÚ file_tableÚ folder_tableÚserver)ÚselfÚchannelÚnamer>Zsftp_siÚlargsÚkwargsÚ transport©rEú;/tmp/pip-target-nv4zd3e_/lib/python/paramiko/sftp_server.pyr9^s  zSFTPServer.__init__csftt|ƒtƒr>|D](}tt|ƒ |d|j ¡d|¡qn$tt|ƒ |d|j ¡d|¡dS)Nz[chan z] )Ú issubclassÚtypeÚlistÚsuperr7Ú_logÚsockÚget_name)r?ÚlevelÚmsgÚm©Ú __class__rErFrK€s ÿ ÿzSFTPServer._logc Cs8||_| td |¡¡| ¡|j ¡z| ¡\}}Wnltk r\| td¡YdSt k r¦}z.| tdt |ƒ¡| tt   ¡¡WY¢dSd}~XYnXt |ƒ}| ¡}z| |||¡Wq*t k r0}zF| tdt |ƒ¡| tt   ¡¡z| |t¡Wn YnXW5d}~XYq*Xq*dS)Nz#Started sftp server on channel {!r}zEOF -- end of sessionzException on channel: z Exception in server processing: )rLrKr ÚformatZ_send_server_versionr>Zsession_startedZ _read_packetÚEOFErrorÚ ExceptionÚstrrZ tb_stringsrÚget_intÚ_processÚ _send_statusr) r?rArDr@ÚtÚdataÚerOÚrequest_numberrErErFÚstart_subsystem‹s0  zSFTPServer.start_subsystemcsX|j ¡tt|ƒ ¡|j ¡D] }| ¡q"|j ¡D] }| ¡q:i|_i|_dS)N) r>Z session_endedrJr7Úfinish_subsystemr<ÚvaluesÚcloser=)r?ÚfrQrErFr_§s   zSFTPServer.finish_subsystemcCs.|tjkrtS|tjks"|tjkr&tStSdS)au Convert an errno value (as from an ``OSError`` or ``IOError``) into a standard SFTP result code. This is a convenience function for trapping exceptions in server code and returning an appropriate result. :param int e: an errno code, as from ``OSError.errno``. :return: an `int` SFTP error code like ``SFTP_NO_SUCH_FILE``. N)ÚerrnoÚEACCESrÚENOENTÚENOTDIRr r)r\rErErFÚ convert_errno³s zSFTPServer.convert_errnoc Cs”tjdkrB|j|j@r$t ||j¡|j|j@rBt ||j |j ¡|j|j @rbt  ||j |jf¡|j|j@rt|dƒ}| |j¡W5QRXdS)a: Change a file's attributes on the local filesystem. The contents of ``attr`` are used to change the permissions, owner, group ownership, and/or modification & access time of the file, depending on which attributes are present in ``attr``. This is meant to be a handy helper function for translating SFTP file requests into local file operations. :param str filename: name of the file to alter (should usually be an absolute path). :param .SFTPAttributes attr: attributes to change. Úwin32zw+N)ÚsysÚplatformÚ_flagsZFLAG_PERMISSIONSÚosÚchmodÚst_modeZ FLAG_UIDGIDÚchownÚst_uidÚst_gidZ FLAG_AMTIMEÚutimeÚst_atimeÚst_mtimeZ FLAG_SIZEÚopenÚtruncateÚst_size)ÚfilenameÚattrrbrErErFÚ set_file_attrÆs      zSFTPServer.set_file_attrcGsœtƒ}| |¡|D]v}t|tƒr.| |¡qt|tƒrD| |¡qt|ttfƒr^| |¡qt |ƒt krv|  |¡qt d  |t |ƒ¡ƒ‚q| ||¡dS)Nzunknown type for {!r} type {!r})rÚadd_intÚ isinstancer Z add_int64ÚintrrÚ add_stringrHr Ú_packrUrSÚ _send_packet)r?r]rZÚargrOÚitemrErErFÚ _responseãs        ÿzSFTPServer._responseFcCsztt|ƒtƒs| ||¡dS| td |j¡ƒ¡|jd7_|rV||j|  ¡<n||j |  ¡<|  |t |  ¡¡dS)Nzhx{:d}r8) rGrHÚ SFTPHandlerYZ _set_namerrSr;r=Z _get_namer<rƒr)r?r]ÚhandleÚfolderrErErFÚ_send_handle_responseõs z SFTPServer._send_handle_responseNcCsD|dkr.z t|}Wntk r,d}YnX| |t||d¡dS)NÚUnknownÚ)rÚ IndexErrorrƒr)r?r]ÚcodeÚdescrErErFrYs   zSFTPServer._send_statuscCsL|j |¡}tt|ƒtƒrZ list_folderrGrHrIr„Z _set_filesr‡rY)r?r]ÚpathÚrespr†rErErFÚ _open_folder s  zSFTPServer._open_foldercCs|| ¡}t|ƒdkr$| |t¡dStƒ}| |¡| t|ƒ¡|D]$}| |j¡| |¡| |¡qF|  t |¡dS)Nr) Z_get_next_filesÚlenrYrrr{r~rxrr€r)r?r]r†ÚflistrOryrErErFÚ _read_folders      zSFTPServer._read_foldercCsÂ| ¡}| ¡}| ¡}| ¡}| ¡}||jkrD| |td¡dS|j|}|D]} | tkrR| } t| } q‚qR| |td¡dS|dkr¼|  ¡} t t | ƒt ƒs²| || d¡dS| j |}|dkrÈ|}|dkrâ| |td¡dStƒ} |}|||kr„t||||ƒ}t|dƒ}d}| ƒ}||krv| ||¡}t|tƒsT| ||d¡dS| |¡|t|ƒ7}||7}q | | ¡7} qìtƒ}| |¡| d ¡| | ¡| | ¡| t|¡dS) NúInvalid handlezNo supported hash types foundrzUnable to stat fileézBlock size too smallizUnable to hash fileú check-file)Ú get_binaryZget_listÚ get_int64rWr<rYrÚ _hash_classrÚstatrGrHr rwÚbytesÚminÚreadr|rÚupdaterÚdigestrr{r~Z add_bytesr€r)r?r]rOr…Zalg_listÚstartÚlengthÚ block_sizerbÚxZalgnameÚalgÚstZsum_outÚoffsetZblocklenZchunklenÚcountZhash_objr[rErErFÚ _check_file%s‚ ÿ ÿ ÿ    ÿ       zSFTPServer._check_filecCsz|t@r|t@rtj}n|t@r(tj}ntj}|t@r@|tjO}|t@rR|tj O}|t @rd|tj O}|t @rv|tj O}|S)z;convert SFTP-style open() flags to Python's os.open() flags)rrrlÚO_RDWRÚO_WRONLYÚO_RDONLYrÚO_APPENDrÚO_CREATrÚO_TRUNCrÚO_EXCL)r?ZpflagsÚflagsrErErFÚ_convert_pflagshs    zSFTPServer._convert_pflagscCsÀ| td t|¡¡|tkrZ| ¡}| | ¡¡}t  |¡}|  ||j   |||¡¡nb|t krÎ| ¡}||jkrŒ|j|=| |t¡dS||jkr¼|j| ¡|j|=| |t¡dS| |td¡nî|tkrl| ¡}| ¡}| ¡} ||jkr| |td¡dS|j| || ¡} t| ttfƒr\t| ƒdkrL| |t¡n| |t| ¡n | || ¡nP|tkrÊ| ¡}| ¡}| ¡} ||jkr¬| |td¡dS| ||j|  || ¡¡nò|t!krô| ¡}| ||j  "|¡¡nÈ|t#kr(| ¡} | ¡} | ||j  $| | ¡¡n”|t%kr^| ¡}t  |¡}| ||j  &||¡¡n^|t'krˆ| ¡}| ||j  (|¡¡n4|t)krª| ¡}| *||¡dS|t+krô| ¡}||jkrÚ| |td¡dS|j|} | ,|| ¡nÈ|t-krB| ¡}|j  .|¡}t/t0|ƒtƒr2| |t1|¡n | ||¡nz|t2kr| ¡}|j  3|¡}t/t0|ƒtƒr€| |t1|¡n | ||¡n,|t4krþ| ¡}||jkrÀ| |td¡dS|j| .¡}t/t0|ƒtƒrî| |t1|¡n | ||¡n¾|t5kr4| ¡}t  |¡}| ||j  6||¡¡nˆ|t7krŠ| ¡}t  |¡}||jkrn| |td¡dS| ||j| 6|¡¡n2|t8krÞ| ¡}|j  9|¡}t|ttfƒrÐ| |t:d|dtƒ¡n | ||¡nÞ|t;kr| ¡}| ¡}| ||j  <||¡¡n¬|t=krF| ¡}|j  >|¡}| |t:d|dtƒ¡nv|t?kr°| ¡}|dkrp| @||¡n>|dkr¢| ¡} | ¡} | ||j  A| | ¡¡n | |tB¡n | |tB¡dS)Nz Request: {}r“rr8r‰r•zposix-rename@openssh.com)CrKr rSrr Zget_textr°rWr Z _from_msgr‡r>rur!r–r=rYr"r<rarr#r—rœr|rrrrrƒr$r%Úwriter&Úremover'Úrenamer(Úmkdirr)Úrmdirr*rr+r’r,r™rGrHr-r.Úlstatr/r0Zchattrr1r2Úreadlinkrr3Úsymlinkr4Ú canonicalizer5r§Z posix_renamer6)r?rZr]rOrr¯ryr…r¥r r[ZoldpathÚnewpathr†rŽÚ target_pathZrpathÚtagrErErFrXzs` ÿ    ÿ  ÿ  ÿÿ   ÿ       ÿ       ÿ     ÿÿ  ÿ  ÿ  ÿ    ÿzSFTPServer._process)F)N)Ú__name__Ú __module__Ú __qualname__Ú__doc__r r9rKr^r_Ú staticmethodrgrzrƒr‡rYrr’r§r°rXÚ __classcell__rErErQrFr7Ws$ û "      Cr7)r„)ErÀrlrcriÚhashlibrrZparamikorZ paramiko.sftprrrrr Zparamiko.sftp_sir Zparamiko.sftp_attrr Zparamiko.commonr Zparamiko.py3compatr rrrZparamiko.serverrrrrrrrrrrrrrrrr r!r"r#r$r%r&r'r(r)r*r+r,r-r.r/r0r1r2r3r4r5r6r˜r7Zparamiko.sftp_handler„rErErErFÚs$     œ( G