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

Implementation of the JSON-RPC API and the Web Admin interface. (dnobori's internal note: 7579 - 7682)

This commit is contained in:
Daiyuu Nobori 2019-05-28 12:51:51 +09:00
parent 03841e4181
commit 98b08c2ad1
35 changed files with 5991 additions and 231 deletions

File diff suppressed because it is too large Load Diff

View File

@ -32,6 +32,8 @@ struct ADMIN
LIST *LogFileList; // Accessible log file list
UINT ClientBuild; // Build number of the client
RPC_WINVER ClientWinVer; // Windows version of client
UINT MaxJsonRpcRecvSize; // Max JSON-RPC Receive Size
char dummy1[MAX_HUBNAME_LEN + 1]; // hubname buffer (dummy)
};
// Test
@ -118,7 +120,8 @@ struct RPC_INT
// Set Password
struct RPC_SET_PASSWORD
{
UCHAR HashedPassword[SHA1_SIZE]; // Hashed password
UCHAR HashedPassword[SHA1_SIZE]; // Hashed password (for traditional RPC)
char PlainTextPassword[MAX_SIZE]; // Plaintext password (for JSON-RPC)
};
// Server farm configuration *
@ -131,6 +134,7 @@ struct RPC_FARM
char ControllerName[MAX_HOST_NAME_LEN + 1]; // Controller name
UINT ControllerPort; // Controller port
UCHAR MemberPassword[SHA1_SIZE]; // Member password
char MemberPasswordPlaintext[MAX_SIZE]; // Member password (plaintext)
UINT Weight; // Performance ratio
bool ControllerOnly; // Only controller function
};
@ -236,6 +240,7 @@ struct RPC_CREATE_HUB
char HubName[MAX_HUBNAME_LEN + 1]; // HUB Name
UCHAR HashedPassword[SHA1_SIZE]; // Administrative password
UCHAR SecurePassword[SHA1_SIZE]; // Administrator password
char AdminPasswordPlainText[MAX_SIZE]; // Password (plaintext)
bool Online; // Online flag
RPC_HUB_OPTION HubOption; // HUB options
UINT HubType; // Type of HUB
@ -553,6 +558,7 @@ struct RPC_ENUM_SESSION_ITEM
char RemoteHostname[MAX_HOST_NAME_LEN + 1]; // Remote server name
char Username[MAX_USERNAME_LEN + 1]; // User name
UINT Ip; // IP address (IPv4)
IP ClientIP; // IP address (IPv4 / IPv6)
char Hostname[MAX_HOST_NAME_LEN + 1]; // Host name
UINT MaxNumTcp; // Maximum number of TCP connections
UINT CurrentNumTcp; // Number of currentl TCP connections
@ -569,6 +575,8 @@ struct RPC_ENUM_SESSION_ITEM
bool IsDormantEnabled; // Is the dormant state enabled
bool IsDormant; // Is in the dormant state
UINT64 LastCommDormant; // Last comm interval in the dormant state
UINT64 CreatedTime; // Creation date and time
UINT64 LastCommTime; // Last communication date and time
};
// Disconnect the session
@ -605,8 +613,9 @@ struct RPC_ENUM_IP_TABLE_ITEM
{
UINT Key; // Key
char SessionName[MAX_SESSION_NAME_LEN + 1]; // Session name
UINT Ip; // IP address
UINT Ip; // IPv4 address
IP IpV6; // IPv6 address
IP IpAddress; // IPv4 / IPv6 Address
bool DhcpAllocated; // Assigned by the DHCP
UINT64 CreatedTime; // Creation date and time
UINT64 UpdatedTime; // Updating date
@ -892,6 +901,10 @@ struct RPC_AZURE_STATUS
bool IsConnected; // Whether it's connected
};
// Constants
#define ADMIN_RPC_MAX_POST_SIZE_BY_SERVER_ADMIN MAX_PACK_SIZE
#define ADMIN_RPC_MAX_POST_SIZE_BY_HUB_ADMIN (8 * 1024 * 1024)
// Function prototype
UINT AdminAccept(CONNECTION *c, PACK *p);
@ -916,6 +929,26 @@ BUF *DownloadFileFromServer(RPC *r, char *server_name, char *filepath, UINT tota
bool CheckAdminSourceAddress(SOCK *sock, char *hubname);
void SiEnumSessionMain(SERVER *s, RPC_ENUM_SESSION *t);
bool SiIsEmptyPassword(void *hash_password);
void JsonRpcProcPost(CONNECTION *c, SOCK *s, HTTP_HEADER *h, UINT post_data_size);
void JsonRpcProcGet(CONNECTION *c, SOCK *s, HTTP_HEADER *h, char *url_target);
void JsonRpcProcOptions(CONNECTION *c, SOCK *s, HTTP_HEADER *h, char *url_target);
JSON_VALUE *JsonRpcProcRequestObject(ADMIN *admin, CONNECTION *c, SOCK *s, JSON_VALUE *json_req, char *method_name);
JSON_VALUE *JsonRpcNewError(int code, wchar_t *message);
JSON_VALUE *JsonRpcNewResponse(PACK *p);
bool HttpParseBasicAuthHeader(HTTP_HEADER *h, char *username, UINT username_size, char *password, UINT password_size);
ADMIN *JsonRpcAuthLogin(CEDAR *c, SOCK *sock, HTTP_HEADER *h);
JSON_VALUE *QueryStringToJsonListValue(char *qs);
JSON_VALUE *ConstructDummyJsonRpcRequest(char *method_name, JSON_VALUE *p);
void AdminWebProcPost(CONNECTION *c, SOCK *s, HTTP_HEADER *h, UINT post_data_size, char *url_target);
void AdminWebProcGet(CONNECTION *c, SOCK *s, HTTP_HEADER *h, char *url_target);
bool AdminWebHandleFileRequest(ADMIN *a, CONNECTION *c, SOCK *s, HTTP_HEADER *h, char *url_src, char *query_string, char *virtual_root_dir, char *physical_root_dir);
BUF *AdminWebProcessServerSideInclude(BUF *src_txt, char *filename, UINT depth);
bool AdminWebSendBody(SOCK *s, UINT status_code, char *status_string, UCHAR *data, UINT data_size, char *content_type, char *add_header_name, char *add_header_value, HTTP_HEADER *request_headers);
bool AdminWebSend404Error(SOCK *s, HTTP_HEADER *request_headers);
bool AdminWebSend302Redirect(SOCK *s, char *url, char *query_string, HTTP_HEADER *request_headers);
BUF *AdminWebTryFindAndReadFile(char *vroot, char *proot, char *url, char *ret_filename, UINT ret_filename_size, bool *is_index_html);
BUF *AdminWebTryOneFile(char *filename, char *ret_filename, UINT ret_filename_size);
bool AdminWebSendUnauthorized(SOCK *s, HTTP_HEADER *http_request_headers);
UINT StTest(ADMIN *a, RPC_TEST *t);
UINT StGetServerInfo(ADMIN *a, RPC_SERVER_INFO *t);
@ -1291,7 +1324,7 @@ void OutRpcAccess(PACK *p, ACCESS *a);
void InRpcEnumAccessList(RPC_ENUM_ACCESS_LIST *a, PACK *p);
void OutRpcEnumAccessList(PACK *p, RPC_ENUM_ACCESS_LIST *a);
void FreeRpcEnumAccessList(RPC_ENUM_ACCESS_LIST *a);
void *InRpcAuthData(PACK *p, UINT *authtype);
void *InRpcAuthData(PACK *p, UINT *authtype, char *username);
void OutRpcAuthData(PACK *p, void *authdata, UINT authtype);
void FreeRpcAuthData(void *authdata, UINT authtype);
void InRpcSetUser(RPC_SET_USER *t, PACK *p);

View File

@ -9578,8 +9578,9 @@ void CmPrintStatusToListViewEx(LVB *b, RPC_CLIENT_GET_CONNECTION_STATUS *s, bool
GetDateTimeStrEx64(tmp, sizeof(tmp), SystemToLocal64(s->StartTime), NULL);
LvInsertAdd(b, 0, NULL, 2, _UU("CM_ST_START_TIME"), tmp);
GetDateTimeStrEx64(tmp, sizeof(tmp), SystemToLocal64(s->FirstConnectionEstablishedTime), NULL);
LvInsertAdd(b, 0, NULL, 2, _UU("CM_ST_FIRST_ESTAB_TIME"), s->FirstConnectionEstablishedTime == 0 ? _UU("CM_ST_NONE") : tmp);
GetDateTimeStrEx64(tmp, sizeof(tmp), SystemToLocal64(s->FirstConnectionEstablisiedTime), NULL);
/* !!! Do not correct the spelling to keep the backward protocol compatibility !!! */
LvInsertAdd(b, 0, NULL, 2, _UU("CM_ST_FIRST_ESTAB_TIME"), s->FirstConnectionEstablisiedTime == 0 ? _UU("CM_ST_NONE") : tmp);
if (s->Connected)
{

View File

@ -137,6 +137,7 @@ typedef struct BLACK BLACK;
typedef struct SEND_SIGNATURE_PARAM SEND_SIGNATURE_PARAM;
typedef struct UPDATE_CLIENT UPDATE_CLIENT;
typedef struct UPDATE_CLIENT_SETTING UPDATE_CLIENT_SETTING;
typedef struct HTTP_MIME_TYPE HTTP_MIME_TYPE;
// ==============================================================

View File

@ -3810,14 +3810,16 @@ void OutRpcClientEnumCa(PACK *p, RPC_CLIENT_ENUM_CA *e)
PackAddNum(p, "NumItem", e->NumItem);
PackSetCurrentJsonGroupName(p, "CAList");
for (i = 0;i < e->NumItem;i++)
{
RPC_CLIENT_ENUM_CA_ITEM *item = e->Items[i];
PackAddIntEx(p, "Key", item->Key, i, e->NumItem);
PackAddUniStrEx(p, "SubjectName", item->SubjectName, i, e->NumItem);
PackAddUniStrEx(p, "IssuerName", item->IssuerName, i, e->NumItem);
PackAddInt64Ex(p, "Expires", item->Expires, i, e->NumItem);
PackAddTime64Ex(p, "Expires", item->Expires, i, e->NumItem);
}
PackSetCurrentJsonGroupName(p, NULL);
}
// RPC_GET_ISSUER
@ -4088,6 +4090,7 @@ void OutRpcClientEnumSecure(PACK *p, RPC_CLIENT_ENUM_SECURE *e)
PackAddNum(p, "NumItem", e->NumItem);
PackSetCurrentJsonGroupName(p, "SecureDeviceList");
for (i = 0;i < e->NumItem;i++)
{
RPC_CLIENT_ENUM_SECURE_ITEM *item = e->Items[i];
@ -4097,6 +4100,7 @@ void OutRpcClientEnumSecure(PACK *p, RPC_CLIENT_ENUM_SECURE *e)
PackAddStrEx(p, "DeviceName", item->DeviceName, i, e->NumItem);
PackAddStrEx(p, "Manufacturer", item->Manufacturer, i, e->NumItem);
}
PackSetCurrentJsonGroupName(p, NULL);
}
// RPC_USE_SECURE
@ -4153,11 +4157,13 @@ void OutRpcEnumObjectInSecure(PACK *p, RPC_ENUM_OBJECT_IN_SECURE *e)
PackAddNum(p, "NumItem", e->NumItem);
PackAddInt(p, "hWnd", e->hWnd);
PackSetCurrentJsonGroupName(p, "ObjectList");
for (i = 0;i < e->NumItem;i++)
{
PackAddStrEx(p, "ItemName", e->ItemName[i], i, e->NumItem);
PackAddIntEx(p, "ItemType", e->ItemType[i], i, e->NumItem);
}
PackSetCurrentJsonGroupName(p, NULL);
}
// RPC_CLIENT_CREATE_VLAN
@ -4277,6 +4283,7 @@ void OutRpcClientEnumVLan(PACK *p, RPC_CLIENT_ENUM_VLAN *v)
PackAddNum(p, "NumItem", v->NumItem);
PackSetCurrentJsonGroupName(p, "VLanList");
for (i = 0;i < v->NumItem;i++)
{
RPC_CLIENT_ENUM_VLAN_ITEM *item = v->Items[i];
@ -4286,6 +4293,7 @@ void OutRpcClientEnumVLan(PACK *p, RPC_CLIENT_ENUM_VLAN *v)
PackAddStrEx(p, "MacAddress", item->MacAddress, i, v->NumItem);
PackAddStrEx(p, "Version", item->Version, i, v->NumItem);
}
PackSetCurrentJsonGroupName(p, NULL);
}
// CLIENT_OPTION
@ -4352,10 +4360,10 @@ void OutRpcClientOption(PACK *p, CLIENT_OPTION *c)
PackAddInt(p, "NumRetry", c->NumRetry);
PackAddInt(p, "RetryInterval", c->RetryInterval);
PackAddInt(p, "MaxConnection", c->MaxConnection);
PackAddInt(p, "UseEncrypt", c->UseEncrypt);
PackAddInt(p, "UseCompress", c->UseCompress);
PackAddInt(p, "HalfConnection", c->HalfConnection);
PackAddInt(p, "NoRoutingTracking", c->NoRoutingTracking);
PackAddBool(p, "UseEncrypt", c->UseEncrypt);
PackAddBool(p, "UseCompress", c->UseCompress);
PackAddBool(p, "HalfConnection", c->HalfConnection);
PackAddBool(p, "NoRoutingTracking", c->NoRoutingTracking);
PackAddInt(p, "AdditionalConnectionInterval", c->AdditionalConnectionInterval);
PackAddInt(p, "ConnectionDisconnectSpan", c->ConnectionDisconnectSpan);
PackAddBool(p, "HideStatusWindow", c->HideStatusWindow);
@ -4568,6 +4576,7 @@ void OutRpcClientEnumAccount(PACK *p, RPC_CLIENT_ENUM_ACCOUNT *e)
PackAddNum(p, "NumItem", e->NumItem);
PackSetCurrentJsonGroupName(p, "AccountList");
for (i = 0;i < e->NumItem;i++)
{
RPC_CLIENT_ENUM_ACCOUNT_ITEM *item = e->Items[i];
@ -4583,10 +4592,11 @@ void OutRpcClientEnumAccount(PACK *p, RPC_CLIENT_ENUM_ACCOUNT *e)
PackAddBoolEx(p, "Connected", item->Connected, i, e->NumItem);
PackAddIntEx(p, "Port", item->Port, i, e->NumItem);
PackAddStrEx(p, "HubName", item->HubName, i, e->NumItem);
PackAddInt64Ex(p, "CreateDateTime", item->CreateDateTime, i, e->NumItem);
PackAddInt64Ex(p, "UpdateDateTime", item->UpdateDateTime, i, e->NumItem);
PackAddInt64Ex(p, "LastConnectDateTime", item->LastConnectDateTime, i, e->NumItem);
PackAddTime64Ex(p, "CreateDateTime", item->CreateDateTime, i, e->NumItem);
PackAddTime64Ex(p, "UpdateDateTime", item->UpdateDateTime, i, e->NumItem);
PackAddTime64Ex(p, "LastConnectDateTime", item->LastConnectDateTime, i, e->NumItem);
}
PackSetCurrentJsonGroupName(p, NULL);
}
// RPC_CLIENT_DELETE_ACCOUNT
@ -4702,9 +4712,9 @@ void OutRpcClientGetAccount(PACK *p, RPC_CLIENT_GET_ACCOUNT *c)
PackAddData(p, "ShortcutKey", c->ShortcutKey, SHA1_SIZE);
PackAddInt64(p, "CreateDateTime", c->CreateDateTime);
PackAddInt64(p, "UpdateDateTime", c->UpdateDateTime);
PackAddInt64(p, "LastConnectDateTime", c->LastConnectDateTime);
PackAddTime64(p, "CreateDateTime", c->CreateDateTime);
PackAddTime64(p, "UpdateDateTime", c->UpdateDateTime);
PackAddTime64(p, "LastConnectDateTime", c->LastConnectDateTime);
}
// RPC_CLIENT_CONNECT
@ -4792,7 +4802,8 @@ void InRpcClientGetConnectionStatus(RPC_CLIENT_GET_CONNECTION_STATUS *s, PACK *p
s->NumTcpConnectionsDownload = PackGetInt(p, "NumTcpConnectionsDownload");
s->StartTime = PackGetInt64(p, "StartTime");
s->FirstConnectionEstablishedTime = PackGetInt64(p, "FirstConnectionEstablishedTime");
/* !!! Do not correct the spelling to keep the backward protocol compatibility !!! */
s->FirstConnectionEstablisiedTime = PackGetInt64(p, "FirstConnectionEstablisiedTime");
s->CurrentConnectionEstablishTime = PackGetInt64(p, "CurrentConnectionEstablishTime");
s->TotalSendSize = PackGetInt64(p, "TotalSendSize");
s->TotalRecvSize = PackGetInt64(p, "TotalRecvSize");
@ -4852,32 +4863,32 @@ void OutRpcClientGetConnectionStatus(PACK *p, RPC_CLIENT_GET_CONNECTION_STATUS *
PackAddData(p, "SessionKey", c->SessionKey, SHA1_SIZE);
PackAddInt(p, "Active", c->Active);
PackAddInt(p, "Connected", c->Connected);
PackAddBool(p, "Active", c->Active);
PackAddBool(p, "Connected", c->Connected);
PackAddInt(p, "SessionStatus", c->SessionStatus);
PackAddInt(p, "ServerPort", c->ServerPort);
PackAddInt(p, "ServerProductVer", c->ServerProductVer);
PackAddInt(p, "ServerProductBuild", c->ServerProductBuild);
PackAddInt(p, "NumConnectionsEstablished", c->NumConnectionsEstablished);
PackAddInt(p, "HalfConnection", c->HalfConnection);
PackAddInt(p, "QoS", c->QoS);
PackAddBool(p, "HalfConnection", c->HalfConnection);
PackAddBool(p, "QoS", c->QoS);
PackAddInt(p, "MaxTcpConnections", c->MaxTcpConnections);
PackAddInt(p, "NumTcpConnections", c->NumTcpConnections);
PackAddInt(p, "NumTcpConnectionsUpload", c->NumTcpConnectionsUpload);
PackAddInt(p, "NumTcpConnectionsDownload", c->NumTcpConnectionsDownload);
PackAddInt(p, "UseEncrypt", c->UseEncrypt);
PackAddInt(p, "UseCompress", c->UseCompress);
PackAddInt(p, "IsRUDPSession", c->IsRUDPSession);
PackAddBool(p, "UseEncrypt", c->UseEncrypt);
PackAddBool(p, "UseCompress", c->UseCompress);
PackAddBool(p, "IsRUDPSession", c->IsRUDPSession);
PackAddStr(p, "UnderlayProtocol", c->UnderlayProtocol);
PackAddInt(p, "IsUdpAccelerationEnabled", c->IsUdpAccelerationEnabled);
PackAddInt(p, "IsUsingUdpAcceleration", c->IsUsingUdpAcceleration);
PackAddBool(p, "IsUdpAccelerationEnabled", c->IsUdpAccelerationEnabled);
PackAddBool(p, "IsUsingUdpAcceleration", c->IsUsingUdpAcceleration);
PackAddBool(p, "IsBridgeMode", c->IsBridgeMode);
PackAddBool(p, "IsMonitorMode", c->IsMonitorMode);
PackAddInt64(p, "StartTime", c->StartTime);
PackAddInt64(p, "FirstConnectionEstablishedTime", c->FirstConnectionEstablishedTime);
PackAddInt64(p, "CurrentConnectionEstablishTime", c->CurrentConnectionEstablishTime);
PackAddTime64(p, "StartTime", c->StartTime);
PackAddTime64(p, "FirstConnectionEstablisiedTime", c->FirstConnectionEstablisiedTime);
PackAddTime64(p, "CurrentConnectionEstablishTime", c->CurrentConnectionEstablishTime);
PackAddInt64(p, "TotalSendSize", c->TotalSendSize);
PackAddInt64(p, "TotalRecvSize", c->TotalRecvSize);
PackAddInt64(p, "TotalSendSizeReal", c->TotalSendSizeReal);
@ -5852,7 +5863,8 @@ void CiGetSessionStatus(RPC_CLIENT_GET_CONNECTION_STATUS *st, SESSION *s)
// Connection start time
st->StartTime = TickToTime(s->CreatedTime);
// Connection completion time of the first connection
st->FirstConnectionEstablishedTime = TickToTime(s->FirstConnectionEstablishedTime);
/* !!! Do not correct the spelling to keep the backward protocol compatibility !!! */
st->FirstConnectionEstablisiedTime = TickToTime(s->FirstConnectionEstablisiedTime);
// Number of connections have been established so far
st->NumConnectionsEstablished = s->NumConnectionsEstablished;
}

View File

@ -325,7 +325,8 @@ struct RPC_CLIENT_GET_CONNECTION_STATUS
X *ServerX; // Server certificate
X *ClientX; // Client certificate
UINT64 StartTime; // Connection start time
UINT64 FirstConnectionEstablishedTime; // Connection completion time of the first connection
/* !!! Do not correct the spelling to keep the backward protocol compatibility !!! */
UINT64 FirstConnectionEstablisiedTime; // Connection completion time of the first connection
UINT64 CurrentConnectionEstablishTime; // Connection completion time of this connection
UINT NumConnectionsEstablished; // Number of connections have been established so far
bool HalfConnection; // Half-connection

View File

@ -15077,8 +15077,10 @@ void CmdPrintStatusToListViewEx(CT *ct, RPC_CLIENT_GET_CONNECTION_STATUS *s, boo
GetDateTimeStrEx64(tmp, sizeof(tmp), SystemToLocal64(s->StartTime), NULL);
CtInsert(ct, _UU("CM_ST_START_TIME"), tmp);
GetDateTimeStrEx64(tmp, sizeof(tmp), SystemToLocal64(s->FirstConnectionEstablishedTime), NULL);
CtInsert(ct, _UU("CM_ST_FIRST_ESTAB_TIME"), s->FirstConnectionEstablishedTime == 0 ? _UU("CM_ST_NONE") : tmp);
/* !!! Do not correct the spelling to keep the backward protocol compatibility !!! */
GetDateTimeStrEx64(tmp, sizeof(tmp), SystemToLocal64(s->FirstConnectionEstablisiedTime), NULL);
/* !!! Do not correct the spelling to keep the backward protocol compatibility !!! */
CtInsert(ct, _UU("CM_ST_FIRST_ESTAB_TIME"), s->FirstConnectionEstablisiedTime == 0 ? _UU("CM_ST_NONE") : tmp);
if (s->Connected)
{

View File

@ -216,6 +216,9 @@ struct CONNECTION
UINT LastPacketQueueSize; // The last queue size of packets
UINT LastRecvFifoTotalSize; // The last RecvFifo total size
UINT LastRecvBlocksNum; // The last ReceivedBlocks num
bool IsJsonRpc; // Is JSON-RPC
bool JsonRpcAuthed; // JSON-RPC Authed
LISTENER *Listener; // Listener ref
};

View File

@ -37,6 +37,9 @@ void DCGetStatus(DDNS_CLIENT *c, DDNS_CLIENT_STATUS *st)
Copy(&st->InternetSetting, &c->InternetSetting, sizeof(INTERNET_SETTING));
}
Unlock(c->Lock);
UniStrCpy(st->ErrStr_IPv4, sizeof(st->ErrStr_IPv4), _E(st->Err_IPv4));
UniStrCpy(st->ErrStr_IPv6, sizeof(st->ErrStr_IPv6), _E(st->Err_IPv6));
}
// Set the Internet settings

