1
0
mirror of https://github.com/SoftEtherVPN/SoftEtherVPN.git synced 2024-11-26 19:39:53 +03:00

Compare commits

..

No commits in common. "68964ab0d795835e4d36e707baf8a1cad23bc481" and "b06486b37d9e7228bcb4629b2120b5b41f1ba26a" have entirely different histories.

7 changed files with 94 additions and 134 deletions

View File

@ -11,7 +11,7 @@ FreeBSD_task:
SSL: SSL:
matrix: matrix:
freebsd_instance: freebsd_instance:
image_family: freebsd-14-0 image_family: freebsd-13-2
prepare_script: prepare_script:
- pkg install -y pkgconf cmake git libsodium $SSL - pkg install -y pkgconf cmake git libsodium $SSL
- git submodule update --init --recursive - git submodule update --init --recursive

View File

@ -65,23 +65,12 @@
} }
}, },
"braces": { "braces": {
"version": "3.0.3", "version": "3.0.2",
"resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz",
"integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==",
"dev": true, "dev": true,
"requires": { "requires": {
"fill-range": "^7.1.1" "fill-range": "^7.0.1"
},
"dependencies": {
"fill-range": {
"version": "7.1.1",
"resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz",
"integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==",
"dev": true,
"requires": {
"to-regex-range": "^5.0.1"
}
}
} }
}, },
"builtin-modules": { "builtin-modules": {
@ -162,6 +151,15 @@
"integrity": "sha1-Cr9PHKpbyx96nYrMbepPqqBLrJs=", "integrity": "sha1-Cr9PHKpbyx96nYrMbepPqqBLrJs=",
"dev": true "dev": true
}, },
"fill-range": {
"version": "7.0.1",
"resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz",
"integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==",
"dev": true,
"requires": {
"to-regex-range": "^5.0.1"
}
},
"fs.realpath": { "fs.realpath": {
"version": "1.0.0", "version": "1.0.0",
"resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",

View File

@ -9349,35 +9349,62 @@ UINT ServeDhcpDiscoverEx(VH *v, UCHAR *mac, UINT request_ip, bool is_static_ip)
// check whether it is a request from the same MAC address // check whether it is a request from the same MAC address
if (Cmp(mac, d->MacAddress, 6) == 0) if (Cmp(mac, d->MacAddress, 6) == 0)
{ {
// Examine whether the specified IP address is within the range of static assignment // Examine whether the specified IP address is within the range of assignment
if (Endian32(v->DhcpIpStart) > Endian32(request_ip) || if (Endian32(v->DhcpIpStart) > Endian32(request_ip) ||
Endian32(request_ip) > Endian32(v->DhcpIpEnd)) Endian32(request_ip) > Endian32(v->DhcpIpEnd))
{ {
// Accept if within the range of static assignment // Accept if within the range
ret = request_ip; ret = request_ip;
} }
} }
else { else {
// Duplicated IPV4 address found. The specified IP address is not available for use // Duplicated IPV4 address found. The DHCP server replies to DHCPREQUEST with DHCP NAK.
char ipstr[MAX_HOST_NAME_LEN + 1] = { 0 }; char ipstr[MAX_HOST_NAME_LEN + 1] = { 0 };
char macstr[128] = { 0 }; char macstr[128] = { 0 };
IPToStr32(ipstr, sizeof(ipstr), request_ip); IPToStr32(ipstr, sizeof(ipstr), request_ip);
MacToStr(macstr, sizeof(macstr), d->MacAddress); BinToStr(macstr, sizeof(macstr), d->MacAddress, 6);
Debug("Virtual DHC Server: Duplicated IP address detected. Static IP: %s, with the MAC: %s\n", ipstr, macstr); Debug("Virtual DHC Server: Duplicated IP address detected. Static IP: %s, Used by MAC:%s\n", ipstr, macstr);
return ret;
} }
} }
else else
{ {
// Examine whether the specified IP address is within the range of static assignment // Examine whether the specified IP address is within the range of assignment
if (Endian32(v->DhcpIpStart) > Endian32(request_ip) || if (Endian32(v->DhcpIpStart) > Endian32(request_ip) ||
Endian32(request_ip) > Endian32(v->DhcpIpEnd)) Endian32(request_ip) > Endian32(v->DhcpIpEnd))
{ {
// Accept if within the range of static assignment // Accept if within the range
ret = request_ip; ret = request_ip;
} }
else else
{ {
// The specified IP address is not available for use // Propose an IP in the range since it's a Discover although It is out of range
}
}
if (ret == 0)
{
// If there is any entry with the same MAC address
// that are already registered, use it with priority
DHCP_LEASE *d = SearchDhcpLeaseByMac(v, mac);
if (d != NULL)
{
// Examine whether the found IP address is in the allocation region
if (Endian32(v->DhcpIpStart) > Endian32(d->IpAddress) ||
Endian32(d->IpAddress) > Endian32(v->DhcpIpEnd))
{
// Use the IP address if it's found within the range
ret = d->IpAddress;
}
}
}
if (ret == 0)
{
// For static IP, the requested IP address must NOT be within the range of the DHCP pool
if (Endian32(v->DhcpIpStart) > Endian32(request_ip) ||
Endian32(request_ip) > Endian32(v->DhcpIpEnd))
{
ret = request_ip;
} }
} }
@ -9568,11 +9595,6 @@ void VirtualDhcpServer(VH *v, PKT *p)
{ {
ip = ServeDhcpRequestEx(v, p->MacAddressSrc, opt->RequestedIp, ip_static); ip = ServeDhcpRequestEx(v, p->MacAddressSrc, opt->RequestedIp, ip_static);
} }
// If the IP address in user's note is changed, then reply to DHCP_REQUEST with DHCP_NAK
if (p->L3.IPv4Header->SrcIP && ip != p->L3.IPv4Header->SrcIP)
{
ip = 0;
}
} }
if (ip != 0 || opt->Opcode == DHCP_INFORM) if (ip != 0 || opt->Opcode == DHCP_INFORM)
@ -9585,14 +9607,6 @@ void VirtualDhcpServer(VH *v, PKT *p)
char client_mac[MAX_SIZE]; char client_mac[MAX_SIZE];
char client_ip[MAX_SIZE]; char client_ip[MAX_SIZE];
// If there is any entry with the same MAC address, then remove it
d = SearchDhcpLeaseByMac(v, p->MacAddressSrc);
if (d != NULL)
{
FreeDhcpLease(d);
Delete(v->DhcpLeaseList, d);
}
// Remove old records with the same IP address // Remove old records with the same IP address
d = SearchDhcpLeaseByIp(v, ip); d = SearchDhcpLeaseByIp(v, ip);
if (d != NULL) if (d != NULL)
@ -9751,7 +9765,7 @@ void VirtualDhcpServer(VH *v, PKT *p)
} }
else else
{ {
// Reply of DHCP_REQUEST must be either DHCP_ACK or DHCP_NAK // Reply of DHCP_REQUEST must be either DHCP_ACK or DHCP_NAK.
if (opt->Opcode == DHCP_REQUEST) if (opt->Opcode == DHCP_REQUEST)
{ {
// There is no IP address that can be provided // There is no IP address that can be provided

View File

@ -11905,9 +11905,7 @@ bool StartSSLEx3(SOCK *sock, X *x, K *priv, LIST *chain, UINT ssl_timeout, char
Unlock(openssl_lock); Unlock(openssl_lock);
} }
#if OPENSSL_VERSION_NUMBER >= 0x30000000L
SSL_set1_groups_list(sock->ssl, PQ_GROUP_LIST); SSL_set1_groups_list(sock->ssl, PQ_GROUP_LIST);
#endif
if (sock->ServerMode) if (sock->ServerMode)
{ {
@ -12289,15 +12287,9 @@ UINT SecureRecv(SOCK *sock, void *data, UINT size)
Debug("%s %u SecureRecv() Disconnect\n", __FILE__, __LINE__); Debug("%s %u SecureRecv() Disconnect\n", __FILE__, __LINE__);
return 0; return 0;
} }
ERR_clear_error();
ret = SSL_peek(ssl, &c, sizeof(c)); ret = SSL_peek(ssl, &c, sizeof(c));
} }
Unlock(sock->ssl_lock); Unlock(sock->ssl_lock);
#if OPENSSL_VERSION_NUMBER < 0x30000000L
// 2021/09/10: After OpenSSL 3.x.x, both 0 and negative values might mean retryable.
// See: https://github.com/openssl/openssl/blob/435981cbadad2c58c35bacd30ca5d8b4c9bea72f/doc/man3/SSL_read.pod
// > Old documentation indicated a difference between 0 and -1, and that -1 was retryable.
// > You should instead call SSL_get_error() to find out if it's retryable.
if (ret == 0) if (ret == 0)
{ {
// The communication have been disconnected // The communication have been disconnected
@ -12305,8 +12297,7 @@ UINT SecureRecv(SOCK *sock, void *data, UINT size)
Debug("%s %u SecureRecv() Disconnect\n", __FILE__, __LINE__); Debug("%s %u SecureRecv() Disconnect\n", __FILE__, __LINE__);
return 0; return 0;
} }
#endif if (ret < 0)
if (ret <= 0)
{ {
// An error has occurred // An error has occurred
e = SSL_get_error(ssl, ret); e = SSL_get_error(ssl, ret);
@ -12321,11 +12312,7 @@ UINT SecureRecv(SOCK *sock, void *data, UINT size)
#endif #endif
) )
{ {
UINT ssl_err_no; Debug("%s %u SSL Fatal Error on ASYNC socket !!!\n", __FILE__, __LINE__);
while (ssl_err_no = ERR_get_error()){
Debug("%s %u SSL_ERROR_SSL on ASYNC socket !!! ssl_err_no = %u: '%s'\n", __FILE__, __LINE__, ssl_err_no, ERR_error_string(ssl_err_no, NULL));
};
Disconnect(sock); Disconnect(sock);
return 0; return 0;
} }
@ -12352,15 +12339,14 @@ UINT SecureRecv(SOCK *sock, void *data, UINT size)
} }
#endif // OS_UNIX #endif // OS_UNIX
// Run the time-out thread for SOLARIS // Run the time-out thread for SOLARIS
#ifdef UNIX_SOLARIS #ifdef UNIX_SOLARIS
ttparam = NewSocketTimeout(sock); ttparam = NewSocketTimeout(sock);
#endif // UNIX_SOLARIS #endif // UNIX_SOLARIS
ERR_clear_error();
ret = SSL_read(ssl, data, size); ret = SSL_read(ssl, data, size);
// Stop the timeout thread // Stop the timeout thread
#ifdef UNIX_SOLARIS #ifdef UNIX_SOLARIS
FreeSocketTimeout(ttparam); FreeSocketTimeout(ttparam);
#endif // UNIX_SOLARIS #endif // UNIX_SOLARIS
@ -12373,11 +12359,7 @@ UINT SecureRecv(SOCK *sock, void *data, UINT size)
} }
#endif // OS_UNIX #endif // OS_UNIX
#if OPENSSL_VERSION_NUMBER < 0x30000000L if (ret < 0)
if (ret < 0) // OpenSSL version < 3.0.0
#else
if (ret <= 0) // OpenSSL version >= 3.0.0
#endif
{ {
e = SSL_get_error(ssl, ret); e = SSL_get_error(ssl, ret);
} }
@ -12400,12 +12382,6 @@ UINT SecureRecv(SOCK *sock, void *data, UINT size)
return (UINT)ret; return (UINT)ret;
} }
#if OPENSSL_VERSION_NUMBER < 0x30000000L
// 2021/09/10: After OpenSSL 3.x.x, both 0 and negative values might mean retryable.
// See: https://github.com/openssl/openssl/blob/435981cbadad2c58c35bacd30ca5d8b4c9bea72f/doc/man3/SSL_read.pod
// > Old documentation indicated a difference between 0 and -1, and that -1 was retryable.
// > You should instead call SSL_get_error() to find out if it's retryable.
if (ret == 0) if (ret == 0)
{ {
// Disconnect the communication // Disconnect the communication
@ -12413,8 +12389,6 @@ UINT SecureRecv(SOCK *sock, void *data, UINT size)
//Debug("%s %u SecureRecv() Disconnect\n", __FILE__, __LINE__); //Debug("%s %u SecureRecv() Disconnect\n", __FILE__, __LINE__);
return 0; return 0;
} }
#endif
if (sock->AsyncMode) if (sock->AsyncMode)
{ {
if (e == SSL_ERROR_WANT_READ || e == SSL_ERROR_WANT_WRITE || e == SSL_ERROR_SSL) if (e == SSL_ERROR_WANT_READ || e == SSL_ERROR_WANT_WRITE || e == SSL_ERROR_SSL)
@ -12428,11 +12402,7 @@ UINT SecureRecv(SOCK *sock, void *data, UINT size)
#endif #endif
) )
{ {
UINT ssl_err_no; Debug("%s %u SSL Fatal Error on ASYNC socket !!!\n", __FILE__, __LINE__);
while (ssl_err_no = ERR_get_error()) {
Debug("%s %u SSL_ERROR_SSL on ASYNC socket !!! ssl_err_no = %u: '%s'\n", __FILE__, __LINE__, ssl_err_no, ERR_error_string(ssl_err_no, NULL));
};
Disconnect(sock); Disconnect(sock);
return 0; return 0;
} }
@ -12441,8 +12411,8 @@ UINT SecureRecv(SOCK *sock, void *data, UINT size)
return SOCK_LATER; return SOCK_LATER;
} }
} }
Debug("%s %u e=%u SecureRecv() Disconnect\n", __FILE__, __LINE__, e);
Disconnect(sock); Disconnect(sock);
Debug("%s %u SecureRecv() Disconnect\n", __FILE__, __LINE__);
return 0; return 0;
} }
@ -12469,13 +12439,8 @@ UINT SecureSend(SOCK *sock, void *data, UINT size)
return 0; return 0;
} }
ERR_clear_error();
ret = SSL_write(ssl, data, size); ret = SSL_write(ssl, data, size);
#if OPENSSL_VERSION_NUMBER < 0x30000000L if (ret < 0)
if (ret < 0) // OpenSSL version < 3.0.0
#else
if (ret <= 0) // OpenSSL version >= 3.0.0
#endif
{ {
e = SSL_get_error(ssl, ret); e = SSL_get_error(ssl, ret);
} }
@ -12497,8 +12462,6 @@ UINT SecureSend(SOCK *sock, void *data, UINT size)
sock->WriteBlocked = false; sock->WriteBlocked = false;
return (UINT)ret; return (UINT)ret;
} }
#if OPENSSL_VERSION_NUMBER < 0x30000000L
if (ret == 0) if (ret == 0)
{ {
// Disconnect // Disconnect
@ -12506,29 +12469,18 @@ UINT SecureSend(SOCK *sock, void *data, UINT size)
Disconnect(sock); Disconnect(sock);
return 0; return 0;
} }
#endif
if (sock->AsyncMode) if (sock->AsyncMode)
{ {
// Confirmation of the error value // Confirmation of the error value
if (e == SSL_ERROR_WANT_READ || e == SSL_ERROR_WANT_WRITE || e == SSL_ERROR_SSL) if (e == SSL_ERROR_WANT_READ || e == SSL_ERROR_WANT_WRITE || e == SSL_ERROR_SSL)
{ {
if (e == SSL_ERROR_SSL)
{
UINT ssl_err_no;
while (ssl_err_no = ERR_get_error()) {
Debug("%s %u SSL_ERROR_SSL on ASYNC socket !!! ssl_err_no = %u: '%s'\n", __FILE__, __LINE__, ssl_err_no, ERR_error_string(ssl_err_no, NULL));
};
Disconnect(sock);
return 0;
}
sock->WriteBlocked = true; sock->WriteBlocked = true;
return SOCK_LATER; return SOCK_LATER;
} }
Debug("%s %u e=%u\n", __FILE__, __LINE__, e);
} }
Debug("%s %u e=%u SecureSend() Disconnect\n", __FILE__, __LINE__, e); //Debug("%s %u SecureSend() Disconnect\n", __FILE__, __LINE__);
Disconnect(sock); Disconnect(sock);
return 0; return 0;
} }

