1
0
mirror of https://github.com/Bayselonarrend/OpenIntegrations.git synced 2025-08-10 22:41:43 +02:00

FTP: Доработка TLS shutdown delay

This commit is contained in:
Anton Titovets
2025-07-31 12:19:38 +03:00
parent f67148246f
commit 08c98b20c9
15 changed files with 8598 additions and 8539 deletions

File diff suppressed because it is too large Load Diff

View File

@@ -198,7 +198,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "778e2ac28f6c47af28e4907f13ffd1e1ddbd400980a9abd7c8df189bf578a5ad"
dependencies = [
"libc",
"windows-sys 0.52.0",
"windows-sys 0.59.0",
]
[[package]]
@@ -445,6 +445,7 @@ dependencies = [
"rustls-pemfile",
"serde",
"serde_json",
"socket2",
"socks",
"suppaftp",
"webpki-roots",
@@ -555,7 +556,7 @@ dependencies = [
"errno",
"libc",
"linux-raw-sys",
"windows-sys 0.52.0",
"windows-sys 0.59.0",
]
[[package]]
@@ -660,6 +661,16 @@ version = "1.13.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67"
[[package]]
name = "socket2"
version = "0.5.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e22376abed350d73dd1cd119b57ffccad95b4e585a7cda43e286245ce23c0678"
dependencies = [
"libc",
"windows-sys 0.52.0",
]
[[package]]
name = "socks"
version = "0.3.4"

View File

@@ -23,4 +23,5 @@ base64 = "0.22.1"
chrono = { version = "0.4", features = ["serde"] }
webpki-roots = "1.0.1"
rustls = { version = "0.23.28", features = ["ring"] }
rustls-pemfile = "2.2.0"
rustls-pemfile = "2.2.0"
socket2 = "0.5.10"

View File

@@ -1,9 +1,9 @@
"MAIN ---"
linux-vdso.so.1 (0x00007ffe82d8e000)
libpthread.so.0 => /lib64/libpthread.so.0 (0x0000725577200000)
libc.so.6 => /lib64/libc.so.6 (0x0000725576e00000)
libdl.so.2 => /lib64/libdl.so.2 (0x0000725576a00000)
/lib64/ld-linux-x86-64.so.2 (0x0000725577800000)
linux-vdso.so.1 (0x00007fff4abf9000)
libpthread.so.0 => /lib64/libpthread.so.0 (0x00007974a2e00000)
libc.so.6 => /lib64/libc.so.6 (0x00007974a2a00000)
libdl.so.2 => /lib64/libdl.so.2 (0x00007974a2600000)
/lib64/ld-linux-x86-64.so.2 (0x00007974a3400000)
GLIBC_2.2.5
GLIBC_2.3
GLIBC_2.3.4

View File

@@ -26,4 +26,5 @@ pub struct FtpTlsSettings {
pub use_tls: bool,
pub accept_invalid_certs: bool,
pub ca_cert_path: Option<String>,
pub shutdown_delay: u64,
}

View File

@@ -1,4 +1,4 @@
use std::io::{copy, BufReader, Cursor};
use std::io::{copy, BufReader, Cursor, Write};
use std::net::{SocketAddr, TcpStream};
use serde_json::json;
use suppaftp::{FtpStream, Mode, RustlsConnector, RustlsFtpStream};
@@ -7,7 +7,8 @@ use std::str::FromStr;
use chrono::{DateTime, Utc};
use serde::Serialize;
use std::string::String;
use std::thread::sleep;
use std::time::Duration;
use crate::component::configuration::{FtpProxySettings, FtpSettings, FtpTlsSettings};
use crate::component::tls_establish;
use crate::component::tcp_establish;
@@ -156,22 +157,22 @@ impl FtpClient {
}
}
pub fn upload_data(&mut self, path: &str, data: &[u8]) -> String {
pub fn upload_data(&mut self, path: &str, data: &[u8], tls_delay: u64) -> String {
let mut cursor = Cursor::new(data);
match self.upload_from_reader(path, &mut cursor) {
match self.upload_from_reader(path, &mut cursor, tls_delay) {
Ok(bytes) => json!({"result": true, "bytes": bytes}).to_string(),
Err(e) => format_json_error(e)
}
}
pub fn upload_file(&mut self, path: &str, filepath: &str) -> String {
pub fn upload_file(&mut self, path: &str, filepath: &str, tls_delay: u64) -> String {
let file = match std::fs::File::open(filepath) {
Ok(f) => f,
Err(e) => return format_json_error(format!("File error: {}", e))
};
let mut buf_reader = BufReader::new(file);
match self.upload_from_reader(path, &mut buf_reader) {
match self.upload_from_reader(path, &mut buf_reader, tls_delay) {
Ok(bytes) => json!({"result": true, "bytes": bytes}).to_string(),
Err(e) => format_json_error(e)
}
@@ -193,7 +194,8 @@ impl FtpClient {
fn upload_from_reader<R: std::io::Read>(
&mut self,
path: &str,
reader: &mut R
reader: &mut R,
tls_delay: u64
) -> Result<u64, String> {
match self {
FtpClient::Secure(stream) => {
@@ -204,8 +206,8 @@ impl FtpClient {
let bytes = copy(reader, &mut data_stream)
.map_err(|e| format!("Upload error: {}", e))?;
let _ = std::io::Write::flush(&mut data_stream);
std::thread::sleep(std::time::Duration::from_millis(300));
let _ = data_stream.flush();
sleep(Duration::from_millis(tls_delay));
stream.finalize_put_stream(data_stream)
.map(|_| bytes)

View File

@@ -41,7 +41,7 @@ pub fn get_params_amount(num: usize) -> usize {
1 => 0,
2 => 1,
3 => 1,
4 => 3,
4 => 4,
5 => 0,
6 => 1,
7 => 1,
@@ -76,8 +76,9 @@ pub fn cal_func(obj: &mut AddIn, num: usize, params: &mut [Variant]) -> Box<dyn
let use_tls = params[0].get_bool().unwrap_or(false);
let accept_invalid_certs = params[1].get_bool().unwrap_or(false);
let ca_cert_path = params[2].get_string().unwrap_or("".to_string());
let shutdown_delay = params[3].get_i32().unwrap_or(0);
Box::new(obj.set_tls(use_tls, accept_invalid_certs, &ca_cert_path))
Box::new(obj.set_tls(use_tls, accept_invalid_certs, &ca_cert_path, shutdown_delay as u64))
},
5 => {
@@ -123,8 +124,13 @@ pub fn cal_func(obj: &mut AddIn, num: usize, params: &mut [Variant]) -> Box<dyn
let path = params[1].get_string().unwrap_or("".to_string());
let tls_delay = match &obj.tls_settings{
Some(s) => s.shutdown_delay,
None => 0
};
Box::new(match &mut obj.get_client(){
Ok(c) => c.upload_data(&path, data),
Ok(c) => c.upload_data(&path, data, tls_delay),
Err(e) => e.to_string()
})
},
@@ -133,8 +139,13 @@ pub fn cal_func(obj: &mut AddIn, num: usize, params: &mut [Variant]) -> Box<dyn
let filepath = params[0].get_string().unwrap_or("".to_string());
let path = params[1].get_string().unwrap_or("".to_string());
let tls_delay = match &obj.tls_settings{
Some(s) => s.shutdown_delay,
None => 0
};
Box::new(match &mut obj.get_client(){
Ok(c) => c.upload_file(&path, &filepath),
Ok(c) => c.upload_file(&path, &filepath, tls_delay),
Err(e) => e.to_string()
})
@@ -274,7 +285,11 @@ impl AddIn {
}
pub fn set_tls(&mut self, use_tls: bool, accept_invalid_certs: bool, ca_cert_path: &str) -> String {
pub fn set_tls(&mut self
, use_tls: bool
, accept_invalid_certs: bool
, ca_cert_path: &str
, shutdown_delay: u64) -> String {
if self.client.is_some(){
return process_error("TLS settings can only be set before the connection is established");
@@ -285,7 +300,8 @@ impl AddIn {
self.tls_settings = Some(FtpTlsSettings{
use_tls,
accept_invalid_certs,
ca_cert_path: ca_path
ca_cert_path: ca_path,
shutdown_delay
});
json!({"result": true}).to_string()

View File

@@ -3,6 +3,7 @@ use std::net::{SocketAddr, TcpStream};
use std::time::Duration;
use socks::{Socks4Stream, Socks5Stream};
use base64::{Engine as _, engine::general_purpose};
use socket2::Socket;
use suppaftp::FtpError;
use crate::component::configuration::{FtpProxySettings, FtpSettings};
@@ -43,6 +44,15 @@ pub fn make_passive_proxy_stream(
let _ = tcp_connection.set_write_timeout(w_timeout);
let _ = tcp_connection.set_read_timeout(r_timeout);
let socket = Socket::from(tcp_connection);
match socket.set_linger(Some(Duration::from_secs(10))){
Ok(_) => {},
Err(e) => return Err(FtpError::ConnectionError(
std::io::Error::new(std::io::ErrorKind::Unsupported, e)))
};
let tcp_connection = TcpStream::from(socket);
Ok(tcp_connection)
},

Binary file not shown.

Binary file not shown.

View File

@@ -21,7 +21,7 @@
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.

View File

@@ -271,16 +271,18 @@
// Примечание:
// Настройки Tls могут быть установлены только в момент создания соединения: явного, при использовании функции `ОткрытьСоединение`^^
// или неявного, при передаче настроек
// `Задержка` может быть увеличена при низкой скорости соединения для избежания проблем с корректным завершением TLS
//
// Параметры:
// ОтключитьПроверкуСертификатов - Булево - Позволяет работать с некорретными сертификатами, в т.ч. самоподписанными - trust
// ПутьКСертификату - Строка - Путь к корневому PEM файлу сертификата, если его нет в системном хранилище - cert
// Задержка - Число - Задержка перед закрытием соединения для корректного завершения TLS (мс) - delay
//
// Возвращаемое значение:
// Структура Из КлючИЗначение - Структура настроек TLS соединения
Функция ПолучитьНастройкиTls(Знач ОтключитьПроверкуСертификатов, Знач ПутьКСертификату = "") Экспорт
Функция ПолучитьНастройкиTls(Знач ОтключитьПроверкуСертификатов, Знач ПутьКСертификату = "", Знач Задержка = 250) Экспорт
Возврат OPI_Компоненты.ПолучитьНастройкиTls(ОтключитьПроверкуСертификатов, ПутьКСертификату);
Возврат OPI_Компоненты.ПолучитьНастройкиTls(ОтключитьПроверкуСертификатов, ПутьКСертификату, Задержка);
КонецФункции

View File

@@ -92,7 +92,17 @@
OPI_ПреобразованиеТипов.ПолучитьБулево(ОтключитьВалидацию);
OPI_ПреобразованиеТипов.ПолучитьСтроку(ПутьКСертификату);
Результат = Компонета.SetTLS(ИспользоватьTls, ОтключитьВалидацию, ПутьКСертификату);
Задержка = Неопределено;
Если OPI_Инструменты.ПолеКоллекцииСуществует(Tls, "shutdown_delay", Задержка) Тогда
OPI_ПреобразованиеТипов.ПолучитьЧисло(Задержка);
Результат = Компонета.SetTLS(ИспользоватьTls, ОтключитьВалидацию, ПутьКСертификату, Задержка);
Иначе
Результат = Компонета.SetTLS(ИспользоватьTls, ОтключитьВалидацию, ПутьКСертификату);
КонецЕсли;
Результат = OPI_Инструменты.JsonВСтруктуру(Результат);
КонецЕсли;
@@ -101,12 +111,15 @@
КонецФункции
Функция ПолучитьНастройкиTls(Знач ОтключитьПроверкуСертификатов, Знач ПутьКСертификату = "") Экспорт
Функция ПолучитьНастройкиTls(Знач ОтключитьПроверкуСертификатов
, Знач ПутьКСертификату = ""
, Знач Задержка = Неопределено) Экспорт
СтруктураСертификата = Новый Структура;
OPI_Инструменты.ДобавитьПоле("use_tls" , Истина , "Булево", СтруктураСертификата);
OPI_Инструменты.ДобавитьПоле("accept_invalid_certs", ОтключитьПроверкуСертификатов, "Булево", СтруктураСертификата);
OPI_Инструменты.ДобавитьПоле("ca_cert_path" , ПутьКСертификату , "Строка", СтруктураСертификата);
OPI_Инструменты.ДобавитьПоле("shutdown_delay" , Задержка , "Число" , СтруктураСертификата);
Возврат СтруктураСертификата;