View File

@ -111,6 +111,8 @@ struct DDNS_REGISTER_PARAM
struct DDNS_CLIENT_STATUS
{
UINT Err_IPv4, Err_IPv6; // Last error
wchar_t ErrStr_IPv4[MAX_SIZE];
wchar_t ErrStr_IPv6[MAX_SIZE];
char CurrentHostName[DDNS_MAX_HOSTNAME + 1]; // Current host name
char CurrentFqdn[MAX_SIZE]; // Current FQDN
char DnsSuffix[MAX_SIZE]; // DNS suffix

View File

@ -558,6 +558,7 @@ void OutRpcEnumDevice(PACK *p, RPC_ENUM_DEVICE *t)
PackAddInt(p, "NumItem", t->NumItem);
PackSetCurrentJsonGroupName(p, "DeviceList");
for (i = 0;i < t->NumItem;i++)
{
RPC_ENUM_DEVICE_ITEM *d = &t->Items[i];
@ -565,6 +566,7 @@ void OutRpcEnumDevice(PACK *p, RPC_ENUM_DEVICE *t)
PackAddStrEx(p, "DeviceName", d->DeviceName, i, t->NumItem);
PackAddBoolEx(p, "Active", d->Active, i, t->NumItem);
}
PackSetCurrentJsonGroupName(p, NULL);
PackAddBool(p, "IsLicenseSupported", t->IsLicenseSupported);
}
@ -605,7 +607,7 @@ void OutRpcElLicenseStatus(PACK *p, RPC_EL_LICENSE_STATUS *t)
PackAddBool(p, "Valid", t->Valid);
PackAddInt64(p, "SystemId", t->SystemId);
PackAddInt64(p, "SystemExpires", t->SystemExpires);
PackAddTime64(p, "SystemExpires", t->SystemExpires);
}
// Listener thread

View File

