3 L]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 dde eZBddlCmDZDdS)z Server-mode SFTP support. N)md5sha1)util)BaseSFTPMessage SFTP_FAILURESFTP_PERMISSION_DENIEDSFTP_NO_SUCH_FILE)SFTPServerInterface)SFTPAttributes)DEBUG)long string_types bytes_typesb)SubsystemHandler)% CMD_HANDLE SFTP_DESC CMD_STATUSSFTP_EOFCMD_NAMESFTP_BAD_MESSAGECMD_EXTENDED_REPLYSFTP_FLAG_READSFTP_FLAG_WRITESFTP_FLAG_APPENDSFTP_FLAG_CREATESFTP_FLAG_TRUNCSFTP_FLAG_EXCL CMD_NAMESCMD_OPEN CMD_CLOSESFTP_OKCMD_READCMD_DATA CMD_WRITE CMD_REMOVE CMD_RENAME CMD_MKDIR CMD_RMDIR CMD_OPENDIR CMD_READDIRCMD_STAT CMD_ATTRS CMD_LSTAT CMD_FSTAT CMD_SETSTAT CMD_FSETSTAT CMD_READLINK CMD_SYMLINK CMD_REALPATH CMD_EXTENDEDSFTP_OP_UNSUPPORTED)rrcseZdZdZefddZfddZddZfdd Ze d d Z e d d Z ddZ d ddZ d!ddZddZddZddZddZddZZS)" 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. cOshtj|tj|||||j}tj|jd|_|j|_ 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.sftpN)r__init__rZ get_transportrZ get_loggerZget_log_channelloggerZ get_hexdumpZ ultra_debug next_handle file_table folder_tableserver)selfchannelnamer>Zsftp_silargskwargs transportrE:/tmp/pip-install-wfra5znf/paramiko/paramiko/sftp_server.pyr9^s  zSFTPServer.__init__csjtt|trBxV|D](}tt|j|d|jjd|qWn$tt|j|d|jjd|dS)Nz[chan z] ) issubclasstypelistsuperr7_logsockget_name)r?levelmsgm) __class__rErFrKs     zSFTPServer._logc #Cs4||_|jtdj||j|jjxy|j\}}Wnbtk r^|jtddSt k r}z(|jtdt ||jtt j dSd}~XnXt |}|j}y|j|||Wq.t k r*}zH|jtdt ||jtt j y|j|tWn YnXWYdd}~Xq.Xq.WdS)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_packetEOFError ExceptionstrrZ tb_stringsrget_int_process _send_statusr) r?rArDr@tdataerOrequest_numberrErErFstart_subsystems2  zSFTPServer.start_subsystemcs`|jjtt|jx|jjD] }|jq$Wx|jjD] }|jq@Wi|_i|_dS)N) r>Z session_endedrJr7finish_subsystemr<valuescloser=)r?f)rQrErFr^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)errnoEACCESrENOENTENOTDIRr r)r[rErErF convert_errnos zSFTPServer.convert_errnoc CstjdkrB|j|j@r$tj||j|j|j@rBtj||j |j |j|j @rbtj ||j |jf|j|j@rt|d}|j|jWdQRXdS)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)sysplatform_flagsZFLAG_PERMISSIONSoschmodst_modeZ FLAG_UIDGIDchownst_uidst_gidZ FLAG_AMTIMEutimest_atimest_mtimeZ FLAG_SIZEopentruncatest_size)filenameattrrarErErF set_file_attrs      zSFTPServer.set_file_attrcGst}|j|x~|D]v}t|tr0|j|qt|trF|j|qt|ttfr`|j|qt |t krx|j |qt dj |t |qW|j||dS)Nzunknown type for {!r} type {!r})radd_int isinstancer Z add_int64intrr add_stringrHr _packrTrR _send_packet)r?r\rYargrOitemrErErF _responses         zSFTPServer._responseFcCsztt|ts|j||dS|jtdj|j|jd7_|rV||j|j <n||j |j <|j |t |j dS)Nzhx{:d}r8) rGrH SFTPHandlerXZ _set_namerrRr;r=Z _get_namer<rr)r?r\handlefolderrErErF_send_handle_responses z SFTPServer._send_handle_responseNcCsD|dkr.y t|}Wntk r,d}YnX|j|t||ddS)NUnknown)r IndexErrorrr)r?r\codedescrErErFrXs   zSFTPServer._send_statuscCsL|jj|}tt|trZ list_folderrGrHrIrZ _set_filesrrX)r?r\pathresprrErErF _open_folder s  zSFTPServer._open_foldercCs|j}t|dkr$|j|tdSt}|j||jt|x,|D]$}|j|j|j||j|qHW|j t |dS)Nr) Z_get_next_fileslenrXrrrzr}rwr~rr)r?r\rflistrOrxrErErF _read_folders      zSFTPServer._read_foldercCs|j}|j}|j}|j}|j}||jkrD|j|tddS|j|}x4|D]} | tkrT| } t| } PqTW|j|tddS|dkr|j } t t | t s|j|| ddS| j |}|dkr|}|dkr|j|tddSt} |}x|||krt||||}t|d}d}| }xX||kr||j||}t|tsZ|j||ddS|j||t|7}||7}q&W| |j7} qWt}|j||jd |j| |j| |jt|dS) NzInvalid handlezNo supported hash types foundrzUnable to stat filezBlock size too smallizUnable to hash filez check-file) get_binaryZget_list get_int64rVr<rXr _hash_classrstatrGrHr rvbytesminreadr{rupdaterdigestrrzr}Z add_bytesrr)r?r\rOrZalg_liststartlength block_sizeraxZalgnameZalgstZsum_outoffsetZblocklenZchunklencountZhash_objrZrErErF _check_file%sj                  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)rrrkO_RDWRO_WRONLYO_RDONLYrO_APPENDrO_CREATrO_TRUNCrO_EXCL)r?ZpflagsflagsrErErF_convert_pflagshs    zSFTPServer._convert_pflagscCs|jtdjt||tkrZ|j}|j|j}tj |}|j ||j j |||nb|t kr|j}||jkr|j|=|j|tdS||jkr|j|j|j|=|j|tdS|j|tdn|tkrl|j}|j}|j} ||jkr|j|tddS|j|j|| } t| ttfr\t| dkrL|j|tn|j|t| n |j|| nP|tkr|j}|j}|j} ||jkr|j|tddS|j||j|j || n|t!kr|j}|j||j j"|n|t#kr(|j} |j} |j||j j$| | n|t%kr^|j}tj |}|j||j j&||n^|t'kr|j}|j||j j(|n4|t)kr|j}|j*||dS|t+kr|j}||jkr|j|tddS|j|} |j,|| n|t-krB|j}|j j.|}t/t0|tr2|j|t1|n |j||nz|t2kr|j}|j j3|}t/t0|tr|j|t1|n |j||n,|t4kr|j}||jkr|j|tddS|j|j.}t/t0|tr|j|t1|n |j||n|t5kr4|j}tj |}|j||j j6||n|t7kr|j}tj |}||jkrn|j|tddS|j||j|j6|n2|t8kr|j}|j j9|}t|ttfr|j|t:d|dtn |j||n|t;kr|j}|j}|j||j j<||n|t=krF|j}|j j>|}|j|t:d|dtnv|t?kr|j}|dkrp|j@||n>|dkr|j} |j} |j||j jA| | n |j|tBn |j|tBdS)Nz Request: {}zInvalid handlerr8rz check-filezposix-rename@openssh.com)CrKr rRrr Zget_textrrVr Z _from_msgrr>rtr!rr=rXr"r<r`rr#rrr{rrrrrr$r%writer&remover'renamer(mkdirr)rmdirr*rr+rr,rrGrHr-r.lstatr/r0Zchattrr1r2readlinkrr3symlinkr4Z canonicalizer5rZ posix_renamer6)r?rYr\rOrrrxrrrrZoldpathnewpathrr target_pathZrpathtagrErErFrWzs                                            zSFTPServer._process)F)N)__name__ __module__ __qualname____doc__r r9rKr]r^ staticmethodrfryrrrXrrrrrW __classcell__rErE)rQrFr7Ws      Cr7)r)ErrkrbrhhashlibrrZparamikorZ 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/r0r1r2r3r4r5r6rr7Zparamiko.sftp_handlerrErErErFs$     ( G