SFTP協議

 

SCP協議本身打開SSH通道時指定的是scp命令,而是用SFTP時指定的sftp。以下是一些具體的介紹,詳細內容需要參考對應的RFC文件。

下面是目前整理的使用的一份:

1) 協議中數據包格式

通過安全通道傳輸的所有包的格式如下:

     uint32           length

     byte             type

     uint32           request-id

     ... 具體類型域 ...

length:整個包的長度,不包括長度域本身。因此,例如一個不包含具體類型域的包的長度域是5個字節,那麼將有9個字節發送到路線上。實際上包的最大尺寸由客戶端決定(它發送的讀寫請求包最大尺寸,外加一些字節的包開銷)。所有服務器應當支持至少34000字節的包(這裏的包尺寸是指全長,包括上述頭部)。也就是允許讀寫最多32768個字節。

 

type:包的類型碼。

 

request-id:從客戶端來的每一個請求包含一個請求ID域,從服務端返回的每個響應也包含和服務器應答的請求一樣的請求ID。一個可能的是實現是客戶提供給我們一個單調遞增的序號(模除2^32)。然而沒有特殊的要求請求ID域是唯一的。

     

SFTP協議中只有兩個包,INIT和VERSION,不需要使用請求ID。

 

2) 協議中各種包具體格式和響應

包的類型type如下:

SSH_FXP_INIT                1

SSH_FXP_VERSION             2

SSH_FXP_OPEN                3

SSH_FXP_CLOSE               4

SSH_FXP_READ                5

SSH_FXP_WRITE               6

SSH_FXP_LSTAT               7

SSH_FXP_FSTAT               8

SSH_FXP_SETSTAT             9

SSH_FXP_FSETSTAT           10

SSH_FXP_OPENDIR            11

SSH_FXP_READDIR            12

SSH_FXP_REMOVE             13

SSH_FXP_MKDIR              14

SSH_FXP_RMDIR              15

SSH_FXP_REALPATH           16

SSH_FXP_STAT               17

SSH_FXP_RENAME             18

SSH_FXP_READLINK           19

SSH_FXP_LINK               21

SSH_FXP_BLOCK              22

SSH_FXP_UNBLOCK            23

 

SSH_FXP_STATUS            101

SSH_FXP_HANDLE            102

SSH_FXP_DATA              103

SSH_FXP_NAME              104

SSH_FXP_ATTRS             105

 

SSH_FXP_EXTENDED          200

SSH_FXP_EXTENDED_REPLY    201

 

客戶端初始化包

type    SSH_FXP_INIT

uint32  version

 

對這個消息的響應是下面的服務器初始化版本包SSH_FXP_VERSION。

 

服務器初始化包

type    SSH_FXP_VERSION

uint32  version

 

打開文件包

byte     SSH_FXP_OPEN

uint32   request-id

string   filename [UTF-8]

uint32   desired-access

uint32   flags

ATTRS  attrs

 

對這個消息的響應將會是SSH_FXP_HANDLE(如果操作成功的話)或者SSH_FXP_STATUS(如果操作失敗)

 

關閉句柄

byte     SSH_FXP_CLOSE

uint32   request-id

string   handle

 

handle是以前SSH_FXP_OPEN或SSH_FXP_OPENDIR返回的句柄。句柄變爲無效後立即請求已發送。

對此請求的響應將是一個SSH_FXP_STATUS消息。請注意,在一些服務器平臺上關閉操作可能會失敗。例如,如果服務器操作系統緩存寫入,在沖洗緩存寫入時發生錯誤,關閉操作就可能失敗。

注意不論SSH_FXP_STATUS的結果,句柄是無效的。沒有辦法爲客戶恢復關閉失敗的句柄。客戶端必須釋放與句柄關聯的所有資源,無論狀態。服務器應採取的任何步驟,它可以恢復從關閉失敗,以確保服務器上的處理相關聯的所有資源正確釋放。

 

讀取文件

byte     SSH_FXP_READ

uint32   request-id

string   handle

uint64   offset

uint32   length

 

handle 是被SSH_FXP_OPEN返回打開的文件句柄。如果不是被SSH_FXP_OPEN返回的句柄,服務器必須返回SSH_FX_INVALID_HANDLE。

   offset是偏移量(以字節爲單位)相對於讀取文件開始的地方。此字段被忽略,如果SSH_FXF_TEXT_MODE指定在打開的時候。

   length 是讀取的最大字節數。

      服務器不能響應比的“length”參數指定的更多的數據。但是,服務器的響應可能較少的數據,如果達到EOF,遇到一個錯誤,或內部緩衝區的服務器無法處理這麼大的要求。

      如果服務器指定一個非零的max-read-size在它的supported2擴展中,並且length小於max-read-size,沒有返回length個字節暗示EOF或者錯誤發生。

 

寫入文件

byte     SSH_FXP_WRITE

