2016-06-30 100 views
0

ETA: Per https://github.com/hiratake55/RForcecom/issues/42 , it looks like the author of the rforcecom package has updated rforcecom to use httr instead of RCurl (as of today, to be uploaded to CRAN tomorrow, 7/1/16), so my particular issue will be solved at that point. However, the general case (implementing TLS 1.1/1.2 in RCurl) may still be worth pursuing for other packages. Or everyone may just switch to the more recent curl package instead of RCurl.RCurl中的TLS v1.1/TLS v1.2支持

背景:我一直在使用rforcecom軟件包與Salesforce進行數月的交流。 Salesforce最近禁用了對TLS v1.0的支持,並且在其Sandbox中需要TLS v1.1或更高版本;此更新將於2017年3月在生產環境中進行。

rforcecom使用RCurl與salesforce.com服務器進行通信。一般使用curlPerform方法,它是實現這樣的事情(本例中爲rforcecom.login.R):

h <- basicHeaderGatherer() 
t <- basicTextGatherer() 
URL <- paste(loginURL, rforcecom.api.getSoapEndpoint(apiVersion), sep="") 
httpHeader <- c("SOAPAction"="login","Content-Type"="text/xml") 
curlPerform(url=URL, httpheader=httpHeader, postfields=soapBody, headerfunction = h$update, writefunction = t$update, ssl.verifypeer=F) 

這已經爲我工作了一段時間,正如我所說。現在,Salesforce的已禁用TLS V1.0上沙箱,但是,它失敗,出現以下錯誤:

UNSUPPORTED_CLIENT: TLS 1.0 has been disabled in this organization. Please use TLS 1.1 or higher when connecting to Salesforce using https. 

我修改和採購(不包中的本地副本實現它,因爲我沒有經驗足夠做到這一點)對RForcecom的登錄模塊的本地副本進行了更改,並且我通過實驗發現,我可以通過將sslversion=SSLVERSION_TLSv1,sslversion=SSLVERSION_SSLv3等添加到SSLVERSION中來成功指定SSLVERSION的任何現有枚舉值curlPerform選項被調用。但是,所有這些都給了我與上面相同的錯誤。當我嘗試使用的是libcurl中實現,但不是在RCurl(SSLVERSION_TLSv1.1SSLVERSION_TLSv1.2)的選項之一,我得到以下錯誤:

Error in merge(list(...), .opts) : object 'SSLVERSION_TLSv1.1' not found 

或:

Error in merge(list(...), .opts) : object 'SSLVERSION_TLSv1.2' not found 

我已經驗證與curlVersion()我的libcurl版本是7.40.0,根據https://curl.haxx.se/libcurl/c/CURLOPT_SSLVERSION.html確實支持這些選項。但是,我無法讓RCurl識別它們。

在這一點上,我正在尋找的是一種讓RCurl使用TLS v1.1或TLS v1.2的方法,我非常感謝能夠得到的任何幫助。對於我的問題中的任何問題/問題,我深表歉意,因爲這是我第一次自問,以前我總是能夠通過閱讀其他人的問題和答案來解決問題。

回答

0

RCurl是libcurl的一個接口,它支持什麼取決於後者。有可能您的libcurl是使用較舊版本的OpenSSL構建的,它不支持TLS v1.1或v.1.2。你可以判斷來自R您的SSL版本是這樣的:

RCurl::curlVersion()$ssl_version 

我認爲,在默認情況下(例如SSL選項CURL_SSLVERSION_DEFAULT),SSL握手過程中,服務器和客戶端將在最新的版本,它們都支持同意。爲了使它工作,你必須更新OpenSSL到一個更新的版本,重新編譯libcurl並重建RCurl,以便它註冊更新。

也就是說,您可以通過自己傳遞所需選項的整數值來強制執行未在RCurl中定義的特定ssl版本。你正在尋找的數字可以從the curl header file on GitHub定義的C enum推斷:

enum { 
    CURL_SSLVERSION_DEFAULT, // 0 
    CURL_SSLVERSION_TLSv1, /* TLS 1.x */ // 1 
    CURL_SSLVERSION_SSLv2, // 2 
    CURL_SSLVERSION_SSLv3, // 3 
    CURL_SSLVERSION_TLSv1_0, // 4 
    CURL_SSLVERSION_TLSv1_1, // 5 
    CURL_SSLVERSION_TLSv1_2, // 6 
    CURL_SSLVERSION_TLSv1_3, // 7 

    CURL_SSLVERSION_LAST /* never use, keep last */ // 8 
}; 

例如:

# the data of you post request 
nameValueList = list(data1 = "data1", data2 = "data2") 

CURL_SSLVERSION_TLSv1_1 <- 5L 
CURL_SSLVERSION_TLSv1_2 <- 6L 

# TLS 1.1 
opts <- RCurl::curlOptions(verbose = TRUE, 
          sslversion = CURL_SSLVERSION_TLSv1_1, ...) 

# TLS 1.2 
opts <- RCurl::curlOptions(verbose = TRUE, 
          sslversion = CURL_SSLVERSION_TLSv1_2, ...) 

# finally, POST the data 
RCurl::postForm(URL, .params = nameValueList, .opts = opts) 

在一般情況下,這可能不是一個很好的做法,因爲捲曲的作者可以決定改變這些選項的價值(儘管我相信機會很低)。