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) 協議工作流程
客戶端向服務器端上發送文件
客戶端從服務器端上獲取文件