@ -681,6 +681,8 @@ void HubOptionStructToData(RPC_ADMIN_OPTION *ao, HUB_OPTION *o, char *hub_name)
{
ADMIN_OPTION *a = LIST_DATA(aol, i);
UniStrCpy(a->Descrption, sizeof(a->Descrption), GetHubAdminOptionHelpString(a->Name));
Copy(&ao->Items[i], a, sizeof(ADMIN_OPTION));
Free(a);

View File

@ -287,6 +287,7 @@ struct ADMIN_OPTION
{
char Name[MAX_ADMIN_OPTION_NAME_LEN + 1]; // Name
UINT Value; // Data
wchar_t Descrption[MAX_SIZE]; // Descrption
};
// Certificate Revocation List entry

View File

@ -150,6 +150,9 @@ void TCPAcceptedThread(THREAD *t, void *param)
// Create a connection
c = NewServerConnection(r->Cedar, s, t);
AddRef(r->ref);
c->Listener = r;
// Register to Cedar as a transient connection
AddConnection(c->Cedar, c);
@ -169,6 +172,8 @@ void TCPAcceptedThread(THREAD *t, void *param)
// Release
SLog(r->Cedar, "LS_CONNECTION_END_1", c->Name);
ReleaseListener(c->Listener);
c->Listener = NULL;
ReleaseConnection(c);
// Release

View File

@ -797,18 +797,20 @@ void OutRpcEnumDhcp(PACK *p, RPC_ENUM_DHCP *t)
PackAddInt(p, "NumItem", t->NumItem);
PackAddStr(p, "HubName", t->HubName);
PackSetCurrentJsonGroupName(p, "DhcpTable");
for (i = 0;i < t->NumItem;i++)
{
RPC_ENUM_DHCP_ITEM *e = &t->Items[i];
PackAddIntEx(p, "Id", e->Id, i, t->NumItem);
PackAddInt64Ex(p, "LeasedTime", e->LeasedTime, i, t->NumItem);
PackAddInt64Ex(p, "ExpireTime", e->ExpireTime, i, t->NumItem);
PackAddTime64Ex(p, "LeasedTime", e->LeasedTime, i, t->NumItem);
PackAddTime64Ex(p, "ExpireTime", e->ExpireTime, i, t->NumItem);
PackAddDataEx(p, "MacAddress", e->MacAddress, 6, i, t->NumItem);
PackAddIp32Ex(p, "IpAddress", e->IpAddress, i, t->NumItem);
PackAddIntEx(p, "Mask", e->Mask, i, t->NumItem);
PackAddStrEx(p, "Hostname", e->Hostname, i, t->NumItem);
}
PackSetCurrentJsonGroupName(p, NULL);
}
void FreeRpcEnumDhcp(RPC_ENUM_DHCP *t)
{
@ -865,6 +867,8 @@ void OutRpcEnumNat(PACK *p, RPC_ENUM_NAT *t)
PackAddInt(p, "NumItem", t->NumItem);
PackAddStr(p, "HubName", t->HubName);
PackSetCurrentJsonGroupName(p, "NatTable");
for (i = 0;i < t->NumItem;i++)
{
RPC_ENUM_NAT_ITEM *e = &t->Items[i];
@ -877,12 +881,13 @@ void OutRpcEnumNat(PACK *p, RPC_ENUM_NAT *t)
PackAddIp32Ex(p, "DestIp", e->DestIp, i, t->NumItem);
PackAddStrEx(p, "DestHost", e->DestHost, i, t->NumItem);
PackAddIntEx(p, "DestPort", e->DestPort, i, t->NumItem);
PackAddInt64Ex(p, "CreatedTime", e->CreatedTime, i, t->NumItem);
PackAddInt64Ex(p, "LastCommTime", e->LastCommTime, i, t->NumItem);
PackAddTime64Ex(p, "CreatedTime", e->CreatedTime, i, t->NumItem);
PackAddTime64Ex(p, "LastCommTime", e->LastCommTime, i, t->NumItem);
PackAddInt64Ex(p, "SendSize", e->SendSize, i, t->NumItem);
PackAddInt64Ex(p, "RecvSize", e->RecvSize, i, t->NumItem);
PackAddIntEx(p, "TcpStatus", e->TcpStatus, i, t->NumItem);
}
PackSetCurrentJsonGroupName(p, NULL);
}
void FreeRpcEnumNat(RPC_ENUM_NAT *t)
{

View File

@ -9,6 +9,726 @@
static UCHAR ssl_packet_start[3] = {0x17, 0x03, 0x00};
// MIME list from https://www.freeformatter.com/mime-types-list.html
static HTTP_MIME_TYPE http_mime_types[] =
{
{".x3d", "application/vnd.hzn-3d-crossword"},
{".3gp", "video/3gpp"},
{".3g2", "video/3gpp2"},
{".mseq", "application/vnd.mseq"},
{".pwn", "application/vnd.3m.post-it-notes"},
{".plb", "application/vnd.3gpp.pic-bw-large"},
{".psb", "application/vnd.3gpp.pic-bw-small"},
{".pvb", "application/vnd.3gpp.pic-bw-var"},
{".tcap", "application/vnd.3gpp2.tcap"},
{".7z", "application/x-7z-compressed"},
{".abw", "application/x-abiword"},
{".ace", "application/x-ace-compressed"},
{".acc", "application/vnd.americandynamics.acc"},
{".acu", "application/vnd.acucobol"},
{".atc", "application/vnd.acucorp"},
{".adp", "audio/adpcm"},
{".aab", "application/x-authorware-bin"},
{".aam", "application/x-authorware-map"},
{".aas", "application/x-authorware-seg"},
{".air", "application/vnd.adobe.air-application-installer-package+zip"},
{".swf", "application/x-shockwave-flash"},
{".fxp", "application/vnd.adobe.fxp"},
{".pdf", "application/pdf"},
{".ppd", "application/vnd.cups-ppd"},
{".dir", "application/x-director"},
{".xdp", "application/vnd.adobe.xdp+xml"},
{".xfdf", "application/vnd.adobe.xfdf"},
{".aac", "audio/x-aac"},
{".ahead", "application/vnd.ahead.space"},
{".azf", "application/vnd.airzip.filesecure.azf"},
{".azs", "application/vnd.airzip.filesecure.azs"},
{".azw", "application/vnd.amazon.ebook"},
{".ami", "application/vnd.amiga.ami"},
{".apk", "application/vnd.android.package-archive"},
{".cii", "application/vnd.anser-web-certificate-issue-initiation"},
{".fti", "application/vnd.anser-web-funds-transfer-initiation"},
{".atx", "application/vnd.antix.game-component"},
{".dmg", "application/x-apple-diskimage"},
{".mpkg", "application/vnd.apple.installer+xml"},
{".aw", "application/applixware"},
{".les", "application/vnd.hhe.lesson-player"},
{".swi", "application/vnd.aristanetworks.swi"},
{".s", "text/x-asm"},
{".atomcat", "application/atomcat+xml"},
{".atomsvc", "application/atomsvc+xml"},
{".atom", "application/atom+xml"},
{".ac", "application/pkix-attr-cert"},
{".aif", "audio/x-aiff"},
{".avi", "video/x-msvideo"},
{".aep", "application/vnd.audiograph"},
{".dxf", "image/vnd.dxf"},
{".dwf", "model/vnd.dwf"},
{".par", "text/plain-bas"},
{".bcpio", "application/x-bcpio"},
{".bin", "application/octet-stream"},
{".bmp", "image/bmp"},
{".torrent", "application/x-bittorrent"},
{".cod", "application/vnd.rim.cod"},
{".mpm", "application/vnd.blueice.multipass"},
{".bmi", "application/vnd.bmi"},
{".sh", "application/x-sh"},
{".btif", "image/prs.btif"},
{".rep", "application/vnd.businessobjects"},
{".bz", "application/x-bzip"},
{".bz2", "application/x-bzip2"},
{".csh", "application/x-csh"},
{".c", "text/x-c"},
{".cdxml", "application/vnd.chemdraw+xml"},
{".css", "text/css"},
{".cdx", "chemical/x-cdx"},
{".cml", "chemical/x-cml"},
{".csml", "chemical/x-csml"},
{".cdbcmsg", "application/vnd.contact.cmsg"},
{".cla", "application/vnd.claymore"},
{".c4g", "application/vnd.clonk.c4group"},
{".sub", "image/vnd.dvb.subtitle"},
{".cdmia", "application/cdmi-capability"},
{".cdmic", "application/cdmi-container"},
{".cdmid", "application/cdmi-domain"},
{".cdmio", "application/cdmi-object"},
{".cdmiq", "application/cdmi-queue"},
{".c11amc", "application/vnd.cluetrust.cartomobile-config"},
{".c11amz", "application/vnd.cluetrust.cartomobile-config-pkg"},
{".ras", "image/x-cmu-raster"},
{".dae", "model/vnd.collada+xml"},
{".csv", "text/csv"},
{".cpt", "application/mac-compactpro"},
{".wmlc", "application/vnd.wap.wmlc"},
{".cgm", "image/cgm"},
{".ice", "x-conference/x-cooltalk"},
{".cmx", "image/x-cmx"},
{".xar", "application/vnd.xara"},
{".cmc", "application/vnd.cosmocaller"},
{".cpio", "application/x-cpio"},
{".clkx", "application/vnd.crick.clicker"},
{".clkk", "application/vnd.crick.clicker.keyboard"},
{".clkp", "application/vnd.crick.clicker.palette"},
{".clkt", "application/vnd.crick.clicker.template"},
{".clkw", "application/vnd.crick.clicker.wordbank"},
{".wbs", "application/vnd.criticaltools.wbs+xml"},
{".cryptonote", "application/vnd.rig.cryptonote"},
{".cif", "chemical/x-cif"},
{".cmdf", "chemical/x-cmdf"},
{".cu", "application/cu-seeme"},
{".cww", "application/prs.cww"},
{".curl", "text/vnd.curl"},
{".dcurl", "text/vnd.curl.dcurl"},
{".mcurl", "text/vnd.curl.mcurl"},
{".scurl", "text/vnd.curl.scurl"},
{".car", "application/vnd.curl.car"},
{".pcurl", "application/vnd.curl.pcurl"},
{".cmp", "application/vnd.yellowriver-custom-menu"},
{".dssc", "application/dssc+der"},
{".xdssc", "application/dssc+xml"},
{".deb", "application/x-debian-package"},
{".uva", "audio/vnd.dece.audio"},
{".uvi", "image/vnd.dece.graphic"},
{".uvh", "video/vnd.dece.hd"},
{".uvm", "video/vnd.dece.mobile"},
{".uvu", "video/vnd.uvvu.mp4"},
{".uvp", "video/vnd.dece.pd"},
{".uvs", "video/vnd.dece.sd"},
{".uvv", "video/vnd.dece.video"},
{".dvi", "application/x-dvi"},
{".seed", "application/vnd.fdsn.seed"},
{".dtb", "application/x-dtbook+xml"},
{".res", "application/x-dtbresource+xml"},
{".ait", "application/vnd.dvb.ait"},
{".svc", "application/vnd.dvb.service"},
{".eol", "audio/vnd.digital-winds"},
{".djvu", "image/vnd.djvu"},
{".dtd", "application/xml-dtd"},
{".mlp", "application/vnd.dolby.mlp"},
{".wad", "application/x-doom"},
{".dpg", "application/vnd.dpgraph"},
{".dra", "audio/vnd.dra"},
{".dfac", "application/vnd.dreamfactory"},
{".dts", "audio/vnd.dts"},
{".dtshd", "audio/vnd.dts.hd"},
{".dwg", "image/vnd.dwg"},
{".geo", "application/vnd.dynageo"},
{".es", "application/ecmascript"},
{".mag", "application/vnd.ecowin.chart"},
{".mmr", "image/vnd.fujixerox.edmics-mmr"},
{".rlc", "image/vnd.fujixerox.edmics-rlc"},
{".exi", "application/exi"},
{".mgz", "application/vnd.proteus.magazine"},
{".epub", "application/epub+zip"},
{".eml", "message/rfc822"},
{".nml", "application/vnd.enliven"},
{".xpr", "application/vnd.is-xpr"},
{".xif", "image/vnd.xiff"},
{".xfdl", "application/vnd.xfdl"},
{".emma", "application/emma+xml"},
{".ez2", "application/vnd.ezpix-album"},
{".ez3", "application/vnd.ezpix-package"},
{".fst", "image/vnd.fst"},
{".fvt", "video/vnd.fvt"},
{".fbs", "image/vnd.fastbidsheet"},
{".fe_launch", "application/vnd.denovo.fcselayout-link"},
{".f4v", "video/x-f4v"},
{".flv", "video/x-flv"},
{".fpx", "image/vnd.fpx"},
{".npx", "image/vnd.net-fpx"},
{".flx", "text/vnd.fmi.flexstor"},
{".fli", "video/x-fli"},
{".ftc", "application/vnd.fluxtime.clip"},
{".fdf", "application/vnd.fdf"},
{".f", "text/x-fortran"},
{".mif", "application/vnd.mif"},
{".fm", "application/vnd.framemaker"},
{".fh", "image/x-freehand"},
{".fsc", "application/vnd.fsc.weblaunch"},
{".fnc", "application/vnd.frogans.fnc"},
{".ltf", "application/vnd.frogans.ltf"},
{".ddd", "application/vnd.fujixerox.ddd"},
{".xdw", "application/vnd.fujixerox.docuworks"},
{".xbd", "application/vnd.fujixerox.docuworks.binder"},
{".oas", "application/vnd.fujitsu.oasys"},
{".oa2", "application/vnd.fujitsu.oasys2"},
{".oa3", "application/vnd.fujitsu.oasys3"},
{".fg5", "application/vnd.fujitsu.oasysgp"},
{".bh2", "application/vnd.fujitsu.oasysprs"},
{".spl", "application/x-futuresplash"},
{".fzs", "application/vnd.fuzzysheet"},
{".g3", "image/g3fax"},
{".gmx", "application/vnd.gmx"},
{".gtw", "model/vnd.gtw"},
{".txd", "application/vnd.genomatix.tuxedo"},
{".ggb", "application/vnd.geogebra.file"},
{".ggt", "application/vnd.geogebra.tool"},
{".gdl", "model/vnd.gdl"},
{".gex", "application/vnd.geometry-explorer"},
{".gxt", "application/vnd.geonext"},
{".g2w", "application/vnd.geoplan"},
{".g3w", "application/vnd.geospace"},
{".gsf", "application/x-font-ghostscript"},
{".bdf", "application/x-font-bdf"},
{".gtar", "application/x-gtar"},
{".texinfo", "application/x-texinfo"},
{".gnumeric", "application/x-gnumeric"},
{".kml", "application/vnd.google-earth.kml+xml"},
{".kmz", "application/vnd.google-earth.kmz"},
{".gqf", "application/vnd.grafeq"},
{".gif", "image/gif"},
{".gv", "text/vnd.graphviz"},
{".gac", "application/vnd.groove-account"},
{".ghf", "application/vnd.groove-help"},
{".gim", "application/vnd.groove-identity-message"},
{".grv", "application/vnd.groove-injector"},
{".gtm", "application/vnd.groove-tool-message"},
{".tpl", "application/vnd.groove-tool-template"},
{".vcg", "application/vnd.groove-vcard"},
{".h261", "video/h261"},
{".h263", "video/h263"},
{".h264", "video/h264"},
{".hpid", "application/vnd.hp-hpid"},
{".hps", "application/vnd.hp-hps"},
{".hdf", "application/x-hdf"},
{".rip", "audio/vnd.rip"},
{".hbci", "application/vnd.hbci"},
{".jlt", "application/vnd.hp-jlyt"},
{".pcl", "application/vnd.hp-pcl"},
{".hpgl", "application/vnd.hp-hpgl"},
{".hvs", "application/vnd.yamaha.hv-script"},
{".hvd", "application/vnd.yamaha.hv-dic"},
{".hvp", "application/vnd.yamaha.hv-voice"},
{".sfd-hdstx", "application/vnd.hydrostatix.sof-data"},
{".stk", "application/hyperstudio"},
{".hal", "application/vnd.hal+xml"},
{".htm", "text/html; charset=utf-8"},
{".html", "text/html; charset=utf-8"},
{".irm", "application/vnd.ibm.rights-management"},
{".sc", "application/vnd.ibm.secure-container"},
{".ics", "text/calendar"},
{".icc", "application/vnd.iccprofile"},
{".ico", "image/x-icon"},
{".igl", "application/vnd.igloader"},
{".ief", "image/ief"},
{".ivp", "application/vnd.immervision-ivp"},
{".ivu", "application/vnd.immervision-ivu"},
{".rif", "application/reginfo+xml"},
{".3dml", "text/vnd.in3d.3dml"},
{".spot", "text/vnd.in3d.spot"},
{".igs", "model/iges"},
{".i2g", "application/vnd.intergeo"},
{".cdy", "application/vnd.cinderella"},
{".xpw", "application/vnd.intercon.formnet"},
{".fcs", "application/vnd.isac.fcs"},
{".ipfix", "application/ipfix"},
{".cer", "application/pkix-cert"},
{".pki", "application/pkixcmp"},
{".crl", "application/pkix-crl"},
{".pkipath", "application/pkix-pkipath"},
{".igm", "application/vnd.insors.igm"},
{".rcprofile", "application/vnd.ipunplugged.rcprofile"},
{".irp", "application/vnd.irepository.package+xml"},
{".jad", "text/vnd.sun.j2me.app-descriptor"},
{".jar", "application/java-archive"},
{".class", "application/java-vm"},
{".jnlp", "application/x-java-jnlp-file"},
{".ser", "application/java-serialized-object"},
{".java", "text/x-java-source"},
{".js", "application/javascript"},
{".json", "application/json"},
{".joda", "application/vnd.joost.joda-archive"},
{".jpm", "video/jpm"},
{".jpg", "image/jpeg"},
{".jpeg", "image/jpeg"},
{".pjpeg", "image/pjpeg"},
{".jpgv", "video/jpeg"},
{".ktz", "application/vnd.kahootz"},
{".mmd", "application/vnd.chipnuts.karaoke-mmd"},
{".karbon", "application/vnd.kde.karbon"},
{".chrt", "application/vnd.kde.kchart"},
{".kfo", "application/vnd.kde.kformula"},
{".flw", "application/vnd.kde.kivio"},
{".kon", "application/vnd.kde.kontour"},
{".kpr", "application/vnd.kde.kpresenter"},
{".ksp", "application/vnd.kde.kspread"},
{".kwd", "application/vnd.kde.kword"},
{".htke", "application/vnd.kenameaapp"},
{".kia", "application/vnd.kidspiration"},
{".kne", "application/vnd.kinar"},
{".sse", "application/vnd.kodak-descriptor"},
{".lasxml", "application/vnd.las.las+xml"},
{".latex", "application/x-latex"},
{".lbd", "application/vnd.llamagraphics.life-balance.desktop"},
{".lbe", "application/vnd.llamagraphics.life-balance.exchange+xml"},
{".jam", "application/vnd.jam"},
{"0.123", "application/vnd.lotus-1-2-3"},
{".apr", "application/vnd.lotus-approach"},
{".pre", "application/vnd.lotus-freelance"},
{".nsf", "application/vnd.lotus-notes"},
{".org", "application/vnd.lotus-organizer"},
{".scm", "application/vnd.lotus-screencam"},
{".lwp", "application/vnd.lotus-wordpro"},
{".lvp", "audio/vnd.lucent.voice"},
{".m3u", "audio/x-mpegurl"},
{".m4v", "video/x-m4v"},
{".hqx", "application/mac-binhex40"},
{".portpkg", "application/vnd.macports.portpkg"},
{".mgp", "application/vnd.osgeo.mapguide.package"},
{".mrc", "application/marc"},
{".mrcx", "application/marcxml+xml"},
{".mxf", "application/mxf"},
{".nbp", "application/vnd.wolfram.player"},
{".ma", "application/mathematica"},
{".mathml", "application/mathml+xml"},
{".mbox", "application/mbox"},
{".mc1", "application/vnd.medcalcdata"},
{".mscml", "application/mediaservercontrol+xml"},
{".cdkey", "application/vnd.mediastation.cdkey"},
{".mwf", "application/vnd.mfer"},
{".mfm", "application/vnd.mfmp"},
{".msh", "model/mesh"},
{".mads", "application/mads+xml"},
{".mets", "application/mets+xml"},
{".mods", "application/mods+xml"},
{".meta4", "application/metalink4+xml"},
{".mcd", "application/vnd.mcd"},
{".flo", "application/vnd.micrografx.flo"},
{".igx", "application/vnd.micrografx.igx"},
{".es3", "application/vnd.eszigno3+xml"},
{".mdb", "application/x-msaccess"},
{".asf", "video/x-ms-asf"},
{".exe", "application/x-msdownload"},
{".cil", "application/vnd.ms-artgalry"},
{".cab", "application/vnd.ms-cab-compressed"},
{".ims", "application/vnd.ms-ims"},
{".application", "application/x-ms-application"},
{".clp", "application/x-msclip"},
{".mdi", "image/vnd.ms-modi"},
{".eot", "application/vnd.ms-fontobject"},
{".xls", "application/vnd.ms-excel"},
{".xlam", "application/vnd.ms-excel.addin.macroenabled.12"},
{".xlsb", "application/vnd.ms-excel.sheet.binary.macroenabled.12"},
{".xltm", "application/vnd.ms-excel.template.macroenabled.12"},
{".xlsm", "application/vnd.ms-excel.sheet.macroenabled.12"},
{".chm", "application/vnd.ms-htmlhelp"},
{".crd", "application/x-mscardfile"},
{".lrm", "application/vnd.ms-lrm"},
{".mvb", "application/x-msmediaview"},
{".mny", "application/x-msmoney"},
{".pptx", "application/vnd.openxmlformats-officedocument.presentationml.presentation"},
{".sldx", "application/vnd.openxmlformats-officedocument.presentationml.slide"},
{".ppsx", "application/vnd.openxmlformats-officedocument.presentationml.slideshow"},
{".potx", "application/vnd.openxmlformats-officedocument.presentationml.template"},
{".xlsx", "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"},
{".xltx", "application/vnd.openxmlformats-officedocument.spreadsheetml.template"},
{".docx", "application/vnd.openxmlformats-officedocument.wordprocessingml.document"},
{".dotx", "application/vnd.openxmlformats-officedocument.wordprocessingml.template"},
{".obd", "application/x-msbinder"},
{".thmx", "application/vnd.ms-officetheme"},
{".onetoc", "application/onenote"},
{".pya", "audio/vnd.ms-playready.media.pya"},
{".pyv", "video/vnd.ms-playready.media.pyv"},
{".ppt", "application/vnd.ms-powerpoint"},
{".ppam", "application/vnd.ms-powerpoint.addin.macroenabled.12"},
{".sldm", "application/vnd.ms-powerpoint.slide.macroenabled.12"},
{".pptm", "application/vnd.ms-powerpoint.presentation.macroenabled.12"},
{".ppsm", "application/vnd.ms-powerpoint.slideshow.macroenabled.12"},
{".potm", "application/vnd.ms-powerpoint.template.macroenabled.12"},
{".mpp", "application/vnd.ms-project"},
{".pub", "application/x-mspublisher"},
{".scd", "application/x-msschedule"},
{".xap", "application/x-silverlight-app"},
{".stl", "application/vnd.ms-pki.stl"},
{".cat", "application/vnd.ms-pki.seccat"},
{".vsd", "application/vnd.visio"},
{".vsdx", "application/vnd.visio2013"},
{".wm", "video/x-ms-wm"},
{".wma", "audio/x-ms-wma"},
{".wax", "audio/x-ms-wax"},
{".wmx", "video/x-ms-wmx"},
{".wmd", "application/x-ms-wmd"},
{".wpl", "application/vnd.ms-wpl"},
{".wmz", "application/x-ms-wmz"},
{".wmv", "video/x-ms-wmv"},
{".wvx", "video/x-ms-wvx"},
{".wmf", "application/x-msmetafile"},
{".trm", "application/x-msterminal"},
{".doc", "application/msword"},
{".docm", "application/vnd.ms-word.document.macroenabled.12"},
{".dotm", "application/vnd.ms-word.template.macroenabled.12"},
{".wri", "application/x-mswrite"},
{".wps", "application/vnd.ms-works"},
{".xbap", "application/x-ms-xbap"},
{".xps", "application/vnd.ms-xpsdocument"},
{".mid", "audio/midi"},
{".mpy", "application/vnd.ibm.minipay"},
{".afp", "application/vnd.ibm.modcap"},
{".rms", "application/vnd.jcp.javame.midlet-rms"},
{".tmo", "application/vnd.tmobile-livetv"},
{".prc", "application/x-mobipocket-ebook"},
{".mbk", "application/vnd.mobius.mbk"},
{".dis", "application/vnd.mobius.dis"},
{".plc", "application/vnd.mobius.plc"},
{".mqy", "application/vnd.mobius.mqy"},
{".msl", "application/vnd.mobius.msl"},
{".txf", "application/vnd.mobius.txf"},
{".daf", "application/vnd.mobius.daf"},
{".fly", "text/vnd.fly"},
{".mpc", "application/vnd.mophun.certificate"},
{".mpn", "application/vnd.mophun.application"},
{".mj2", "video/mj2"},
{".mpga", "audio/mpeg"},
{".mxu", "video/vnd.mpegurl"},
{".mpeg", "video/mpeg"},
{".m21", "application/mp21"},
{".mp4a", "audio/mp4"},
{".mp4", "video/mp4"},
{".mp4", "application/mp4"},
{".m3u8", "application/vnd.apple.mpegurl"},
{".mus", "application/vnd.musician"},
{".msty", "application/vnd.muvee.style"},
{".mxml", "application/xv+xml"},
{".ngdat", "application/vnd.nokia.n-gage.data"},
{".n-gage", "application/vnd.nokia.n-gage.symbian.install"},
{".ncx", "application/x-dtbncx+xml"},
{".nc", "application/x-netcdf"},
{".nlu", "application/vnd.neurolanguage.nlu"},
{".dna", "application/vnd.dna"},
{".nnd", "application/vnd.noblenet-directory"},
{".nns", "application/vnd.noblenet-sealer"},
{".nnw", "application/vnd.noblenet-web"},
{".rpst", "application/vnd.nokia.radio-preset"},
{".rpss", "application/vnd.nokia.radio-presets"},
{".n3", "text/n3"},
{".edm", "application/vnd.novadigm.edm"},
{".edx", "application/vnd.novadigm.edx"},
{".ext", "application/vnd.novadigm.ext"},
{".gph", "application/vnd.flographit"},
{".ecelp4800", "audio/vnd.nuera.ecelp4800"},
{".ecelp7470", "audio/vnd.nuera.ecelp7470"},
{".ecelp9600", "audio/vnd.nuera.ecelp9600"},
{".oda", "application/oda"},
{".ogx", "application/ogg"},
{".oga", "audio/ogg"},
{".ogv", "video/ogg"},
{".dd2", "application/vnd.oma.dd2+xml"},
{".oth", "application/vnd.oasis.opendocument.text-web"},
{".opf", "application/oebps-package+xml"},
{".qbo", "application/vnd.intu.qbo"},
{".oxt", "application/vnd.openofficeorg.extension"},
{".osf", "application/vnd.yamaha.openscoreformat"},
{".weba", "audio/webm"},
{".webm", "video/webm"},
{".odc", "application/vnd.oasis.opendocument.chart"},
{".otc", "application/vnd.oasis.opendocument.chart-template"},
{".odb", "application/vnd.oasis.opendocument.database"},
{".odf", "application/vnd.oasis.opendocument.formula"},
{".odft", "application/vnd.oasis.opendocument.formula-template"},
{".odg", "application/vnd.oasis.opendocument.graphics"},
{".otg", "application/vnd.oasis.opendocument.graphics-template"},
{".odi", "application/vnd.oasis.opendocument.image"},
{".oti", "application/vnd.oasis.opendocument.image-template"},
{".odp", "application/vnd.oasis.opendocument.presentation"},
{".otp", "application/vnd.oasis.opendocument.presentation-template"},
{".ods", "application/vnd.oasis.opendocument.spreadsheet"},
{".ots", "application/vnd.oasis.opendocument.spreadsheet-template"},
{".odt", "application/vnd.oasis.opendocument.text"},
{".odm", "application/vnd.oasis.opendocument.text-master"},
{".ott", "application/vnd.oasis.opendocument.text-template"},
{".ktx", "image/ktx"},
{".sxc", "application/vnd.sun.xml.calc"},
{".stc", "application/vnd.sun.xml.calc.template"},
{".sxd", "application/vnd.sun.xml.draw"},
{".std", "application/vnd.sun.xml.draw.template"},
{".sxi", "application/vnd.sun.xml.impress"},
{".sti", "application/vnd.sun.xml.impress.template"},
{".sxm", "application/vnd.sun.xml.math"},
{".sxw", "application/vnd.sun.xml.writer"},
{".sxg", "application/vnd.sun.xml.writer.global"},
{".stw", "application/vnd.sun.xml.writer.template"},
{".otf", "application/x-font-otf"},
{".osfpvg", "application/vnd.yamaha.openscoreformat.osfpvg+xml"},
{".dp", "application/vnd.osgi.dp"},
{".pdb", "application/vnd.palm"},
{".p", "text/x-pascal"},
{".paw", "application/vnd.pawaafile"},
{".pclxl", "application/vnd.hp-pclxl"},
{".efif", "application/vnd.picsel"},
{".pcx", "image/x-pcx"},
{".psd", "image/vnd.adobe.photoshop"},
{".prf", "application/pics-rules"},
{".pic", "image/x-pict"},
{".chat", "application/x-chat"},
{".p10", "application/pkcs10"},
{".p12", "application/x-pkcs12"},
{".p7m", "application/pkcs7-mime"},
{".p7s", "application/pkcs7-signature"},
{".p7r", "application/x-pkcs7-certreqresp"},
{".p7b", "application/x-pkcs7-certificates"},
{".p8", "application/pkcs8"},
{".plf", "application/vnd.pocketlearn"},
{".pnm", "image/x-portable-anymap"},
{".pbm", "image/x-portable-bitmap"},
{".pcf", "application/x-font-pcf"},
{".pfr", "application/font-tdpfr"},
{".pgn", "application/x-chess-pgn"},
{".pgm", "image/x-portable-graymap"},
{".png", "image/png"},
{".png", "image/x-citrix-png"},
{".png", "image/x-png"},
{".ppm", "image/x-portable-pixmap"},
{".pskcxml", "application/pskc+xml"},
{".pml", "application/vnd.ctc-posml"},
{".ai", "application/postscript"},
{".pfa", "application/x-font-type1"},
{".pbd", "application/vnd.powerbuilder6"},
{".pgp", "application/pgp-encrypted"},
{".pgp", "application/pgp-signature"},
{".box", "application/vnd.previewsystems.box"},
{".ptid", "application/vnd.pvi.ptid1"},
{".pls", "application/pls+xml"},
{".str", "application/vnd.pg.format"},
{".ei6", "application/vnd.pg.osasli"},
{".dsc", "text/prs.lines.tag"},
{".psf", "application/x-font-linux-psf"},
{".qps", "application/vnd.publishare-delta-tree"},
{".wg", "application/vnd.pmi.widget"},
{".qxd", "application/vnd.quark.quarkxpress"},
{".esf", "application/vnd.epson.esf"},
{".msf", "application/vnd.epson.msf"},
{".ssf", "application/vnd.epson.ssf"},
{".qam", "application/vnd.epson.quickanime"},
{".qfx", "application/vnd.intu.qfx"},
{".qt", "video/quicktime"},
{".rar", "application/x-rar-compressed"},
{".ram", "audio/x-pn-realaudio"},
{".rmp", "audio/x-pn-realaudio-plugin"},
{".rsd", "application/rsd+xml"},
{".rm", "application/vnd.rn-realmedia"},
{".bed", "application/vnd.realvnc.bed"},
{".mxl", "application/vnd.recordare.musicxml"},
{".musicxml", "application/vnd.recordare.musicxml+xml"},
{".rnc", "application/relax-ng-compact-syntax"},
{".rdz", "application/vnd.data-vision.rdz"},
{".rdf", "application/rdf+xml"},
{".rp9", "application/vnd.cloanto.rp9"},
{".jisp", "application/vnd.jisp"},
{".rtf", "application/rtf"},
{".rtx", "text/richtext"},
{".link66", "application/vnd.route66.link66+xml"},
{".rss", "application/rss+xml"},
{".shf", "application/shf+xml"},
{".st", "application/vnd.sailingtracker.track"},
{".svg", "image/svg+xml"},
{".sus", "application/vnd.sus-calendar"},
{".sru", "application/sru+xml"},
{".setpay", "application/set-payment-initiation"},
{".setreg", "application/set-registration-initiation"},
{".sema", "application/vnd.sema"},
{".semd", "application/vnd.semd"},
{".semf", "application/vnd.semf"},
{".see", "application/vnd.seemail"},
{".snf", "application/x-font-snf"},
{".spq", "application/scvp-vp-request"},
{".spp", "application/scvp-vp-response"},
{".scq", "application/scvp-cv-request"},
{".scs", "application/scvp-cv-response"},
{".sdp", "application/sdp"},
{".etx", "text/x-setext"},
{".movie", "video/x-sgi-movie"},
{".ifm", "application/vnd.shana.informed.formdata"},
{".itp", "application/vnd.shana.informed.formtemplate"},
{".iif", "application/vnd.shana.informed.interchange"},
{".ipk", "application/vnd.shana.informed.package"},
{".tfi", "application/thraud+xml"},
{".shar", "application/x-shar"},
{".rgb", "image/x-rgb"},
{".slt", "application/vnd.epson.salt"},
{".aso", "application/vnd.accpac.simply.aso"},
{".imp", "application/vnd.accpac.simply.imp"},
{".twd", "application/vnd.simtech-mindmapper"},
{".csp", "application/vnd.commonspace"},
{".saf", "application/vnd.yamaha.smaf-audio"},
{".mmf", "application/vnd.smaf"},
{".spf", "application/vnd.yamaha.smaf-phrase"},
{".teacher", "application/vnd.smart.teacher"},
{".svd", "application/vnd.svd"},
{".rq", "application/sparql-query"},
{".srx", "application/sparql-results+xml"},
{".gram", "application/srgs"},
{".grxml", "application/srgs+xml"},
{".ssml", "application/ssml+xml"},
{".skp", "application/vnd.koan"},
{".sgml", "text/sgml"},
{".sdc", "application/vnd.stardivision.calc"},
{".sda", "application/vnd.stardivision.draw"},
{".sdd", "application/vnd.stardivision.impress"},
{".smf", "application/vnd.stardivision.math"},
{".sdw", "application/vnd.stardivision.writer"},
{".sgl", "application/vnd.stardivision.writer-global"},
{".sm", "application/vnd.stepmania.stepchart"},
{".sit", "application/x-stuffit"},
{".sitx", "application/x-stuffitx"},
{".sdkm", "application/vnd.solent.sdkm+xml"},
{".xo", "application/vnd.olpc-sugar"},
{".au", "audio/basic"},
{".wqd", "application/vnd.wqd"},
{".sis", "application/vnd.symbian.install"},
{".smi", "application/smil+xml"},
{".xsm", "application/vnd.syncml+xml"},
{".bdm", "application/vnd.syncml.dm+wbxml"},
{".xdm", "application/vnd.syncml.dm+xml"},
{".sv4cpio", "application/x-sv4cpio"},
{".sv4crc", "application/x-sv4crc"},
{".sbml", "application/sbml+xml"},
{".tsv", "text/tab-separated-values"},
{".tiff", "image/tiff"},
{".tao", "application/vnd.tao.intent-module-archive"},
{".tar", "application/x-tar"},
{".tcl", "application/x-tcl"},
{".tex", "application/x-tex"},
{".tfm", "application/x-tex-tfm"},
{".tei", "application/tei+xml"},
{".txt", "text/plain; charset=utf-8"},
{".md", "text/markdown; charset=utf-8"},
{".dxp", "application/vnd.spotfire.dxp"},
{".sfs", "application/vnd.spotfire.sfs"},
{".tsd", "application/timestamped-data"},
{".tpt", "application/vnd.trid.tpt"},
{".mxs", "application/vnd.triscape.mxs"},
{".t", "text/troff"},
{".tra", "application/vnd.trueapp"},
{".ttf", "application/x-font-ttf"},
{".ttl", "text/turtle"},
{".umj", "application/vnd.umajin"},
{".uoml", "application/vnd.uoml+xml"},
{".unityweb", "application/vnd.unity"},
{".ufd", "application/vnd.ufdl"},
{".uri", "text/uri-list"},
{".utz", "application/vnd.uiq.theme"},
{".ustar", "application/x-ustar"},
{".uu", "text/x-uuencode"},
{".vcs", "text/x-vcalendar"},
{".vcf", "text/x-vcard"},
{".vcd", "application/x-cdlink"},
{".vsf", "application/vnd.vsf"},
{".wrl", "model/vrml"},
{".vcx", "application/vnd.vcx"},
{".mts", "model/vnd.mts"},
{".vtu", "model/vnd.vtu"},
{".vis", "application/vnd.visionary"},
{".viv", "video/vnd.vivo"},
{".ccxml", "application/ccxml+xml"},
{".vxml", "application/voicexml+xml"},
{".src", "application/x-wais-source"},
{".wbxml", "application/vnd.wap.wbxml"},
{".wbmp", "image/vnd.wap.wbmp"},
{".wav", "audio/x-wav"},
{".davmount", "application/davmount+xml"},
{".woff", "application/x-font-woff"},
{".wspolicy", "application/wspolicy+xml"},
{".webp", "image/webp"},
{".wtb", "application/vnd.webturbo"},
{".wgt", "application/widget"},
{".hlp", "application/winhlp"},
{".wml", "text/vnd.wap.wml"},
{".wmls", "text/vnd.wap.wmlscript"},
{".wmlsc", "application/vnd.wap.wmlscriptc"},
{".wpd", "application/vnd.wordperfect"},
{".stf", "application/vnd.wt.stf"},
{".wsdl", "application/wsdl+xml"},
{".xbm", "image/x-xbitmap"},
{".xpm", "image/x-xpixmap"},
{".xwd", "image/x-xwindowdump"},
{".der", "application/x-x509-ca-cert"},
{".fig", "application/x-xfig"},
{".xhtml", "application/xhtml+xml"},
{".xml", "application/xml"},
{".xdf", "application/xcap-diff+xml"},
{".xenc", "application/xenc+xml"},
{".xer", "application/patch-ops-error+xml"},
{".rl", "application/resource-lists+xml"},
{".rs", "application/rls-services+xml"},
{".rld", "application/resource-lists-diff+xml"},
{".xslt", "application/xslt+xml"},
{".xop", "application/xop+xml"},
{".xpi", "application/x-xpinstall"},
{".xspf", "application/xspf+xml"},
{".xul", "application/vnd.mozilla.xul+xml"},
{".xyz", "chemical/x-xyz"},
{".yaml", "text/yaml"},
{".yang", "application/yang"},
{".yin", "application/yin+xml"},
{".zir", "application/vnd.zul"},
{".zip", "application/zip"},
{".zmm", "application/vnd.handheld-entertainment+xml"},
{".zaz", "application/vnd.zzazz.deck+xml"},
};
// Get HTTP MIME type from filename
char *GetMimeTypeFromFileName(char *filename)
{
UINT i;
UINT num = sizeof(http_mime_types) / sizeof(HTTP_MIME_TYPE);
if (filename == NULL)
{
return NULL;
}
for (i = 0;i < num;i++)
{
HTTP_MIME_TYPE *a = &http_mime_types[i];
if (EndWith(filename, a->Extension))
{
return a->MimeType;
}
}
return NULL;
}
// Download and save intermediate certificates if necessary
bool DownloadAndSaveIntermediateCertificatesIfNecessary(X *x)
{
@ -1183,6 +1903,11 @@ bool ServerAccept(CONNECTION *c)
error_detail_2 = NULL;
if (ServerDownloadSignature(c, &error_detail_2) == false)
{
if (c->Type == CONNECTION_TYPE_ADMIN_RPC)
{
c->Err = ERR_NO_ERROR;
}
if (error_detail_2 == NULL)
{
error_detail = "ServerDownloadSignature";
@ -5045,11 +5770,11 @@ PACK *PackWelcome(SESSION *s)
}
#define PACK_ADD_POLICY_BOOL(name, value) \
PackAddInt(p, "policy:" name, y->value == false ? 0 : 1)
PackAddBool(p, "policy:" name, y->value == false ? 0 : 1)
#define PACK_ADD_POLICY_UINT(name, value) \
PackAddInt(p, "policy:" name, y->value)
#define PACK_GET_POLICY_BOOL(name, value) \
y->value = (PackGetInt(p, "policy:" name) == 0 ? false : true)
y->value = (PackGetBool(p, "policy:" name))
#define PACK_GET_POLICY_UINT(name, value) \
y->value = PackGetInt(p, "policy:" name)
@ -5560,6 +6285,10 @@ bool ServerDownloadSignature(CONNECTION *c, char **error_detail_str)
if (h == NULL)
{
c->Err = ERR_CLIENT_IS_NOT_VPN;
if (c->IsJsonRpc)
{
c->Err = ERR_DISCONNECTED;
}
return false;
}
@ -5568,6 +6297,43 @@ bool ServerDownloadSignature(CONNECTION *c, char **error_detail_str)
{
// Receive the data since it's POST
data_size = GetContentLength(h);
if (server->DisableJsonRpcWebApi == false)
{
if (StrCmpi(h->Target, "/api") == 0 || StrCmpi(h->Target, "/api/") == 0)
{
c->IsJsonRpc = true;
c->Type = CONNECTION_TYPE_ADMIN_RPC;
JsonRpcProcPost(c, s, h, data_size);
FreeHttpHeader(h);
if (c->JsonRpcAuthed)
{
num = 0;
}
continue;
}
else if (StartWith(h->Target, "/admin"))
{
c->IsJsonRpc = true;
c->Type = CONNECTION_TYPE_ADMIN_RPC;
AdminWebProcPost(c, s, h, data_size, h->Target);
FreeHttpHeader(h);
if (c->JsonRpcAuthed)
{
num = 0;
}
continue;
}
}
if ((data_size > MAX_WATERMARK_SIZE || data_size < SizeOfWaterMark()) && (data_size != StrLen(HTTP_VPN_TARGET_POSTDATA)))
{
// Data is too large
@ -5616,6 +6382,25 @@ bool ServerDownloadSignature(CONNECTION *c, char **error_detail_str)
}
}
}
else if (StrCmpi(h->Method, "OPTIONS") == 0)
{
if (server->DisableJsonRpcWebApi == false)
{
if (StrCmpi(h->Target, "/api") == 0 || StrCmpi(h->Target, "/api/") == 0 || StartWith(h->Target, "/admin"))
{
c->IsJsonRpc = true;
c->Type = CONNECTION_TYPE_ADMIN_RPC;
JsonRpcProcOptions(c, s, h, h->Target);
FreeHttpHeader(h);
num = 0;
continue;
}
}
}
else if (StrCmpi(h->Method, "SSTP_DUPLEX_POST") == 0 && (server->DisableSSTPServer == false || s->IsReverseAcceptedSocket
) &&
GetServerCapsBool(server, "b_support_sstp") && GetNoSstp() == false)
@ -5733,6 +6518,45 @@ bool ServerDownloadSignature(CONNECTION *c, char **error_detail_str)
}
}
if (b == false)
{
if (server->DisableJsonRpcWebApi == false)
{
if (StartWith(h->Target, "/api?") || StartWith(h->Target, "/api/") || StrCmpi(h->Target, "/api") == 0)
{
c->IsJsonRpc = true;
c->Type = CONNECTION_TYPE_ADMIN_RPC;
JsonRpcProcGet(c, s, h, h->Target);
if (c->JsonRpcAuthed)
{
num = 0;
}
FreeHttpHeader(h);
continue;
}
else if (StartWith(h->Target, "/admin"))
{
c->IsJsonRpc = true;
c->Type = CONNECTION_TYPE_ADMIN_RPC;
AdminWebProcGet(c, s, h, h->Target);
if (c->JsonRpcAuthed)
{
num = 0;
}
FreeHttpHeader(h);
continue;
}
}
}
if (b == false)
{
// Not Found

View File

@ -8,6 +8,13 @@
#ifndef PROTOCOL_H
#define PROTOCOL_H
// MIME types
struct HTTP_MIME_TYPE
{
char *Extension;
char *MimeType;
};
// The parameters that will be passed to the certificate confirmation thread
struct CHECK_CERT_THREAD_PROC
{
@ -190,6 +197,6 @@ X *FindCertIssuerFromCertList(LIST *o, X *x);
bool TryGetRootCertChain(LIST *o, X *x, bool auto_save, X **found_root_x);
bool TryGetParentCertFromCertList(LIST *o, X *x, LIST *found_chain);
bool DownloadAndSaveIntermediateCertificatesIfNecessary(X *x);
char *GetMimeTypeFromFileName(char *filename);
#endif // PROTOCOL_H

View File

@ -15,6 +15,10 @@ void EndRpc(RPC *rpc)
// Release the RPC
void RpcFree(RPC *rpc)
{
RpcFreeEx(rpc, false);
}
void RpcFreeEx(RPC *rpc, bool no_disconnect)
{
// Validate arguments
if (rpc == NULL)
@ -22,7 +26,11 @@ void RpcFree(RPC *rpc)
return;
}
if (no_disconnect == false)
{
Disconnect(rpc->Sock);
}
ReleaseSock(rpc->Sock);
DeleteLock(rpc->Lock);

View File

@ -42,6 +42,7 @@ bool RpcIsOk(PACK *p);
UINT RpcGetError(PACK *p);
void EndRpc(RPC *rpc);
void RpcFree(RPC *rpc);
void RpcFreeEx(RPC *rpc, bool no_disconnect);
#endif // REMOTE_H

View File

@ -974,6 +974,9 @@ LIST *EnumLogFile(char *hubname)
// Enumerate in the packet_log
Format(tmp, sizeof(tmp), "%s/packet_log", exe_dir);
if (hubname == NULL)
{
dir = EnumDir(tmp);
if (dir != NULL)
{
@ -985,20 +988,28 @@ LIST *EnumLogFile(char *hubname)
if (e->Folder)
{
char dir_name[MAX_PATH];
if (hubname == NULL || StrCmpi(hubname, e->FileName) == 0)
{
Format(dir_name, sizeof(dir_name), "packet_log/%s", e->FileName);
EnumLogFileDir(o, dir_name);
}
}
}
FreeDir(dir);
}
}
else
{
char dir_name[MAX_PATH];
Format(dir_name, sizeof(dir_name), "packet_log/%s", hubname);
EnumLogFileDir(o, dir_name);
}
// Enumerate in the security_log
Format(tmp, sizeof(tmp), "%s/security_log", exe_dir);
if (hubname == NULL)
{
dir = EnumDir(tmp);
if (dir != NULL)
{
@ -1011,16 +1022,23 @@ LIST *EnumLogFile(char *hubname)
{
char dir_name[MAX_PATH];
if (hubname == NULL || StrCmpi(hubname, e->FileName) == 0)
{
Format(dir_name, sizeof(dir_name), "security_log/%s", e->FileName);
EnumLogFileDir(o, dir_name);
}
}
}
FreeDir(dir);
}
}
else
{
char dir_name[MAX_PATH];
Format(dir_name, sizeof(dir_name), "security_log/%s", hubname);
EnumLogFileDir(o, dir_name);
}
return o;
}
@ -1731,14 +1749,37 @@ void OutRpcCapsList(PACK *p, CAPSLIST *t)
return;
}
PackSetCurrentJsonGroupName(p, "CapsList");
for (i = 0;i < LIST_NUM(t->CapsList);i++)
{
char tmp[MAX_SIZE];
char ct_key[MAX_PATH];
wchar_t ct_description[MAX_PATH];
wchar_t *w;
CAPS *c = LIST_DATA(t->CapsList, i);
Format(tmp, sizeof(tmp), "caps_%s", c->Name);
PackAddInt(p, tmp, c->Value);
Format(ct_key, sizeof(ct_key), "CT_%s", c->Name);
Zero(ct_description, sizeof(ct_description));
w = _UU(ct_key);
if (UniIsEmptyStr(w) == false)
{
UniStrCpy(ct_description, sizeof(ct_description), w);
}
else
{
StrToUni(ct_description, sizeof(ct_description), c->Name);
}
PackAddInt(p, tmp, c->Value);
PackAddStrEx(p, "CapsName", c->Name, i, LIST_NUM(t->CapsList));
PackAddIntEx(p, "CapsValue", c->Value, i, LIST_NUM(t->CapsList));
PackAddUniStrEx(p, "CapsDescrption", ct_description, i, LIST_NUM(t->CapsList));
}
PackSetCurrentJsonGroupName(p, NULL);
}
void FreeRpcCapsList(CAPSLIST *t)
{
@ -5982,6 +6023,10 @@ void SiLoadServerCfg(SERVER *s, FOLDER *f)
c->SslAcceptSettings.Tls_Disable1_2 = CfgGetBool(f, "Tls_Disable1_2");
s->StrictSyslogDatetimeFormat = CfgGetBool(f, "StrictSyslogDatetimeFormat");
// Disable JSON-RPC Web API
s->DisableJsonRpcWebApi = CfgGetBool(f, "DisableJsonRpcWebApi");
// Bits of Diffie-Hellman parameters
c->DhParamBits = CfgGetInt(f, "DhParamBits");
if (c->DhParamBits == 0)
@ -6314,6 +6359,9 @@ void SiWriteServerCfg(FOLDER *f, SERVER *s)
CfgAddBool(f, "DisableSessionReconnect", GetGlobalServerFlag(GSF_DISABLE_SESSION_RECONNECT));
CfgAddBool(f, "StrictSyslogDatetimeFormat", s->StrictSyslogDatetimeFormat);
// Disable JSON-RPC Web API
CfgAddBool(f, "DisableJsonRpcWebApi", s->DisableJsonRpcWebApi);
}
Unlock(c->lock);
}
@ -7031,7 +7079,7 @@ FARM_MEMBER *SiGetNextFarmMember(SERVER *s, CONNECTION *c, HUB *h)
PackAddIntEx(p, "NumTcpConnections", f->NumTcpConnections, i, num);
PackAddIntEx(p, "NumHubs", LIST_NUM(f->HubList), i, num);
PackAddBoolEx(p, "Me", f->Me, i, num);
PackAddInt64Ex(p, "ConnectedTime", f->ConnectedTime, i, num);
PackAddTime64Ex(p, "ConnectedTime", f->ConnectedTime, i, num);
PackAddInt64Ex(p, "SystemId", f->SystemId, i, num);
PackAddBoolEx(p, "DoNotSelect", do_not_select, i, num);
}
@ -7060,7 +7108,7 @@ FARM_MEMBER *SiGetNextFarmMember(SERVER *s, CONNECTION *c, HUB *h)
PackAddStr(p, "CipherName", c->CipherName);
PackAddStr(p, "ClientStr", c->ClientStr);
PackAddInt(p, "ClientVer", c->ClientVer);
PackAddInt64(p, "ConnectedTime", Tick64ToTime64(c->ConnectedTick));
PackAddTime64(p, "ConnectedTime", Tick64ToTime64(c->ConnectedTick));
PackAddStr(p, "HubName", h->Name);
PackAddBool(p, "StaticHub", h->Type == HUB_TYPE_FARM_STATIC);
@ -7200,8 +7248,8 @@ void SiCalledEnumHub(SERVER *s, PACK *p, PACK *req)
PackAddIntEx(p, "NumIpTables", LIST_NUM(h->IpTable), i, num);
PackAddInt64Ex(p, "LastCommTime", h->LastCommTime, i, num);
PackAddInt64Ex(p, "CreatedTime", h->CreatedTime, i, num);
PackAddTime64Ex(p, "LastCommTime", h->LastCommTime, i, num);
PackAddTime64Ex(p, "CreatedTime", h->CreatedTime, i, num);
}
Unlock(h->lock);
}