View File

@ -59,9 +59,7 @@ struct DYN_VALUE
#define DEFAULT_CIPHER_LIST "ECDHE+AESGCM:ECDHE+CHACHA20:DHE+AESGCM:DHE+CHACHA20:ECDHE+AES256:DHE+AES256:RSA+AES" #define DEFAULT_CIPHER_LIST "ECDHE+AESGCM:ECDHE+CHACHA20:DHE+AESGCM:DHE+CHACHA20:ECDHE+AES256:DHE+AES256:RSA+AES"
#if OPENSSL_VERSION_NUMBER >= 0x30000000L
#define PQ_GROUP_LIST "p521_kyber1024:x25519_kyber768:P-521:X25519:P-256" #define PQ_GROUP_LIST "p521_kyber1024:x25519_kyber768:P-521:X25519:P-256"
#endif
// SSL logging function // SSL logging function
//#define ENABLE_SSL_LOGGING //#define ENABLE_SSL_LOGGING

View File

@ -115,7 +115,7 @@ ERR_48 Не удалось подключиться к контроллер
ERR_49 Контроллеру кластера не удалось установить новую сессию в кластере. ERR_49 Контроллеру кластера не удалось установить новую сессию в кластере.
ERR_50 Не удается управлять Virtual Hub-ом сервера-члена кластера. ERR_50 Не удается управлять Virtual Hub-ом сервера-члена кластера.
ERR_51 Удаленное подключение запрещено, т.к. использован пустой пароль пользователя. Пустой пароль может быть разрешен только для соединений с локального хоста VPN-сервера (127.0.0.1). ERR_51 Удаленное подключение запрещено, т.к. использован пустой пароль пользователя. Пустой пароль может быть разрешен только для соединений с локального хоста VPN-сервера (127.0.0.1).
ERR_52 Недостаточно прав. ERR_52 Не достаточно прав.
ERR_53 Указанный порт прослушивания не найден. ERR_53 Указанный порт прослушивания не найден.
ERR_54 Указанный порт прослушивания уже существует. ERR_54 Указанный порт прослушивания уже существует.
ERR_55 Этот сервер не член кластера. ERR_55 Этот сервер не член кластера.
@ -2421,8 +2421,8 @@ STATIC17 Другие конфигурации:
R_NO_ROUTING Не вносить изменения в таблицу маршрутизации R_NO_ROUTING Не вносить изменения в таблицу маршрутизации
STATIC18 Если у вас нет опыта работы с сетью и безопасностью, то оставьте настройки в этом окне по умолчанию. STATIC18 Если у вас нет опыта работы с сетью и безопасностью, то оставьте настройки в этом окне по умолчанию.
STATIC19 Функции VoIP/QoS обрабатывают пакеты (например VoIP) с высоким приоритетом для более быстрой передачи. STATIC19 Функции VoIP/QoS обрабатывают пакеты (например VoIP) с высоким приоритетом для более быстрой передачи.
STATIC20 IP адрес источника: STATIC20 Source IP Address:
STATIC21 Номер порта: STATIC21 Source Port Number:
R_DISABLE_QOS Отключить функции VoIP / QoS R_DISABLE_QOS Отключить функции VoIP / QoS
IDOK &OK IDOK &OK
IDCANCEL Отмена IDCANCEL Отмена
@ -2524,7 +2524,7 @@ STATIC2 Имя Virtual &Hub:
STATIC3 &Пользователь: STATIC3 &Пользователь:
STATIC4 &Старый пароль: STATIC4 &Старый пароль:
STATIC5 &Новый пароль: STATIC5 &Новый пароль:
STATIC6 &Подтвердить пароль: STATIC6 &Подтвердить новый пароль:
IDOK &OK IDOK &OK
IDCANCEL Отмена IDCANCEL Отмена
S_STATIC Примечание: Вы не сможете изменить пароль пользователя, если выбран тип авторизации "RADIUS или авторизация в домене". S_STATIC Примечание: Вы не сможете изменить пароль пользователя, если выбран тип авторизации "RADIUS или авторизация в домене".
@ -2533,7 +2533,7 @@ S_STATIC Примечание: Вы не сможете изменить па
PREFIX D_SM_MAIN PREFIX D_SM_MAIN
CAPTION SoftEther VPN-сервер менеджер Developer Edition CAPTION SoftEther VPN-сервер менеджер Developer Edition
STATIC1 Настройки подключения для VPN-сервера: STATIC1 Настройки подключения для VPN-сервера:
STATIC2 Настройки подключения для VPN-сервера или VPN-моста. Чтобы подключиться к серверу дважды щелкните по его названию.\r\nЧтобы добавить новое подключение, нажмите "Новое подключение". STATIC2 Настройки подключения для VPN-сервера или VPN-моста. Чтобы подключиться к серверу дважды щелкните по его названию.\r\n Чтобы добавить новое подключение, нажмите "Новое подключение".
B_NEW_SETTING &Создать B_NEW_SETTING &Создать
B_EDIT_SETTING &Изменить B_EDIT_SETTING &Изменить
B_DELETE &Удалить B_DELETE &Удалить
@ -2558,9 +2558,9 @@ STATIC8 Прокси-сервер:
STATIC9 Вы можете подключиться к VPN-серверу через прокси-сервер. STATIC9 Вы можете подключиться к VPN-серверу через прокси-сервер.
STATIC10 Тип прокси: STATIC10 Тип прокси:
R_DIRECT_TCP &Прямое TCP/IP соединение (без прокси) R_DIRECT_TCP &Прямое TCP/IP соединение (без прокси)
R_HTTPS Через HTTP прокси-сервер R_HTTPS Подключиться через HTTP прокси-сервер
R_SOCKS Через SOCKS прокси-сервер R_SOCKS Подключиться через SOCKS прокси-сервер
R_SOCKS5 Через SOCKS5 прокси-сервер R_SOCKS5 Подключиться через SOCKS5 прокси-сервер
B_PROXY_CONFIG Настройки прокси-сервера B_PROXY_CONFIG Настройки прокси-сервера
STATIC11 Выберите режим администрирования и введите пароль STATIC11 Выберите режим администрирования и введите пароль
STATIC12 Вы можете подключиться к VPN-серверу, используя либо режим администратора сервера, либо режим Virtual Hub администратора. \r\n\r\nРежим администратора сервера позволяет вам управлять VPN-сервером и всеми Virtual Hub. \r\n\r\nРежим Virtual Hub администратора позволяет вам управлять только одним Virtual Hub, на который у вас есть права. STATIC12 Вы можете подключиться к VPN-серверу, используя либо режим администратора сервера, либо режим Virtual Hub администратора. \r\n\r\nРежим администратора сервера позволяет вам управлять VPN-сервером и всеми Virtual Hub. \r\n\r\nРежим Virtual Hub администратора позволяет вам управлять только одним Virtual Hub, на который у вас есть права.