uint32   request-id

string    handle

uint64    offset

string    data

 

   handle是一個打開文件句柄被SSH_FXP_OPEN返回的。如果handle不是一個SSH_FXP_OPEN返回的句柄,服務器必須返回SSH_FX_INVALID_HANDLE。

   offset是偏移量(以字節爲單位),相對於文件的開頭寫必須開始。此字段被忽略,如果SSH_FXF_TEXT_MODE是在打開期間指定。如果超出文件末尾寫的話,會擴展文件。它是合法的,寫一個偏移量超出該文件的末尾擴展的語義是從文件末尾寫字節值0x00指定的偏移,然後是數據。在大多數操作系統上,如寫不分配磁盤空間,而是創建一個稀疏文件。

   data是要寫入文件的數據。

   服務器響應一個寫請求一個SSH_FXP_STATUS消息。

 

獲取文件屬性

很多時候,文件屬性是SSH_FXP_READDIR自動返回的。然而,有些時候需要專門獲得命名文件的屬性。可以使用SSH_FXP_STAT,SSH_FXP_LSTAT和SSH_FXP_FSTAT請求。

   SSH_FXP_STAT和SSH_FXP_LSTAT不同,僅僅在於SSH_FXP_STAT遵循在服務器上的符號鏈接,然而SSH_FXP_LSTAT不遵循符號鏈接。兩者的有一樣的格式:

  byte     SSH_FXP_STAT or SSH_FXP_LSTAT

  uint32   request-id

  string   path [UTF-8]

  uint32   flags

 

   其中request-id是請求標識符,path指定狀態被返回的文件系統對象。服務器用SSH_FXP_ATTRS或者SSH_FXP_STATUS返回請求。

   flag字段指定客戶端有特別興趣的屬性標誌。這是到服務器的提示。例如,在某些操作系統上獲取ower、group和acl信息是昂貴的操作,服務器可能不獲取它們除非客戶端表達出特別的興趣。

   客戶端不能保證服務器提供所有它感興趣的字段。

  

   SSH_FXP_FSTAT不同於其他在於它返回一個打開的文件(文件句柄標識)的狀態信息。

   byte      SSH_FXP_FSTAT

   uint32    request-id

   string    handle

   uint32    flags

 

      handle是一個SSH_FXP_OPEN或者SSH_FXP_OPENDIR打開的文件句柄。

   服務器用SSH_FXP_ATTRS或者SSH_FXP_STATUS來響應這個請求。

 

設置文件屬性

文件屬性可以使用SSH_FXP_SETSTAT和SSH_FXP_FSETSTAT請求來修改。

byte      SSH_FXP_SETSTAT

uint32    request-id

string    path [UTF-8]

ATTRS     attrs

 

byte      SSH_FXP_FSETSTAT

uint32    request-id

string    handle

ATTRS     attrs

 

path是屬性被修改的文件系統對象(例如,文件或者目錄)。如果對象不存在,或者用戶沒有足夠的訪問權限去改寫屬性,請求會失敗。

handle是SSH_FXP_OPEN或者SSH_FXP_OPENDIR打開的文件句柄。如果句柄沒有被足夠的訪問權限打開去改寫請求的熟悉,請求會失敗。

attrs指定被應用的修改屬性。更多細節參看File Attributes節。

服務器用SSH_FXP_STATUS消息響應。

因爲某些系統可能使用分離的系統調用來設置各種屬性,可能某些屬性已經被修改了,仍然返回一個失敗的響應。如果可能,服務器應該避免這種情況;然而,客戶端必須清楚這種可能性。

 

打開目錄

byte     SSH_FXP_OPENDIR

uint32   request-id

string   path [UTF-8]

 

path字段是列舉的(沒有任何尾隨的斜線)的目錄的路徑名。更多信息參看“File Names”。

如果“路徑”並不是指到一個目錄,服務器必須返回SSH_FX_NOT_A_DIRECTORY。

此消息的響應,將要麼SSH_FXP_HANDLE(如果操作成功)或SSH_FXP_STATUS(如果操作失敗)。

 

讀取目錄

byte     SSH_FXP_READDIR

uint32   request-id

string   handle

 

handle是由SSH_FXP_OPENDIR返回的句柄。如果handle是一個SSH_FXP_OPEN返回普通的文件句柄,服務器必須返回SSH_FX_INVALID_HANDLE。

服務器用一個SSH_FXP_NAME或SSH_FXP_STATUS消息響應這個請求。在一段時間,可能會返回一個或多個名稱。完整的狀態信息返回每個名稱,以加速典型的目錄清單。

如果沒有更多的名字可以讀取,服務器必須響應一個SSH_FXP_STATUS消息,錯誤代碼的SSH_FX_EOF

 

刪除文件

byte      SSH_FXP_REMOVE

uint32    request-id

string    filename [UTF-8]

filename是要刪除的文件名稱。更多信息參考“File Names”。

如果filename是一個符號鏈接,鏈接被刪除,指向的文件不會被刪除。

這個請求不能被用於移除目錄,在這種情況下,服務器必須返回SSH_FX_FILE_IS_A_DIRECTORY。

服務器將會用SSH_FXP_STATUS消息響應這個請求。

 

重命名文件

byte       SSH_FXP_RENAME

uint32     request-id

string     oldpath [UTF-8]

string     newpath [UTF-8]

uint32     flags

 

  其中“request-id”是請求標識符,“oldpath“是現有的文件或目錄的名稱,”newpath“是爲新的文件或目錄名稱。

   'flags' 是 0 或者以下值的組合:

   SSH_FXF_RENAME_OVERWRITE  0x00000001

   SSH_FXF_RENAME_ATOMIC     0x00000002

   SSH_FXF_RENAME_NATIVE     0x00000004

   如果服務器不支持請求的操作模式,它必須返回SSH_FX_OP_UNSUPPORTED。

   如果flags不包括SSH_FXP_RENAME_OVERWRITE,newpath指定的名稱已經存在一個文件,服務器必須響應SSH_FX_FILE_ALREADY_EXISTS。

   如果flags包括SSH_FXP_RENAME_ATOMIC,目標文件已存在,它是在一個原子的方式取代。例如,有沒有在時間上觀察到的瞬間,其中的名稱並不是指無論是舊的或新的文件。 SSH_FXP_RENAME_ATOMIC意味着SSH_FXP_RENAME_OVERWRITE。

   服務器將用SSH_FXP_STATUS消息來回應這個請求。

 

創建目錄

byte      SSH_FXP_MKDIR

uint32    request-id

string    path [UTF-8]

ATTRS  attrs

其中request-id是請求標識符,path指定被創建的目錄,attrs指定了應該被應用到創建上的屬性。

服務器將用SSH_FXP_STATUS消息來響應這個請求。如果指定的文件或者目錄已經存在了,錯誤將被返回。

 

移除目錄

byte     SSH_FXP_RMDIR

uint32   request-id

string   path [UTF-8]

 

其中request-id是請求標識符,path指定被移除的目錄。

服務器用SSH_FXP_STATUS消息響應請求。

 

狀態響應

SSH_FXP_STATUS響應數據部分的格式如下:

byte     SSH_FXP_STATUS

uint32   request-id

uint32   error/status code

string   error message (ISO-10646 UTF-8 [RFC-2279])

string   language tag (as defined in [RFC-1766])

error-specific data

 

request-id指示服務端響應的客戶端請求。

error/status code是機器可讀的狀態代碼指示請求的結果。值SSH_FX_OK指示成功,其他值指示失敗。實現必須準備能收到意想不到的錯誤代碼,他們理智地處理(如他們視爲等同於SSH_FX_FAILURE)。

error message是人類可讀的錯誤描述。

language tag指示錯誤使用的語言。

error-specific data可能是空的,可能包含附加的錯誤信息。

 

句柄響應

SSH_FXP_HANDLE響應的格式如下:

byte      SSH_FXP_HANDLE

uint32    request-id

string    handle

 

handle是一個任意的字符串,用於標識一個打開的文件或服務器上的目錄。句柄對客戶端是不透明的,不要試圖以任何方式解釋或修改它。句柄字符串的長度不能超過256個字節的數據。

 

數據響應

SSH_FXP_DATA響應的格式如下:

byte     SSH_FXP_DATA

uint32   request-id

string   data

bool     end-of-file [optional]

      

data是一個任意字節的字符串,其中包含請求的數據。數據字符串最多可能被要求在SSH_FXP_READ請求的字節數,但也可能較短。

end-of-file此字段是可選的,如果是存在和爲真的,它表明,EOF的是讀期間到達的。這可以幫助客戶避免了往返,以確定短讀是否正常(由於EOF)或一些其他問題(例如有限的服務器的緩衝區。)

名稱響應

SSH_FXP_NAME響應的格式如下:

byte     SSH_FXP_NAME

uint32   request-id

uint32   count

repeats  count times:

    string       filename [UTF-8]

    ATTRS        attrs

bool     end-of-list [optional]

 

count在這個響應中返回的名稱的數目,filename和attrs重複count次。

filename是被返回的文件名。

attrs是該文件的屬性。

end-of-list如果這個字段是存在的和爲真,沒有更多的讀取條目了。除非請求是SSH_FXP_READDIR,否則字段應該被省略或爲真。

 

屬性響應

SSH_FXP_ATTRS響應的格式如下:

byte      SSH_FXP_ATTRS

uint32    request-id

ATTRS     attrs

 

attrs返回的文件屬性。

 

1) 協議工作流程

客戶端向服務器端上發送文件

 

客戶端從服務器端上獲取文件

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章