View File

@ -267,6 +267,7 @@ struct SERVER
IP ListenIP; // Listen IP
bool StrictSyslogDatetimeFormat; // Make syslog datetime format strict RFC3164
bool DisableJsonRpcWebApi; // Disable JSON-RPC Web API
};
@ -290,6 +291,7 @@ struct RPC_SESSION_STATUS
RPC_CLIENT_GET_CONNECTION_STATUS Status; // Status
UINT ClientIp; // Client IP address
UCHAR ClientIp6[16]; // Client IPv6 address
IP ClientIpAddress; // Client IP address (IPv4/IPv6)
char ClientHostName[MAX_HOST_NAME_LEN + 1]; // Client host name
NODE_INFO NodeInfo; // Node information
};

View File

@ -108,9 +108,9 @@ void SessionMain(SESSION *s)
s->NumConnectionsEstablished++;
s->CurrentConnectionEstablishTime = Tick64();
if (s->FirstConnectionEstablishedTime == 0)
if (s->FirstConnectionEstablisiedTime == 0) /* !!! Do not correct the spelling to keep the backward protocol compatibility !!! */
{
s->FirstConnectionEstablishedTime = Tick64();
s->FirstConnectionEstablisiedTime = Tick64(); /* !!! Do not correct the spelling to keep the backward protocol compatibility !!! */
}
if (s->ServerMode == false && s->Cedar->Client != NULL)
@ -1158,7 +1158,10 @@ void StopSessionEx(SESSION *s, bool no_wait)
// Server and client mode
if (s->Connection)
{
StopConnection(s->Connection, no_wait);
CONNECTION *c = s->Connection;
AddRef(c->ref);
StopConnection(c, no_wait);
ReleaseConnection(c);
}
// Wait until the stop

View File

@ -157,7 +157,8 @@ struct SESSION
UINT NumDisconnected; // Number of socket disconnection
bool NoReconnectToSession; // Disable to reconnect to the session
char UnderlayProtocol[64]; // Physical communication protocol
UINT64 FirstConnectionEstablishedTime; // Connection completion time of the first connection
/* !!! Do not correct the spelling to keep the backward protocol compatibility !!! */
UINT64 FirstConnectionEstablisiedTime; // Connection completion time of the first connection
UINT64 CurrentConnectionEstablishTime; // Completion time of this connection
UINT NumConnectionsEstablished; // Number of connections established so far
UINT AdjustMss; // MSS adjustment value

View File

@ -1127,6 +1127,12 @@ void BuildHamcore(char *dst_filename, char *src_dir, bool unix_only)
}
}
if (InStr(rpath, "\\node_modules\\"))
{
// Exclude node_modules in the hamcore\webroot
ok = false;
}
if (ok)
{
b = ReadDump(s);

View File

@ -1408,11 +1408,103 @@ void GetDateTimeStrMilli(char *str, UINT size, SYSTEMTIME *st)
st->wMilliseconds);
}
// Convert string RFC3339 format (example: 2017-09-27T18:25:55.434-9:00) to UINT64
UINT64 DateTimeStrRFC3339ToSystemTime64(char *str)
{
SYSTEMTIME st;
if (DateTimeStrRFC3339ToSystemTime(&st, str))
{
return SystemToUINT64(&st);
}
else
{
return 0;
}
}
// Convert string RFC3339 format (example: 2017-09-27T18:25:55.434-9:00) to SYSTEMTIME
bool DateTimeStrRFC3339ToSystemTime(SYSTEMTIME *st, char *str)
{
bool ok = false;
UINT index_plus;
char tmp[MAX_PATH];
Zero(st, sizeof(SYSTEMTIME));
if (st == NULL || str == NULL)
{
return false;
}
StrCpy(tmp, sizeof(tmp), str);
index_plus = SearchStrEx(tmp, "+", 0, false);
if (index_plus != INFINITE)
{
tmp[index_plus] = 0;
}
if (StrLen(tmp) >= 19)
{
if (tmp[4] == '-' && tmp[7] == '-' && tmp[10] == 'T' && tmp[13] == ':' &&
tmp[16] == ':')
{
char str_year[16], str_month[16], str_day[16], str_hour[16], str_minute[16],
str_second[16], str_msec[16];
StrCpy(str_year, sizeof(str_year), tmp + 0);
str_year[4] = 0;
StrCpy(str_month, sizeof(str_month), tmp + 5);
str_month[2] = 0;
StrCpy(str_day, sizeof(str_day), tmp + 8);
str_day[2] = 0;
StrCpy(str_hour, sizeof(str_hour), tmp + 11);
str_hour[2] = 0;
StrCpy(str_minute, sizeof(str_minute), tmp + 14);
str_minute[2] = 0;
StrCpy(str_second, sizeof(str_second), tmp + 17);
str_second[2] = 0;
str_msec[0] = 0;
if (StrLen(tmp) >= 21 && tmp[19] == '.')
{
StrCpy(str_msec, sizeof(str_msec), tmp + 20);
str_msec[StrLen(tmp) - 21] = 0;
while (StrLen(str_msec) < 3)
{
StrCat(str_msec, sizeof(str_msec), "0");
}
str_msec[3] = 0;
}
st->wYear = ToInt(str_year);
st->wMonth = ToInt(str_month);
st->wDay = ToInt(str_day);
st->wHour = ToInt(str_hour);
st->wMinute = ToInt(str_minute);
st->wSecond = ToInt(str_second);
st->wMilliseconds = ToInt(str_msec);
NormalizeSystem(st);
ok = true;
}
}
return ok;
}
// Get the date and time string in RFC3339 format (example: 2017-09-27T18:25:55.434-9:00)
void GetDateTimeStrRFC3339(char *str, UINT size, SYSTEMTIME *st, int timezone_min){
// Validate arguments
if (str == NULL || st == NULL)
{
ClearStr(str, size);
return;
}

View File

@ -137,6 +137,8 @@ void GetDateTimeStrEx64(wchar_t *str, UINT size, UINT64 sec64, LOCALE *locale);
void GetDateStrEx64(wchar_t *str, UINT size, UINT64 sec64, LOCALE *locale);
void GetTimeStrMilli64(char *str, UINT size, UINT64 sec64);
void GetDateTimeStrRFC3339(char *str, UINT size, SYSTEMTIME *st, int timezone_min);
bool DateTimeStrRFC3339ToSystemTime(SYSTEMTIME *st, char *str);
UINT64 DateTimeStrRFC3339ToSystemTime64(char *str);
UINT64 SafeTime64(UINT64 sec64);
bool Run(char *filename, char *arg, bool hide, bool wait);
bool RunW(wchar_t *filename, wchar_t *arg, bool hide, bool wait);

View File

@ -347,6 +347,9 @@ typedef struct PRAND PRAND;
// Str.h
typedef struct TOKEN_LIST TOKEN_LIST;
typedef struct INI_ENTRY INI_ENTRY;
typedef struct JSON_OBJECT JSON_OBJECT;
typedef struct JSON_ARRAY JSON_ARRAY;
typedef struct JSON_VALUE JSON_VALUE;
// Internat.h
typedef struct UNI_TOKEN_LIST UNI_TOKEN_LIST;
@ -383,6 +386,8 @@ typedef struct INSTANCE INSTANCE;
typedef struct VALUE VALUE;
typedef struct ELEMENT ELEMENT;
typedef struct PACK PACK;
typedef struct JSONPACKHINT JSONPACKHINT;
typedef struct JSONPACKHINT_ITEM JSONPACKHINT_ITEM;
// Cfg.h
typedef struct FOLDER FOLDER;

View File

@ -1413,6 +1413,48 @@ bool ReplaceListPointer(LIST *o, void *oldptr, void *newptr)
return false;
}
// New string list
LIST *NewStrList()
{
return NewListFast(CompareStr);
}
// Release string list
void ReleaseStrList(LIST *o)
{
UINT i;
if (o == NULL)
{
return;
}
for (i = 0;i < LIST_NUM(o);i++)
{
char *s = LIST_DATA(o, i);
Free(s);
}
ReleaseList(o);
}
// Add a string distinct to the string list
bool AddStrToStrListDistinct(LIST *o, char *str)
{
if (o == NULL || str == NULL)
{
return false;
}
if (IsInListStr(o, str) == false)
{
Add(o, CopyStr(str));
return true;
}
return false;
}
// Examine whether a string items are present in the list
bool IsInListStr(LIST *o, char *str)
{
@ -2948,6 +2990,43 @@ void WriteBufBuf(BUF *b, BUF *bb)
WriteBuf(b, bb->Buf, bb->Size);
}
// Write the buffer (from the offset) to a buffer
void WriteBufBufWithOffset(BUF *b, BUF *bb)
{
// Validate arguments
if (b == NULL || bb == NULL)
{
return;
}
WriteBuf(b, ((UCHAR *)bb->Buf) + bb->Current, bb->Size - bb->Current);
}
// Skip UTF-8 BOM
bool BufSkipUtf8Bom(BUF *b)
{
if (b == NULL)
{
return false;
}
SeekBufToBegin(b);
if (b->Size >= 3)
{
UCHAR *data = b->Buf;
if (data[0] == 0xEF && data[1] == 0xBB && data[2] == 0xBF)
{
SeekBuf(b, 3, 1);
return true;
}
}
return false;
}
// Read into a buffer from the buffer
BUF *ReadBufFromBuf(BUF *b, UINT size)
{

View File

@ -208,7 +208,9 @@ BUF *NewBufFromMemory(void *buf, UINT size);
void ClearBuf(BUF *b);
void WriteBuf(BUF *b, void *buf, UINT size);
void WriteBufBuf(BUF *b, BUF *bb);
void WriteBufBufWithOffset(BUF *b, BUF *bb);
UINT ReadBuf(BUF *b, void *buf, UINT size);
bool BufSkipUtf8Bom(BUF *b);
BUF *ReadBufFromBuf(BUF *b, UINT size);
void AdjustBufSize(BUF *b, UINT new_size);
void SeekBuf(BUF *b, UINT offset, int mode);
@ -357,5 +359,9 @@ void CleanupSharedBuffer(SHARED_BUFFER *b);
void AppendBufUtf8(BUF *b, wchar_t *str);
void AppendBufStr(BUF *b, char *str);
LIST *NewStrList();
void ReleaseStrList(LIST *o);
bool AddStrToStrListDistinct(LIST *o, char *str);
#endif // MEMORY_H

View File

@ -7229,6 +7229,12 @@ bool IsIP4(IP *ip)
return (IsIP6(ip) ? false : true);
}
// Copy the IP address
void CopyIP(IP *dst, IP *src)
{
Copy(dst, src, sizeof(IP));
}
// Get the number of clients connected from the specified IP address
UINT GetNumIpClient(IP *ip)
{
@ -11368,6 +11374,50 @@ void InitSockSet(SOCKSET *set)
Zero(set, sizeof(SOCKSET));
}
// Receive data and discard all of them
bool RecvAllWithDiscard(SOCK *sock, UINT size, bool secure)
{
static UCHAR buffer[4096];
UINT recv_size, sz, ret;
if (sock == NULL)
{
return false;
}
if (size == 0)
{
return true;
}
if (sock->AsyncMode)
{
return false;
}
recv_size = 0;
while (true)
{
sz = MIN(size - recv_size, sizeof(buffer));
ret = Recv(sock, buffer, sz, secure);
if (ret == 0)
{
return false;
}
if (ret == SOCK_LATER)
{
// I suppose that this is safe because the RecvAll() function is used only
// if the sock->AsyncMode == true. And the Recv() function may return
// SOCK_LATER only if the sock->AsyncMode == false. Therefore the call of
// Recv() function in the RecvAll() function never returns SOCK_LATER.
return false;
}
recv_size += ret;
if (recv_size >= size)
{
return true;
}
}
}
// Receive all by TCP
bool RecvAll(SOCK *sock, void *data, UINT size, bool secure)
{

View File

@ -953,6 +953,7 @@ UINT GetContentLength(HTTP_HEADER *header);
void GetHttpDateStr(char *str, UINT size, UINT64 t);
bool HttpSendForbidden(SOCK *s, char *target, char *server_id);
bool HttpSendNotFound(SOCK *s, char *target);
bool HttpSendBody(SOCK *s, void *data, UINT size, char *contents_type);
bool HttpSendNotImplemented(SOCK *s, char *method, char *target, char *version);
bool HttpServerSend(SOCK *s, PACK *p);
bool HttpClientSend(SOCK *s, PACK *p);
@ -1193,6 +1194,7 @@ void SendAdd(SOCK *sock, void *data, UINT size);
bool SendNow(SOCK *sock, int secure);
bool RecvAll(SOCK *sock, void *data, UINT size, bool secure);
bool RecvAllEx(SOCK *sock, void **data_new_ptr, UINT size, bool secure);
bool RecvAllWithDiscard(SOCK *sock, UINT size, bool secure);
void InitSockSet(SOCKSET *set);
void AddSockSet(SOCKSET *set, SOCK *sock);
CANCEL *NewCancel();
@ -1308,6 +1310,7 @@ void SocketTimeoutThread(THREAD *t, void *param);
SOCKET_TIMEOUT_PARAM *NewSocketTimeout(SOCK *sock);
void FreeSocketTimeout(SOCKET_TIMEOUT_PARAM *ttp);
void CopyIP(IP *dst, IP *src);
bool IsIP6(IP *ip);
bool IsIP4(IP *ip);
void IPv6AddrToIP(IP *ip, IPV6_ADDR *addr);

File diff suppressed because it is too large Load Diff

View File

@ -55,12 +55,38 @@ struct ELEMENT
UINT num_value; // Number of values (>=1)
UINT type; // Type
VALUE **values; // List of pointers to the value
bool JsonHint_IsArray;
bool JsonHint_IsBool;
bool JsonHint_IsDateTime;
bool JsonHint_IsIP;
char JsonHint_GroupName[MAX_ELEMENT_NAME_LEN + 1];
};
// PACK object
struct PACK
{
LIST *elements; // Element list
LIST *json_subitem_names; // JSON sub-item names
char CurrentJsonHint_GroupName[MAX_ELEMENT_NAME_LEN + 1];
};
#define MAX_JSONPACK_HINT_ITEMS 64
#define JSONPACK_HINT_TYPE_ARRAY 1
// JSON/PACK converter hint element
struct JSONPACKHINT_ITEM
{
UINT Type;
char ArrayNumNameInPack[MAX_ELEMENT_NAME_LEN + 1];
char ArrayMembersInPack[MAX_SIZE + 1];
};
// JSON/PACK converter hint
struct JSONPACKHINT
{
UINT NumHints;
JSONPACKHINT_ITEM Hints[MAX_JSONPACK_HINT_ITEMS];
};
@ -100,21 +126,23 @@ TOKEN_LIST *GetPackElementNames(PACK *p);
X *PackGetX(PACK *p, char *name);
K *PackGetK(PACK *p, char *name);
void PackAddX(PACK *p, char *name, X *x);
void PackAddK(PACK *p, char *name, K *k);
void PackAddStr(PACK *p, char *name, char *str);
void PackAddStrEx(PACK *p, char *name, char *str, UINT index, UINT total);
void PackAddUniStr(PACK *p, char *name, wchar_t *unistr);
void PackAddUniStrEx(PACK *p, char *name, wchar_t *unistr, UINT index, UINT total);
void PackAddInt(PACK *p, char *name, UINT i);
void PackAddNum(PACK *p, char *name, UINT num);
void PackAddIntEx(PACK *p, char *name, UINT i, UINT index, UINT total);
void PackAddInt64(PACK *p, char *name, UINT64 i);
void PackAddInt64Ex(PACK *p, char *name, UINT64 i, UINT index, UINT total);
void PackAddData(PACK *p, char *name, void *data, UINT size);
void PackAddDataEx(PACK *p, char *name, void *data, UINT size, UINT index, UINT total);
void PackAddBuf(PACK *p, char *name, BUF *b);
void PackAddBufEx(PACK *p, char *name, BUF *b, UINT index, UINT total);
ELEMENT *PackAddX(PACK *p, char *name, X *x);
ELEMENT *PackAddK(PACK *p, char *name, K *k);
ELEMENT *PackAddStr(PACK *p, char *name, char *str);
ELEMENT *PackAddStrEx(PACK *p, char *name, char *str, UINT index, UINT total);
ELEMENT *PackAddUniStr(PACK *p, char *name, wchar_t *unistr);
ELEMENT *PackAddUniStrEx(PACK *p, char *name, wchar_t *unistr, UINT index, UINT total);
ELEMENT *PackAddInt(PACK *p, char *name, UINT i);
ELEMENT *PackAddNum(PACK *p, char *name, UINT num);
ELEMENT *PackAddIntEx(PACK *p, char *name, UINT i, UINT index, UINT total);
ELEMENT *PackAddInt64(PACK *p, char *name, UINT64 i);
ELEMENT *PackAddInt64Ex(PACK *p, char *name, UINT64 i, UINT index, UINT total);
ELEMENT *PackAddTime64(PACK *p, char *name, UINT64 i);
ELEMENT *PackAddTime64Ex(PACK *p, char *name, UINT64 i, UINT index, UINT total);
ELEMENT *PackAddData(PACK *p, char *name, void *data, UINT size);
ELEMENT *PackAddDataEx(PACK *p, char *name, void *data, UINT size, UINT index, UINT total);
ELEMENT *PackAddBuf(PACK *p, char *name, BUF *b);
ELEMENT *PackAddBufEx(PACK *p, char *name, BUF *b, UINT index, UINT total);
bool PackGetStr(PACK *p, char *name, char *str, UINT size);
bool PackGetStrEx(PACK *p, char *name, char *str, UINT size, UINT index);
bool PackGetUniStr(PACK *p, char *name, wchar_t *unistr, UINT size);
@ -133,23 +161,38 @@ bool PackGetDataEx(PACK *p, char *name, void *data, UINT index);
BUF *PackGetBuf(PACK *p, char *name);
BUF *PackGetBufEx(PACK *p, char *name, UINT index);
bool PackGetBool(PACK *p, char *name);
void PackAddBool(PACK *p, char *name, bool b);
void PackAddBoolEx(PACK *p, char *name, bool b, UINT index, UINT total);
ELEMENT *PackAddBool(PACK *p, char *name, bool b);
ELEMENT *PackAddBoolEx(PACK *p, char *name, bool b, UINT index, UINT total);
bool PackGetBoolEx(PACK *p, char *name, UINT index);
void PackAddIp(PACK *p, char *name, IP *ip);
void PackAddIpEx(PACK *p, char *name, IP *ip, UINT index, UINT total);
void PackAddIpEx2(PACK *p, char *name, IP *ip, UINT index, UINT total, bool is_single);
bool PackGetIp(PACK *p, char *name, IP *ip);
bool PackGetIpEx(PACK *p, char *name, IP *ip, UINT index);
UINT PackGetIp32(PACK *p, char *name);
UINT PackGetIp32Ex(PACK *p, char *name, UINT index);
void PackAddIp32(PACK *p, char *name, UINT ip32);
void PackAddIp32Ex(PACK *p, char *name, UINT ip32, UINT index, UINT total);
void PackAddIp6AddrEx(PACK *p, char *name, IPV6_ADDR *addr, UINT index, UINT total);
void PackAddIp32Ex2(PACK *p, char *name, UINT ip32, UINT index, UINT total, bool is_single);
ELEMENT *PackAddIp6AddrEx(PACK *p, char *name, IPV6_ADDR *addr, UINT index, UINT total);
bool PackGetIp6AddrEx(PACK *p, char *name, IPV6_ADDR *addr, UINT index);
void PackAddIp6Addr(PACK *p, char *name, IPV6_ADDR *addr);
ELEMENT *PackAddIp6Addr(PACK *p, char *name, IPV6_ADDR *addr);
bool PackGetIp6Addr(PACK *p, char *name, IPV6_ADDR *addr);
bool PackGetData2(PACK *p, char *name, void *data, UINT size);
bool PackGetDataEx2(PACK *p, char *name, void *data, UINT size, UINT index);
bool PackIsValueExists(PACK *p, char *name);
void PackSetCurrentJsonGroupName(PACK *p, char *json_group_name);
ELEMENT *ElementNullSafe(ELEMENT *p);
JSON_VALUE *PackToJson(PACK *p);
char *PackToJsonStr(PACK *p);
PACK *JsonToPack(JSON_VALUE *v);
PACK *JsonStrToPack(char *str);
void PackArrayElementToJsonArray(JSON_ARRAY *ja, PACK *p, ELEMENT *e, UINT index);
void PackElementToJsonObject(JSON_OBJECT *o, PACK *p, ELEMENT *e, UINT index);
char *DetermineJsonSuffixForPackElement(ELEMENT *e);
bool JsonTryParseValueAddToPack(PACK *p, JSON_VALUE *v, char *v_name, UINT index, UINT total, bool is_single);
#endif // PACK_H

File diff suppressed because it is too large Load Diff

View File

@ -79,7 +79,9 @@ void BinToStrW(wchar_t *str, UINT str_size, void *data, UINT data_size);
void PrintBin(void *data, UINT size);
bool StartWith(char *str, char *key);
bool EndWith(char *str, char *key);
bool TrimEndWith(char *dst, UINT dst_size, char *str, char *key);
UINT64 ToInt64(char *str);
UINT64 Json_ToInt64Ex(char *str, char **endptr, bool *error);
void ToStr64(char *str, UINT64 value);
TOKEN_LIST *ParseCmdLine(char *str);
TOKEN_LIST *CopyToken(TOKEN_LIST *src);
@ -128,6 +130,259 @@ LIST *StrToIntList(char *str, bool sorted);
void NormalizeIntListStr(char *dst, UINT dst_size, char *src, bool sorted, char *separate_str);
void ClearStr(char *str, UINT str_size);
void SetStrCaseAccordingToBits(char *str, UINT bits);
char *UrlDecode(char *url_str);
// *** JSON strings support
// Original source code from Parson ( http://kgabis.github.com/parson/ )
// Modified by dnobori
/*
Parson ( http://kgabis.github.com/parson/ )
Copyright (c) 2012 - 2017 Krzysztof Gabis
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
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,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/
/* Type definitions */
typedef union JSON_VALUE_UNION {
char *string;
UINT64 number;
JSON_OBJECT *object;
JSON_ARRAY *array;
int boolean;
int null;
} JSON_VALUE_UNION;
struct JSON_VALUE {
JSON_VALUE *parent;
UINT type;
JSON_VALUE_UNION value;
};
struct JSON_OBJECT {
JSON_VALUE *wrapping_value;
char **names;
JSON_VALUE **values;
UINT count;
UINT capacity;
};
struct JSON_ARRAY {
JSON_VALUE *wrapping_value;
JSON_VALUE **items;
UINT count;
UINT capacity;
};
enum JSON_TYPES {
JSON_TYPE_ERROR = -1,
JSON_TYPE_NULL = 1,
JSON_TYPE_STRING = 2,
JSON_TYPE_NUMBER = 3,
JSON_TYPE_OBJECT = 4,
JSON_TYPE_ARRAY = 5,
JSON_TYPE_BOOL = 6
};
typedef unsigned int UINT;
enum JSON_RETS {
JSON_RET_OK = 0,
JSON_RET_ERROR = -1
};
typedef void * (*JSON_Malloc_Function)(UINT);
typedef void(*JSON_Free_Function)(void *);
/* Call only once, before calling any other function from parson API. If not called, malloc and free
from stdlib will be used for all allocations */
void JsonSetAllocationFunctions(JSON_Malloc_Function malloc_fun, JSON_Free_Function free_fun);
/* Parses first JSON value in a string, returns NULL in case of error */
JSON_VALUE * JsonParseString(char *string);
/* Parses first JSON value in a string and ignores comments (/ * * / and //),
returns NULL in case of error */
JSON_VALUE * JsonParseStringWithComments(char *string);
/* Serialization */
UINT JsonGetSerializationSize(JSON_VALUE *value); /* returns 0 on fail */
UINT JsonSerializeToBuffer(JSON_VALUE *value, char *buf, UINT buf_size_in_bytes);
char * JsonSerializeToString(JSON_VALUE *value);
/* Pretty serialization */
UINT JsonGetSerializationSizePretty(JSON_VALUE *value); /* returns 0 on fail */
UINT JsonSerializeToBufferPretty(JSON_VALUE *value, char *buf, UINT buf_size_in_bytes);
char * JsonSerializeToStringPretty(JSON_VALUE *value);
char *JsonToStr(JSON_VALUE *v);
void JsonFreeString(char *string); /* frees string from json_serialize_to_string and json_serialize_to_string_pretty */
/* Comparing */
int JsonCmp(JSON_VALUE *a, JSON_VALUE *b);
/* Validation
This is *NOT* JSON Schema. It validates json by checking if object have identically
named fields with matching types.
For example schema {"name":"", "age":0} will validate
{"name":"Joe", "age":25} and {"name":"Joe", "age":25, "gender":"m"},
but not {"name":"Joe"} or {"name":"Joe", "age":"Cucumber"}.
In case of arrays, only first value in schema is checked against all values in tested array.
Empty objects ({}) validate all objects, empty arrays ([]) validate all arrays,
null validates values of every type.
*/
UINT JsonValidate(JSON_VALUE *schema, JSON_VALUE *value);
/*
* JSON Object
*/
JSON_VALUE * JsonGet(JSON_OBJECT *object, char *name);
char * JsonGetStr(JSON_OBJECT *object, char *name);
JSON_OBJECT * JsonGetObj(JSON_OBJECT *object, char *name);
JSON_ARRAY * JsonGetArray(JSON_OBJECT *object, char *name);
UINT64 JsonGetNumber(JSON_OBJECT *object, char *name); /* returns 0 on fail */
bool JsonGetBool(JSON_OBJECT *object, char *name); /* returns 0 on fail */
/* dotget functions enable addressing values with dot notation in nested objects,
just like in structs or c++/java/c# objects (e.g. objectA.objectB.value).
Because valid names in JSON can contain dots, some values may be inaccessible
this way. */
JSON_VALUE * JsonDotGet(JSON_OBJECT *object, char *name);
char * JsonDotGetStr(JSON_OBJECT *object, char *name);
JSON_OBJECT * JsonDotGetObj(JSON_OBJECT *object, char *name);
JSON_ARRAY * JsonDotGetArray(JSON_OBJECT *object, char *name);
UINT64 JsonDotGetNumber(JSON_OBJECT *object, char *name); /* returns 0 on fail */
bool JsonDotGetBool(JSON_OBJECT *object, char *name); /* returns -1 on fail */
/* Functions to get available names */
UINT JsonGetCount(JSON_OBJECT *object);
char * JsonGetName(JSON_OBJECT *object, UINT index);
JSON_VALUE * JsonGetValueAt(JSON_OBJECT *object, UINT index);
JSON_VALUE * JsonGetWrappingValue(JSON_OBJECT *object);
/* Functions to check if object has a value with a specific name. Returned value is 1 if object has
* a value and 0 if it doesn't. dothas functions behave exactly like dotget functions. */
int JsonIsExists(JSON_OBJECT *object, char *name);
int JsonIsExistsWithValueType(JSON_OBJECT *object, char *name, UINT type);
int JsonDotIsExists(JSON_OBJECT *object, char *name);
int JsonDotIsExistsWithValueType(JSON_OBJECT *object, char *name, UINT type);
/* Creates new name-value pair or frees and replaces old value with a new one.
* json_object_set_value does not copy passed value so it shouldn't be freed afterwards. */
UINT JsonSet(JSON_OBJECT *object, char *name, JSON_VALUE *value);
UINT JsonSetStr(JSON_OBJECT *object, char *name, char *string);
UINT JsonSetUniStr(JSON_OBJECT *object, char *name, wchar_t *string);
UINT JsonSetNumber(JSON_OBJECT *object, char *name, UINT64 number);
UINT JsonSetBool(JSON_OBJECT *object, char *name, int boolean);
UINT JsonSetNull(JSON_OBJECT *object, char *name);
UINT JsonSetData(JSON_OBJECT *object, char *name, void *data, UINT size);
/* Works like dotget functions, but creates whole hierarchy if necessary.
* json_object_dotset_value does not copy passed value so it shouldn't be freed afterwards. */
UINT JsonDotSet(JSON_OBJECT *object, char *name, JSON_VALUE *value);
UINT JsonDotSetStr(JSON_OBJECT *object, char *name, char *string);
UINT JsonDotSetNumber(JSON_OBJECT *object, char *name, UINT64 number);
UINT JsonDotSetBool(JSON_OBJECT *object, char *name, int boolean);
UINT JsonDotSetNull(JSON_OBJECT *object, char *name);
/* Frees and removes name-value pair */
UINT JsonDelete(JSON_OBJECT *object, char *name);
/* Works like dotget function, but removes name-value pair only on exact match. */
UINT JsonDotDelete(JSON_OBJECT *object, char *key);
/* Removes all name-value pairs in object */
UINT JsonDeleteAll(JSON_OBJECT *object);
/*
*JSON Array
*/
JSON_VALUE * JsonArrayGet(JSON_ARRAY *array, UINT index);
char * JsonArrayGetStr(JSON_ARRAY *array, UINT index);
JSON_OBJECT * JsonArrayGetObj(JSON_ARRAY *array, UINT index);
JSON_ARRAY * JsonArrayGetArray(JSON_ARRAY *array, UINT index);
UINT64 JsonArrayGetNumber(JSON_ARRAY *array, UINT index); /* returns 0 on fail */
bool JsonArrayGetBool(JSON_ARRAY *array, UINT index); /* returns 0 on fail */
UINT JsonArrayGetCount(JSON_ARRAY *array);
JSON_VALUE * JsonArrayGetWrappingValue(JSON_ARRAY *array);
/* Frees and removes value at given index, does nothing and returns JSONFailure if index doesn't exist.
* Order of values in array may change during execution. */
UINT JsonArrayDelete(JSON_ARRAY *array, UINT i);
/* Frees and removes from array value at given index and replaces it with given one.
* Does nothing and returns JSONFailure if index doesn't exist.
* json_array_replace_value does not copy passed value so it shouldn't be freed afterwards. */
UINT JsonArrayReplace(JSON_ARRAY *array, UINT i, JSON_VALUE *value);
UINT JsonArrayReplaceStr(JSON_ARRAY *array, UINT i, char* string);
UINT JsonArrayReplaceNumber(JSON_ARRAY *array, UINT i, UINT64 number);
UINT JsonArrayReplaceBool(JSON_ARRAY *array, UINT i, int boolean);
UINT JsonArrayReplaceNull(JSON_ARRAY *array, UINT i);
/* Frees and removes all values from array */
UINT JsonArrayDeleteAll(JSON_ARRAY *array);
/* Appends new value at the end of array.
* json_array_append_value does not copy passed value so it shouldn't be freed afterwards. */
UINT JsonArrayAdd(JSON_ARRAY *array, JSON_VALUE *value);
UINT JsonArrayAddStr(JSON_ARRAY *array, char *string);
UINT JsonArrayAddUniStr(JSON_ARRAY *array, wchar_t *string);
UINT JsonArrayAddNumber(JSON_ARRAY *array, UINT64 number);
UINT JsonArrayAddData(JSON_ARRAY *array, void *data, UINT size);
UINT JsonArrayAddBool(JSON_ARRAY *array, int boolean);
UINT JsonArrayAddNull(JSON_ARRAY *array);
/*
*JSON Value
*/
JSON_VALUE * JsonNewObject(void);
JSON_VALUE * JsonNewArray(void);
JSON_VALUE * JsonNewStr(char *string); /* copies passed string */
JSON_VALUE * JsonNewNumber(UINT64 number);
JSON_VALUE * JsonNewBool(int boolean);
JSON_VALUE * JsonNewNull(void);
JSON_VALUE * JsonDeepCopy(JSON_VALUE *value);
void JsonFree(JSON_VALUE *value);
UINT JsonValueGetType(JSON_VALUE *value);
JSON_OBJECT * JsonValueGetObject(JSON_VALUE *value);
JSON_ARRAY * JsonValueGetArray(JSON_VALUE *value);
char * JsonValueGetStr(JSON_VALUE *value);
UINT64 JsonValueGetNumber(JSON_VALUE *value);
bool JsonValueGetBool(JSON_VALUE *value);
JSON_VALUE * JsonValueGetParent(JSON_VALUE *value);
/* Same as above, but shorter */
UINT JsonType(JSON_VALUE *value);
JSON_OBJECT * JsonObject(JSON_VALUE *value);
JSON_ARRAY * JsonArray(JSON_VALUE *value);
char * JsonString(JSON_VALUE *value);
UINT64 JsonNumber(JSON_VALUE *value);
int JsonBool(JSON_VALUE *value);
void SystemTimeToJsonStr(char *dst, UINT size, SYSTEMTIME *t);
void SystemTime64ToJsonStr(char *dst, UINT size, UINT64 t);
JSON_VALUE *StrToJson(char *str);
#endif // STR_H