View File

@ -373,23 +373,12 @@
} }
}, },
"braces": { "braces": {
"version": "3.0.3", "version": "3.0.2",
"resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz",
"integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==",
"dev": true, "dev": true,
"requires": { "requires": {
"fill-range": "^7.1.1" "fill-range": "^7.0.1"
},
"dependencies": {
"fill-range": {
"version": "7.1.1",
"resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz",
"integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==",
"dev": true,
"requires": {
"to-regex-range": "^5.0.1"
}
}
} }
}, },
"browserslist": { "browserslist": {
@ -614,6 +603,15 @@
"integrity": "sha512-eRnCtTTtGZFpQCwhJiUOuxPQWRXVKYDn0b2PeHfXL6/Zi53SLAzAHfVhVWK2AryC/WH05kGfxhFIPvTF0SXQzg==", "integrity": "sha512-eRnCtTTtGZFpQCwhJiUOuxPQWRXVKYDn0b2PeHfXL6/Zi53SLAzAHfVhVWK2AryC/WH05kGfxhFIPvTF0SXQzg==",
"dev": true "dev": true
}, },
"fill-range": {
"version": "7.0.1",
"resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz",
"integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==",
"dev": true,
"requires": {
"to-regex-range": "^5.0.1"
}
},
"find-up": { "find-up": {
"version": "4.1.0", "version": "4.1.0",
"resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz",