1643 lines
34 KiB
C
1643 lines
34 KiB
C
#include "SHSSDK.h"
|
|
#include "main.h"
|
|
#include "solbox_util.h"
|
|
#include "GTS_INFO.h"
|
|
|
|
#undef HAVE_SSPI
|
|
|
|
#include "ne_request.h"
|
|
#include "ne_socket.h"
|
|
#include "ne_string.h"
|
|
#ifdef WIN32
|
|
#include <winsock2.h>
|
|
#include <ws2tcpip.h>
|
|
#pragma comment(lib, "ws2_32.lib")
|
|
#endif
|
|
|
|
#ifdef WIN32
|
|
typedef __int32 int32_t;
|
|
typedef unsigned __int32 uint32_t;
|
|
#endif
|
|
|
|
#define AUTHPRIME 137897
|
|
typedef struct _s_time_sync_t
|
|
{
|
|
int32_t sync_info;
|
|
}time_sync_t;
|
|
|
|
|
|
#pragma pack(1)
|
|
typedef struct {
|
|
char id[32];
|
|
char domain[128];
|
|
char domain2[128];
|
|
} SERVICE_STRUCT, *PSERVICE_STRUCT;
|
|
#pragma pack()
|
|
|
|
#pragma pack(1)
|
|
typedef struct {
|
|
char szTranId[52];
|
|
__int32 nMode;
|
|
char szIssuer[128];
|
|
char szServiceId[128];
|
|
__int32 nResult;
|
|
__int32 nLength;
|
|
} COMMAND_STRUCT, *PCOMMAND_STRUCT;
|
|
|
|
typedef struct {
|
|
char path[2048];
|
|
} PATHINFO_STRUCT, *PPATHINFO_STRUCT;
|
|
#pragma pack()
|
|
|
|
#define CENTER_HOST G_CENTERADDR
|
|
#define CENTER_PORT G_CENTERADDR_PORT
|
|
|
|
#define RCTS_PORT 13104
|
|
|
|
#define PRIVATE_KEY "I'm your father"
|
|
// 2013-12-27 dadamin
|
|
// GTS(cc_tsd) 통신 시 이용되는 구분자 변경
|
|
// sp-console => SP-Console3
|
|
// SHSSDK => SSDK
|
|
#ifdef _SP_SDK_
|
|
#define SERVER_NAME "SP-Console3"
|
|
#else // !_SP_SDK_
|
|
#define SERVER_NAME "SSDK"
|
|
#endif // _SP_SDK_
|
|
|
|
#define DELIMITER 0x1b
|
|
|
|
// cc_tsd
|
|
#define MODE_SRV_LST_2ND_REQUEST 0x0080
|
|
#define MODE_SRV_TRAFFIC_REQUEST 0x0082
|
|
|
|
// rc_mngd(rc_tsd)
|
|
#define SDK_REQ_VOLUME_INFO 0x0012 // old : MSG_MODE_SPCONS_RCTRAN_VOLUME_SIZE
|
|
#define SDK_REQ_SET_ANONY_DIR 0x0014 // old : MSG_MODE_SPCONS_RCTRAN_SET_ANONY
|
|
#define SDK_REQ_UNSET_ANONY_DIR 0x0018 // old : MSG_MODE_SPCONS_RCTRAN_UNSET_ANONY
|
|
#define SDK_REQ_ANONY_DIR 0x0030 // old : MSG_MODE_SPCONS_RCTRAN_RETRIVE_ANONY
|
|
|
|
/* Elenoa MOD : START */
|
|
/* default timeout 5 second */
|
|
#include <fcntl.h>
|
|
|
|
static int timeout = 5;
|
|
static char szCacheFile[MAX_PATH]={0};
|
|
|
|
static char g_cnthost[255] = CENTER_HOST;
|
|
static int g_cntport = CENTER_PORT;
|
|
static char g_sntphost[255] = SNTP_DOMAIN;
|
|
static int g_sntpport = SNTP_PORT;
|
|
|
|
static int _sh_send(SOCKET s, char *buf, int len);
|
|
static int _sh_recv(SOCKET s, char *buf, int len);
|
|
const char *sh_get_rcts_host(const char *userId, const char *password, const char *serviceId);
|
|
char* get_address(const char *userId, const char *password, const char *serviceId,int nFlag);
|
|
int get_psl_from_cache(PSERVICE_STRUCT *psl);
|
|
int set_psl_to_cache(PSERVICE_STRUCT *psl,int nCount);
|
|
|
|
#ifdef _WIN32
|
|
static int __nonblock_win32(SOCKET s)
|
|
{
|
|
int ul = 1;
|
|
int result;
|
|
|
|
result = ioctlsocket( s, FIONBIO, (u_long FAR*)&ul );
|
|
|
|
return result;
|
|
}
|
|
#else
|
|
static int __nonblock(int fd)
|
|
{
|
|
int result;
|
|
int flags;
|
|
|
|
flags = fcntl(fd, F_GETFL, 0);
|
|
result = fcntl(fd, F_SETFL, flags | O_NONBLOCK);
|
|
|
|
return result;
|
|
}
|
|
#endif
|
|
|
|
void sh_set_timeout(int second)
|
|
{
|
|
timeout = second;
|
|
}
|
|
/* Elenoa MOD : END */
|
|
|
|
int get_psl_from_cache(PSERVICE_STRUCT *psl)
|
|
{
|
|
int nCount = 0;
|
|
FILE* fp=NULL;
|
|
int i=0;
|
|
int numread=0;
|
|
|
|
int nErr = GetLastError();
|
|
|
|
if (strlen(szCacheFile) == 0)
|
|
{
|
|
if(nErr) SetLastError(nErr);
|
|
return 0;
|
|
}
|
|
|
|
fp = fopen(szCacheFile,"rb");
|
|
|
|
if(fp)
|
|
{
|
|
fread(&nCount,sizeof(int),1,fp);
|
|
|
|
*psl = malloc(sizeof(SERVICE_STRUCT) * nCount);
|
|
numread = fread(*psl,sizeof(SERVICE_STRUCT) * nCount,1,fp);
|
|
|
|
if (numread < 1)
|
|
{
|
|
SetLastError(SHERRNO_INVALIDCACHEFILE);
|
|
return 0;
|
|
}
|
|
|
|
fclose(fp);
|
|
}
|
|
|
|
if(nErr) SetLastError(nErr);
|
|
|
|
return nCount;
|
|
}
|
|
|
|
int set_psl_to_cache(PSERVICE_STRUCT *psl,int nCount)
|
|
{
|
|
FILE* fp=NULL;
|
|
int i=0;
|
|
|
|
if (strlen(szCacheFile) == 0)
|
|
return 0;
|
|
|
|
fp = fopen(szCacheFile,"wb");
|
|
|
|
if (fp)
|
|
{
|
|
fwrite(&nCount,sizeof(int),1,fp);
|
|
|
|
fwrite(*psl,sizeof(SERVICE_STRUCT)*nCount,1,fp);
|
|
fclose(fp);
|
|
}
|
|
|
|
return 1;
|
|
}
|
|
|
|
time_t get_time_from_sntp()
|
|
{
|
|
char szHost[128];
|
|
int nRecv;
|
|
time_sync_t tst;
|
|
int nWrite;
|
|
time_sync_t *pSyncInfo = NULL;
|
|
#ifdef WIN32
|
|
struct tm *ttm=NULL;
|
|
#endif
|
|
SOCKET sock;
|
|
struct sockaddr_in sa;
|
|
long ltime;
|
|
|
|
ltime = (long)time(NULL);
|
|
|
|
if (ne_sock_init() != NE_OK)
|
|
{
|
|
return ltime;
|
|
}
|
|
|
|
// Get server time
|
|
strcpy(szHost, g_sntphost);
|
|
if (isalpha(szHost[0]))
|
|
{
|
|
struct addrinfo *result;
|
|
struct addrinfo hints = {0};
|
|
struct sockaddr_in * addr;
|
|
|
|
hints.ai_socktype = SOCK_STREAM;
|
|
hints.ai_family = PF_UNSPEC;
|
|
|
|
if( getaddrinfo( szHost, NULL, &hints, &result ) != 0 )
|
|
{
|
|
return ltime;
|
|
}
|
|
|
|
sprintf(szHost, "%s", inet_ntoa(((struct sockaddr_in *)result->ai_addr)->sin_addr));
|
|
freeaddrinfo(result);
|
|
}
|
|
|
|
sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
|
|
if (sock == INVALID_SOCKET)
|
|
{
|
|
return ltime;
|
|
}
|
|
|
|
sa.sin_family = AF_INET;
|
|
sa.sin_addr.s_addr = inet_addr(szHost);
|
|
sa.sin_port = htons(g_sntpport);
|
|
|
|
#ifdef WIN32
|
|
__nonblock_win32(sock);
|
|
|
|
if (connect(sock, (SOCKADDR*)&sa, sizeof(sa)) == SOCKET_ERROR)
|
|
{
|
|
|
|
if (WSAEWOULDBLOCK == WSAGetLastError())
|
|
{
|
|
fd_set wfd, efd;
|
|
struct timeval tv;
|
|
FD_ZERO(&wfd);
|
|
FD_ZERO(&efd);
|
|
FD_SET(sock, &wfd);
|
|
FD_SET(sock, &efd);
|
|
tv.tv_sec = timeout;
|
|
tv.tv_usec = 0;
|
|
nRecv = select(0, 0, &wfd, &efd,&tv);
|
|
if (SOCKET_ERROR == nRecv || 0 == nRecv)
|
|
{
|
|
int nRet = WSAGetLastError();
|
|
return ltime;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
return ltime;
|
|
}
|
|
}
|
|
|
|
#else
|
|
__nonblock(sock);
|
|
{
|
|
int i, nRet;
|
|
for (i = 0; i < (timeout * 10); i++) {
|
|
if (connect(sock, (SOCKADDR*)&sa, sizeof(sa)) != SOCKET_ERROR) {
|
|
errno = 0;
|
|
break;
|
|
} else {
|
|
nRet = errno;
|
|
}
|
|
if (errno == EISCONN)
|
|
break;
|
|
|
|
if (((i + 1) % 10) == 0) {
|
|
shutdown(sock, 2);
|
|
//close(sock);
|
|
//fprintf(stderr, "RETRY ");
|
|
}
|
|
usleep(100000);
|
|
//fprintf(stderr, "CLI %d\n", i);
|
|
}
|
|
|
|
if (errno != EISCONN && errno != 0)
|
|
{
|
|
return ltime;
|
|
}
|
|
}
|
|
#endif
|
|
|
|
tst.sync_info = ltime + AUTHPRIME - (ltime % AUTHPRIME);
|
|
|
|
tst.sync_info = htonl(tst.sync_info);
|
|
nWrite = _sh_send(sock, (char *)&tst, sizeof(tst));
|
|
|
|
if(nWrite < 0)
|
|
{
|
|
closesocket(sock);
|
|
return ltime;
|
|
}
|
|
|
|
nRecv = _sh_recv(sock, szHost, sizeof(szHost));
|
|
|
|
if (nRecv < 4)
|
|
{
|
|
closesocket(sock);
|
|
return ltime;
|
|
}
|
|
|
|
pSyncInfo = (time_sync_t *)&szHost;
|
|
pSyncInfo->sync_info = ntohl(pSyncInfo->sync_info);
|
|
|
|
closesocket(sock);
|
|
|
|
return pSyncInfo->sync_info;
|
|
}
|
|
|
|
PSERVICE_STRUCT get_addressex(const char *userId, const char *password, int *cnt)
|
|
{
|
|
// define varialbles
|
|
char *pszResult = NULL;
|
|
|
|
char szMD5[256], szVerifyKey[256], szPassword[128], szAuth[256];
|
|
__int64 nRandom;
|
|
struct tm *ptmNow = NULL;
|
|
time_t tmtNow;
|
|
|
|
COMMAND_STRUCT cmd;
|
|
|
|
PSERVICE_STRUCT psl = NULL;
|
|
int i, nServiceCount = 0;
|
|
|
|
char szHost[30];
|
|
SOCKET sock = INVALID_SOCKET;
|
|
struct sockaddr_in sa;
|
|
BOOL bIsCache = FALSE;
|
|
|
|
// get current time & random number
|
|
if (ne_sock_init() != NE_OK)
|
|
{
|
|
SetLastError(GetLastError());
|
|
bIsCache = TRUE;
|
|
goto CACHE_FUNCTION;
|
|
}
|
|
|
|
tmtNow = get_time_from_sntp();
|
|
|
|
srand((unsigned int)tmtNow);
|
|
nRandom = rand() * rand();
|
|
|
|
ptmNow = gmtime((const time_t *)&tmtNow);
|
|
|
|
tmtNow %= 10000000000; // MAX 10
|
|
nRandom %= 10000000000; // MAX 10
|
|
|
|
// create command struct
|
|
#ifdef WIN32
|
|
sprintf(szMD5, "%010d%010I64d%s%s", tmtNow, nRandom, PRIVATE_KEY, SERVER_NAME);
|
|
#else
|
|
sprintf(szMD5, "%010d%010lld%s%s", (int)tmtNow, nRandom, PRIVATE_KEY, SERVER_NAME);
|
|
#endif
|
|
md5_buffer(szMD5, szVerifyKey);
|
|
|
|
md5_buffer(password, szPassword);
|
|
sprintf(szMD5, "%s%s%d", userId, szPassword, (int)tmtNow);
|
|
md5_buffer(szMD5, szPassword);
|
|
|
|
sprintf(szAuth, "%s%c%s%c%d", userId, DELIMITER, szPassword, DELIMITER, (int)tmtNow);
|
|
|
|
// Make header
|
|
#ifdef WIN32
|
|
memset((void *)&cmd, NULL, sizeof(cmd));
|
|
sprintf(cmd.szTranId, "%04d%02d%02d%02d%02d%02d-%.10s-%010d-%010I64d",
|
|
#else
|
|
memset((void *)&cmd, 0, sizeof(cmd));
|
|
sprintf(cmd.szTranId, "%04d%02d%02d%02d%02d%02d-%.10s-%010d-%010lld",
|
|
#endif
|
|
ptmNow->tm_year + 1900, ptmNow->tm_mon, ptmNow->tm_wday, ptmNow->tm_hour, ptmNow->tm_min, ptmNow->tm_sec,
|
|
szVerifyKey, (int)tmtNow, nRandom);
|
|
|
|
cmd.nMode = htonl(MODE_SRV_LST_2ND_REQUEST);
|
|
strcpy(cmd.szIssuer, SERVER_NAME);
|
|
cmd.nLength = htonl((u_long)strlen(szAuth));
|
|
|
|
// create socket
|
|
strcpy(szHost, g_cnthost);
|
|
if (isalpha(szHost[0])) {
|
|
struct addrinfo *result;
|
|
struct addrinfo hints = {0};
|
|
|
|
hints.ai_socktype = SOCK_STREAM;
|
|
hints.ai_family = PF_UNSPEC;
|
|
|
|
if( getaddrinfo( szHost, NULL, &hints, &result ) != 0 )
|
|
{
|
|
bIsCache = TRUE;
|
|
goto CACHE_FUNCTION;
|
|
}
|
|
|
|
sa.sin_addr.s_addr = ((struct sockaddr_in *)result->ai_addr)->sin_addr.s_addr;
|
|
freeaddrinfo(result);
|
|
}
|
|
else
|
|
sa.sin_addr.s_addr = inet_addr(szHost);
|
|
|
|
if ((sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) == INVALID_SOCKET)
|
|
{
|
|
bIsCache = TRUE;
|
|
goto CACHE_FUNCTION;
|
|
}
|
|
|
|
sa.sin_family = AF_INET;
|
|
sa.sin_port = htons(g_cntport);
|
|
|
|
/* Elenoa MOD : START */
|
|
#ifdef _WIN32
|
|
__nonblock_win32(sock);
|
|
|
|
if (connect(sock, (SOCKADDR*)&sa, sizeof(sa)) == SOCKET_ERROR)
|
|
{
|
|
|
|
if (WSAEWOULDBLOCK == WSAGetLastError())
|
|
{
|
|
fd_set wfd, efd;
|
|
struct timeval tv;
|
|
int result;
|
|
FD_ZERO(&wfd);
|
|
FD_ZERO(&efd);
|
|
FD_SET(sock, &wfd);
|
|
FD_SET(sock, &efd);
|
|
tv.tv_sec = timeout;
|
|
tv.tv_usec = 0;
|
|
result = select(0, 0, &wfd, &efd,&tv);
|
|
if (SOCKET_ERROR == result || 0 == result)
|
|
{
|
|
if(result == 0)
|
|
{
|
|
// time_out
|
|
SetLastError(WSAETIMEDOUT);
|
|
}
|
|
result = WSAGetLastError();
|
|
bIsCache = TRUE;
|
|
goto CACHE_FUNCTION;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
bIsCache = TRUE;
|
|
goto CACHE_FUNCTION;
|
|
}
|
|
}
|
|
|
|
#else
|
|
__nonblock(sock);
|
|
{
|
|
int i;
|
|
for (i = 0; i < (timeout * 10); i++) {
|
|
if (connect(sock, (SOCKADDR*)&sa, sizeof(sa)) != SOCKET_ERROR) {
|
|
errno = 0;
|
|
break;
|
|
}
|
|
if (errno == EISCONN)
|
|
break;
|
|
|
|
if (((i + 1) % 10) == 0)
|
|
{
|
|
shutdown(sock, 2);
|
|
//close(sock);
|
|
}
|
|
usleep(100000);
|
|
//fprintf(stderr, "%d\n", i);
|
|
}
|
|
|
|
if (errno != EISCONN && errno != 0)
|
|
{
|
|
bIsCache = TRUE;
|
|
goto CACHE_FUNCTION;
|
|
// goto EXIT_FUNCTION;
|
|
}
|
|
}
|
|
#endif
|
|
// Send packet
|
|
if (_sh_send(sock, (char *)&cmd, sizeof(cmd)) == SOCKET_ERROR)
|
|
{
|
|
bIsCache = TRUE;
|
|
goto CACHE_FUNCTION;
|
|
}
|
|
|
|
if (_sh_send(sock, szAuth, (int)strlen(szAuth)) == SOCKET_ERROR)
|
|
{
|
|
bIsCache = TRUE;
|
|
goto CACHE_FUNCTION;
|
|
}
|
|
|
|
if (_sh_recv(sock, (char*)&cmd, sizeof(cmd)) == SOCKET_ERROR)
|
|
{
|
|
bIsCache = TRUE;
|
|
goto CACHE_FUNCTION;
|
|
}
|
|
|
|
cmd.nLength = ntohl(cmd.nLength);
|
|
cmd.nResult = ntohl(cmd.nResult);
|
|
if (cmd.nResult != 0x1000) {
|
|
if (cmd.nResult == 0x3000)
|
|
SetLastError(SHERRNO_UNDEFINED);
|
|
else if (cmd.nResult == 0x3001)
|
|
SetLastError(SHERRNO_AUTHORIZATION);
|
|
else if (cmd.nResult == 0x9000)
|
|
SetLastError(SHERRNO_INTERNAL);
|
|
|
|
bIsCache = TRUE;
|
|
goto CACHE_FUNCTION;
|
|
}
|
|
|
|
if (_sh_recv(sock, (char*)&nServiceCount, 4) == SOCKET_ERROR)
|
|
{
|
|
bIsCache = TRUE;
|
|
goto CACHE_FUNCTION;
|
|
}
|
|
|
|
nServiceCount = ntohl(nServiceCount);
|
|
if(cnt) *cnt = nServiceCount;
|
|
psl = malloc(sizeof(SERVICE_STRUCT) * nServiceCount);
|
|
|
|
if (!psl)
|
|
goto EXIT_FUNCTION;
|
|
|
|
if (_sh_recv(sock, (char*)psl, sizeof(SERVICE_STRUCT) * nServiceCount) == SOCKET_ERROR)
|
|
{
|
|
bIsCache = TRUE;
|
|
if (psl)
|
|
free(psl);
|
|
goto CACHE_FUNCTION;
|
|
}
|
|
|
|
closesocket(sock);
|
|
sock = INVALID_SOCKET;
|
|
|
|
set_psl_to_cache(&psl,nServiceCount); // 캐쉬파일에 기록
|
|
|
|
if ( nServiceCount == 0 )
|
|
SetLastError(SHERRNO_NOSERVICE);
|
|
|
|
CACHE_FUNCTION:
|
|
|
|
if( bIsCache)
|
|
nServiceCount = get_psl_from_cache(&psl);
|
|
|
|
EXIT_FUNCTION:
|
|
i = GetLastError();
|
|
|
|
//if (psl)
|
|
// free(psl);
|
|
|
|
if (sock != INVALID_SOCKET)
|
|
closesocket(sock);
|
|
|
|
SetLastError(i);
|
|
return psl;
|
|
}
|
|
|
|
char* get_address(const char *userId, const char *password, const char *serviceId,int nFlag)
|
|
{
|
|
// define varialbles
|
|
char *pszResult = NULL;
|
|
|
|
char szMD5[256], szVerifyKey[256], szPassword[128], szAuth[256];
|
|
__int64 nRandom;
|
|
struct tm *ptmNow = NULL;
|
|
time_t tmtNow;
|
|
|
|
COMMAND_STRUCT cmd;
|
|
|
|
PSERVICE_STRUCT psl = NULL;
|
|
int i, nServiceCount = 0;
|
|
|
|
char szHost[30];
|
|
SOCKET sock = INVALID_SOCKET;
|
|
struct sockaddr_in sa;
|
|
BOOL bIsCache = FALSE;
|
|
|
|
// get current time & random number
|
|
if (ne_sock_init() != NE_OK)
|
|
{
|
|
SetLastError(GetLastError());
|
|
bIsCache = TRUE;
|
|
goto CACHE_FUNCTION;
|
|
}
|
|
|
|
tmtNow = get_time_from_sntp();
|
|
|
|
srand((unsigned int)tmtNow);
|
|
nRandom = rand() * rand();
|
|
|
|
ptmNow = gmtime((const time_t *)&tmtNow);
|
|
|
|
tmtNow %= 10000000000; // MAX 10
|
|
nRandom %= 10000000000; // MAX 10
|
|
|
|
// create command struct
|
|
#ifdef WIN32
|
|
sprintf(szMD5, "%010d%010I64d%s%s", tmtNow, nRandom, PRIVATE_KEY, SERVER_NAME);
|
|
#else
|
|
sprintf(szMD5, "%010d%010lld%s%s", (int)tmtNow, nRandom, PRIVATE_KEY, SERVER_NAME);
|
|
#endif
|
|
//md5_buffer(szMD5, szVerifyKey);
|
|
|
|
md5_buffer(password, szPassword);
|
|
sprintf(szMD5, "%s%s%d", userId, szPassword, (int)tmtNow);
|
|
md5_buffer(szMD5, szPassword);
|
|
|
|
sprintf(szAuth, "%s%c%s%c%d", userId, DELIMITER, szPassword, DELIMITER, (int)tmtNow);
|
|
|
|
// Make header
|
|
#ifdef WIN32
|
|
memset((void *)&cmd, NULL, sizeof(cmd));
|
|
sprintf(cmd.szTranId, "%04d%02d%02d%02d%02d%02d-%.10s-%010d-%010I64d",
|
|
#else
|
|
memset((void *)&cmd, 0, sizeof(cmd));
|
|
sprintf(cmd.szTranId, "%04d%02d%02d%02d%02d%02d-%.10s-%010d-%010lld",
|
|
#endif
|
|
ptmNow->tm_year + 1900, ptmNow->tm_mon, ptmNow->tm_wday, ptmNow->tm_hour, ptmNow->tm_min, ptmNow->tm_sec,
|
|
szVerifyKey, (int)tmtNow, nRandom);
|
|
|
|
cmd.nMode = htonl(MODE_SRV_LST_2ND_REQUEST);
|
|
strcpy(cmd.szIssuer, SERVER_NAME);
|
|
cmd.nLength = htonl((u_long)strlen(szAuth));
|
|
|
|
// create socket
|
|
strcpy(szHost, g_cnthost);
|
|
if (isalpha(szHost[0])) {
|
|
struct addrinfo *result;
|
|
struct addrinfo hints = {0};
|
|
|
|
hints.ai_socktype = SOCK_STREAM;
|
|
hints.ai_family = PF_UNSPEC;
|
|
|
|
if( getaddrinfo( szHost, NULL, &hints, &result ) != 0 )
|
|
{
|
|
bIsCache = TRUE;
|
|
goto CACHE_FUNCTION;
|
|
}
|
|
|
|
sa.sin_addr.s_addr = ((struct sockaddr_in *)result->ai_addr)->sin_addr.s_addr;
|
|
freeaddrinfo(result);
|
|
}
|
|
else
|
|
sa.sin_addr.s_addr = inet_addr(szHost);
|
|
|
|
if ((sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) == INVALID_SOCKET)
|
|
{
|
|
bIsCache = TRUE;
|
|
goto CACHE_FUNCTION;
|
|
}
|
|
|
|
sa.sin_family = AF_INET;
|
|
sa.sin_port = htons(g_cntport);
|
|
|
|
/* Elenoa MOD : START */
|
|
#ifdef _WIN32
|
|
__nonblock_win32(sock);
|
|
|
|
if (connect(sock, (SOCKADDR*)&sa, sizeof(sa)) == SOCKET_ERROR)
|
|
{
|
|
|
|
if (WSAEWOULDBLOCK == WSAGetLastError())
|
|
{
|
|
fd_set wfd, efd;
|
|
struct timeval tv;
|
|
int result;
|
|
FD_ZERO(&wfd);
|
|
FD_ZERO(&efd);
|
|
FD_SET(sock, &wfd);
|
|
FD_SET(sock, &efd);
|
|
tv.tv_sec = timeout;
|
|
tv.tv_usec = 0;
|
|
result = select(0, 0, &wfd, &efd,&tv);
|
|
if (SOCKET_ERROR == result || 0 == result)
|
|
{
|
|
if(result == 0)
|
|
{
|
|
// time_out
|
|
SetLastError(WSAETIMEDOUT);
|
|
}
|
|
|
|
result = WSAGetLastError();
|
|
bIsCache = TRUE;
|
|
goto CACHE_FUNCTION;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
bIsCache = TRUE;
|
|
goto CACHE_FUNCTION;
|
|
}
|
|
}
|
|
|
|
#else
|
|
__nonblock(sock);
|
|
{
|
|
int i;
|
|
for (i = 0; i < (timeout * 10); i++) {
|
|
if (connect(sock, (SOCKADDR*)&sa, sizeof(sa)) != SOCKET_ERROR) {
|
|
errno = 0;
|
|
break;
|
|
}
|
|
if (errno == EISCONN)
|
|
break;
|
|
|
|
if (((i + 1) % 10) == 0)
|
|
{
|
|
shutdown(sock, 2);
|
|
//close(sock);
|
|
}
|
|
usleep(100000);
|
|
//fprintf(stderr, "%d\n", i);
|
|
}
|
|
|
|
if (errno != EISCONN && errno != 0)
|
|
{
|
|
bIsCache = TRUE;
|
|
goto CACHE_FUNCTION;
|
|
// goto EXIT_FUNCTION;
|
|
}
|
|
}
|
|
#endif
|
|
// Send packet
|
|
if (_sh_send(sock, (char *)&cmd, sizeof(cmd)) == SOCKET_ERROR)
|
|
{
|
|
bIsCache = TRUE;
|
|
goto CACHE_FUNCTION;
|
|
}
|
|
|
|
if (_sh_send(sock, szAuth, (int)strlen(szAuth)) == SOCKET_ERROR)
|
|
{
|
|
bIsCache = TRUE;
|
|
goto CACHE_FUNCTION;
|
|
}
|
|
|
|
if (_sh_recv(sock, (char*)&cmd, sizeof(cmd)) == SOCKET_ERROR)
|
|
{
|
|
bIsCache = TRUE;
|
|
goto CACHE_FUNCTION;
|
|
}
|
|
|
|
cmd.nLength = ntohl(cmd.nLength);
|
|
cmd.nResult = ntohl(cmd.nResult);
|
|
if (cmd.nResult != 0x1000) {
|
|
if (cmd.nResult == 0x3000)
|
|
SetLastError(SHERRNO_UNDEFINED);
|
|
else if (cmd.nResult == 0x3001)
|
|
SetLastError(SHERRNO_AUTHORIZATION);
|
|
else if (cmd.nResult == 0x9000)
|
|
SetLastError(SHERRNO_INTERNAL);
|
|
|
|
bIsCache = TRUE;
|
|
goto CACHE_FUNCTION;
|
|
}
|
|
|
|
if (_sh_recv(sock, (char*)&nServiceCount, 4) == SOCKET_ERROR)
|
|
{
|
|
bIsCache = TRUE;
|
|
goto CACHE_FUNCTION;
|
|
}
|
|
|
|
nServiceCount = ntohl(nServiceCount);
|
|
psl = malloc(sizeof(SERVICE_STRUCT) * nServiceCount);
|
|
|
|
if (!psl)
|
|
goto EXIT_FUNCTION;
|
|
|
|
if (_sh_recv(sock, (char*)psl, sizeof(SERVICE_STRUCT) * nServiceCount) == SOCKET_ERROR)
|
|
{
|
|
bIsCache = TRUE;
|
|
if (psl)
|
|
free(psl);
|
|
goto CACHE_FUNCTION;
|
|
}
|
|
|
|
closesocket(sock);
|
|
sock = INVALID_SOCKET;
|
|
|
|
set_psl_to_cache(&psl,nServiceCount); // 캐쉬파일에 기록
|
|
|
|
if (!pszResult)
|
|
SetLastError(SHERRNO_NOSERVICE);
|
|
|
|
CACHE_FUNCTION:
|
|
|
|
if( bIsCache)
|
|
nServiceCount = get_psl_from_cache(&psl);
|
|
|
|
for (i = 0; i < nServiceCount; i++) {
|
|
if (strcmp((const char *)psl[i].id, serviceId) == 0)
|
|
{
|
|
switch(nFlag)
|
|
{
|
|
case 0: // dav address
|
|
strcat(psl[i].domain2, "/dav");
|
|
pszResult = strdup((const char *)psl[i].domain2);
|
|
break;
|
|
case 1: // rcts adress
|
|
pszResult = strdup((const char *)psl[i].domain);
|
|
break;
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
|
|
EXIT_FUNCTION:
|
|
i = GetLastError();
|
|
|
|
if (psl)
|
|
free(psl);
|
|
|
|
if (sock != INVALID_SOCKET)
|
|
closesocket(sock);
|
|
|
|
SetLastError(i);
|
|
|
|
return pszResult;
|
|
}
|
|
|
|
const char *sh_get_service_host(const char *userId, const char *password, const char *serviceId)
|
|
{
|
|
return get_address(userId,password,serviceId,0);
|
|
}
|
|
|
|
const char *sh_get_rcts_host(const char *userId, const char *password, const char *serviceId)
|
|
{
|
|
return get_address(userId,password,serviceId,1);
|
|
}
|
|
|
|
void sh_mem_free(void* pData)
|
|
{
|
|
free(pData);
|
|
}
|
|
|
|
const int sh_get_service_info(const char *userId, const char *password, const char *serviceId, PINT64 totalSpace, PINT64 freeSpace)
|
|
{
|
|
// define varialbles
|
|
int nResult = 0;
|
|
|
|
char szMD5[256], szVerifyKey[256], szPassword[128], szAuth[256];
|
|
__int64 nRandom;
|
|
struct tm *ptmNow = NULL;
|
|
time_t tmtNow;
|
|
char* pdata;
|
|
|
|
COMMAND_STRUCT cmd;
|
|
|
|
char szRecvBuf[1024], *pszUsedSpace;
|
|
int i;
|
|
|
|
SOCKET sock = INVALID_SOCKET;
|
|
struct sockaddr_in sa;
|
|
|
|
char* pszHost = (char *)sh_get_rcts_host(userId, password, serviceId);
|
|
|
|
if (!pszHost)
|
|
return 0;
|
|
|
|
pdata = strstr(pszHost,"/");
|
|
|
|
if (pdata)
|
|
*pdata = 0x00;
|
|
|
|
// get current time & random number
|
|
tmtNow = get_time_from_sntp();
|
|
|
|
|
|
srand((unsigned int)tmtNow);
|
|
nRandom = rand() * rand();
|
|
|
|
ptmNow = gmtime((const time_t *)&tmtNow);
|
|
|
|
tmtNow %= 10000000000; // MAX 10
|
|
nRandom %= 10000000000; // MAX 10
|
|
|
|
// create command struct
|
|
#ifdef WIN32
|
|
sprintf(szMD5, "%010d%010I64d%s%s", tmtNow, nRandom, PRIVATE_KEY, SERVER_NAME);
|
|
#else
|
|
sprintf(szMD5, "%010d%010lld%s%s", (int)tmtNow, nRandom, PRIVATE_KEY, SERVER_NAME);
|
|
#endif
|
|
md5_buffer(szMD5, szVerifyKey);
|
|
|
|
md5_buffer(password, szPassword);
|
|
sprintf(szMD5, "%s@%s%s%d", serviceId, userId, szPassword, (int)tmtNow);
|
|
md5_buffer(szMD5, szPassword);
|
|
|
|
sprintf(szAuth, "%s@%s%c%s%c%d", serviceId, userId, DELIMITER, szPassword, DELIMITER, (int)tmtNow);
|
|
|
|
// Make header
|
|
|
|
#ifdef WIN32
|
|
memset((void *)&cmd, NULL, sizeof(cmd));
|
|
sprintf(cmd.szTranId, "%04d%02d%02d%02d%02d%02d-%.10s-%010d-%010I64d",
|
|
#else
|
|
memset((void *)&cmd, 0, sizeof(cmd));
|
|
sprintf(cmd.szTranId, "%04d%02d%02d%02d%02d%02d-%.10s-%010d-%010lld",
|
|
#endif
|
|
ptmNow->tm_year + 1900, ptmNow->tm_mon+1, ptmNow->tm_mday, ptmNow->tm_hour, ptmNow->tm_min, ptmNow->tm_sec,
|
|
szVerifyKey, (int)tmtNow, nRandom);
|
|
cmd.nMode = htonl(SDK_REQ_VOLUME_INFO);
|
|
strcpy(cmd.szIssuer, SERVER_NAME);
|
|
strcpy(cmd.szServiceId, serviceId);
|
|
cmd.nLength = htonl((u_long)strlen(szAuth));
|
|
|
|
// create socket
|
|
if (isalpha(pszHost[0])) {
|
|
struct addrinfo *result;
|
|
struct addrinfo hints = {0};
|
|
|
|
hints.ai_socktype = SOCK_STREAM;
|
|
hints.ai_family = PF_UNSPEC;
|
|
|
|
if( getaddrinfo( pszHost, NULL, &hints, &result ) != 0 )
|
|
goto EXIT_FUNCTION;
|
|
|
|
sa.sin_addr.s_addr = ((struct sockaddr_in *)result->ai_addr)->sin_addr.s_addr;
|
|
freeaddrinfo(result);
|
|
}
|
|
else
|
|
sa.sin_addr.s_addr = inet_addr(pszHost);
|
|
|
|
if ((sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) == INVALID_SOCKET)
|
|
goto EXIT_FUNCTION;
|
|
|
|
sa.sin_family = AF_INET;
|
|
sa.sin_port = htons(RCTS_PORT);
|
|
|
|
/* Elenoa MOD : START */
|
|
#ifdef _WIN32
|
|
__nonblock_win32(sock);
|
|
|
|
if (connect(sock, (SOCKADDR*)&sa, sizeof(sa)) == SOCKET_ERROR)
|
|
{
|
|
|
|
if (WSAEWOULDBLOCK == WSAGetLastError())
|
|
{
|
|
fd_set wfd, efd;
|
|
struct timeval tv;
|
|
int result;
|
|
FD_ZERO(&wfd);
|
|
FD_ZERO(&efd);
|
|
FD_SET(sock, &wfd);
|
|
FD_SET(sock, &efd);
|
|
tv.tv_sec = timeout;
|
|
tv.tv_usec = 0;
|
|
result = select(0, 0, &wfd, &efd,&tv);
|
|
if (SOCKET_ERROR == result || 0 == result)
|
|
{
|
|
int nRet = WSAGetLastError();
|
|
goto EXIT_FUNCTION;
|
|
}
|
|
}
|
|
else
|
|
goto EXIT_FUNCTION;
|
|
}
|
|
|
|
#else
|
|
__nonblock(sock);
|
|
{
|
|
int i;
|
|
for (i = 0; i < (timeout * 10); i++) {
|
|
if (connect(sock, (SOCKADDR*)&sa, sizeof(sa)) != SOCKET_ERROR) {
|
|
errno = 0;
|
|
break;
|
|
}
|
|
if (errno == EISCONN)
|
|
break;
|
|
|
|
if (((i + 1) % 10) == 0)
|
|
{
|
|
shutdown(sock, 2);
|
|
close(sock);
|
|
}
|
|
usleep(100000);
|
|
//fprintf(stderr, "%d\n", i);
|
|
}
|
|
|
|
if (errno != EISCONN && errno != 0)
|
|
goto EXIT_FUNCTION;
|
|
}
|
|
#endif
|
|
|
|
// Send packet
|
|
if (_sh_send(sock, (char *)&cmd, sizeof(cmd)) == SOCKET_ERROR)
|
|
goto EXIT_FUNCTION;
|
|
|
|
if (_sh_send(sock, szAuth, (int)strlen(szAuth)) == SOCKET_ERROR)
|
|
goto EXIT_FUNCTION;
|
|
|
|
if (_sh_recv(sock, (char*)&cmd, sizeof(cmd)) == SOCKET_ERROR)
|
|
goto EXIT_FUNCTION;
|
|
|
|
cmd.nLength = ntohl(cmd.nLength);
|
|
cmd.nResult = ntohl(cmd.nResult);
|
|
if (cmd.nResult != 0x1000) {
|
|
if (cmd.nResult == 0x3000)
|
|
SetLastError(SHERRNO_UNDEFINED);
|
|
else if (cmd.nResult == 0x3001)
|
|
SetLastError(SHERRNO_AUTHORIZATION);
|
|
else if (cmd.nResult == 0x9000)
|
|
SetLastError(SHERRNO_INTERNAL);
|
|
goto EXIT_FUNCTION;
|
|
}
|
|
|
|
if (_sh_recv(sock, szRecvBuf, cmd.nLength) == SOCKET_ERROR)
|
|
goto EXIT_FUNCTION;
|
|
|
|
closesocket(sock);
|
|
sock = INVALID_SOCKET;
|
|
|
|
pszUsedSpace = strchr(szRecvBuf, DELIMITER);
|
|
*(pszUsedSpace++) = (char)NULL;
|
|
|
|
#ifdef WIN32
|
|
*totalSpace = _atoi64(szRecvBuf);
|
|
*freeSpace = *totalSpace - _atoi64(pszUsedSpace);
|
|
#else
|
|
*totalSpace = strtoll(szRecvBuf, NULL, 10);
|
|
*freeSpace = *totalSpace - strtoll(pszUsedSpace, NULL, 10);
|
|
#endif
|
|
|
|
nResult = 1;
|
|
|
|
EXIT_FUNCTION:
|
|
i = GetLastError();
|
|
|
|
if (pszHost)
|
|
free(pszHost);
|
|
|
|
if (sock != INVALID_SOCKET)
|
|
closesocket(sock);
|
|
|
|
SetLastError(i);
|
|
|
|
return nResult;
|
|
}
|
|
|
|
#ifndef WIN32
|
|
void SetLastError(int nErrCode)
|
|
{
|
|
errno = nErrCode;
|
|
}
|
|
|
|
#endif
|
|
|
|
/* Elenoa MOD START */
|
|
static int _sh_send(SOCKET s, char *pszBuf, int nLen)
|
|
{
|
|
int iSent = 0, nSentLen;
|
|
fd_set wset;
|
|
struct timeval tv;
|
|
|
|
FD_ZERO(&wset);
|
|
FD_SET(s, &wset);
|
|
tv.tv_sec = timeout;
|
|
tv.tv_usec = 0;
|
|
do {
|
|
//if (select(s + 1, NULL, &wset, NULL, &tv) < 0) break;
|
|
|
|
int n = select(s + 1, NULL, &wset, NULL, &tv);
|
|
|
|
if(n == 0)
|
|
{
|
|
// time_out
|
|
#ifdef WIN32
|
|
SetLastError(WSAETIMEDOUT);
|
|
#else // WIN32
|
|
SetLastError(ETIMEDOUT);
|
|
#endif // WIN32
|
|
break;
|
|
}
|
|
else if ( n < 0 )
|
|
{
|
|
// error
|
|
SetLastError(GetLastError());
|
|
break;
|
|
}
|
|
|
|
|
|
if (!FD_ISSET(s, &wset)) break;
|
|
|
|
nSentLen = send(s, pszBuf + iSent, nLen, 0);
|
|
|
|
iSent += nSentLen;
|
|
nLen -= nSentLen;
|
|
} while (nLen > 0 && nSentLen > 0);
|
|
|
|
return nLen > 0 ? SOCKET_ERROR : iSent;
|
|
}
|
|
|
|
static int _sh_recv(SOCKET s, char *pszBuf, int nLen)
|
|
{
|
|
int iRecv = 0, nRecvLen;
|
|
fd_set rset;
|
|
struct timeval tv;
|
|
int nRet;
|
|
|
|
FD_ZERO(&rset);
|
|
FD_SET(s, &rset);
|
|
tv.tv_sec = timeout;
|
|
tv.tv_usec = 0;
|
|
do {
|
|
nRet = select(s + 1, &rset, NULL, NULL, &tv);
|
|
|
|
if (nRet == 0)
|
|
{
|
|
// time out
|
|
#ifdef WIN32
|
|
SetLastError(WSAETIMEDOUT);
|
|
#else // WIN32
|
|
SetLastError(ETIMEDOUT);
|
|
#endif // WIN32
|
|
break;
|
|
}
|
|
else if (nRet < 0)
|
|
{
|
|
// error
|
|
SetLastError(GetLastError());
|
|
break;
|
|
}
|
|
|
|
if (!FD_ISSET(s, &rset)) break;
|
|
|
|
nRecvLen = recv(s, pszBuf + iRecv, nLen, 0);
|
|
|
|
iRecv += nRecvLen;
|
|
nLen -= nRecvLen;
|
|
} while (nLen > 0 && nRecvLen > 0);
|
|
|
|
return nLen < 0 ? SOCKET_ERROR : iRecv;
|
|
}
|
|
|
|
|
|
void sh_set_cache_file(const char *file_path)
|
|
{
|
|
strncpy(szCacheFile,file_path,sizeof(szCacheFile));
|
|
}
|
|
|
|
void * sh_get_service_list(const char *userId, const char *password, int *cnt)
|
|
{
|
|
PSERVICE_STRUCT psl = NULL;
|
|
|
|
if(cnt)
|
|
*cnt = 0;
|
|
|
|
psl = get_addressex(userId, password, cnt);
|
|
return (void*) psl;
|
|
}
|
|
|
|
void sh_set_center_info ( const char *host, int port )
|
|
{
|
|
if(host && strlen(host) > 0 )
|
|
strcpy(g_cnthost, host);
|
|
else
|
|
strcpy(g_cnthost, CENTER_HOST);
|
|
|
|
if(port > 0)
|
|
g_cntport = port;
|
|
else
|
|
g_cntport = CENTER_PORT;
|
|
}
|
|
|
|
void sh_set_sntp_info ( const char *host, int port )
|
|
{
|
|
if(host && strlen(host) > 0 )
|
|
strcpy(g_sntphost, host);
|
|
else
|
|
strcpy(g_sntphost, SNTP_DOMAIN);
|
|
|
|
if(port > 0)
|
|
g_sntpport = port;
|
|
else
|
|
g_sntpport = SNTP_PORT;
|
|
}
|
|
|
|
void* sh_get_anonyauth( const char *userId, const char *password, const char *serviceId, int * cnt)
|
|
{
|
|
PPATHINFO_STRUCT ppl = NULL;
|
|
char szMD5[256], szVerifyKey[256], szPassword[128], szAuth[256];
|
|
__int64 nRandom;
|
|
struct tm *ptmNow = NULL;
|
|
time_t tmtNow;
|
|
char* pdata;
|
|
|
|
COMMAND_STRUCT cmd;
|
|
|
|
char szRecvBuf[1024], *pszUsedSpace;
|
|
int i;
|
|
int nCount = 0;
|
|
|
|
SOCKET sock = INVALID_SOCKET;
|
|
struct sockaddr_in sa;
|
|
|
|
char* pszHost = (char *)sh_get_rcts_host(userId, password, serviceId);
|
|
|
|
if (!pszHost)
|
|
return 0;
|
|
|
|
pdata = strstr(pszHost,"/");
|
|
|
|
if (pdata)
|
|
*pdata = 0x00;
|
|
|
|
// get current time & random number
|
|
tmtNow = get_time_from_sntp();
|
|
|
|
|
|
srand((unsigned int)tmtNow);
|
|
nRandom = rand() * rand();
|
|
|
|
ptmNow = gmtime((const time_t *)&tmtNow);
|
|
|
|
tmtNow %= 10000000000; // MAX 10
|
|
nRandom %= 10000000000; // MAX 10
|
|
|
|
// create command struct
|
|
#ifdef WIN32
|
|
sprintf(szMD5, "%010d%010I64d%s%s", tmtNow, nRandom, PRIVATE_KEY, SERVER_NAME);
|
|
#else
|
|
sprintf(szMD5, "%010d%010lld%s%s", (int)tmtNow, nRandom, PRIVATE_KEY, SERVER_NAME);
|
|
#endif
|
|
md5_buffer(szMD5, szVerifyKey);
|
|
|
|
md5_buffer(password, szPassword);
|
|
sprintf(szMD5, "%s@%s%s%d", serviceId, userId, szPassword, (int)tmtNow);
|
|
md5_buffer(szMD5, szPassword);
|
|
|
|
sprintf(szAuth, "%s@%s%c%s%c%d", serviceId, userId, DELIMITER, szPassword, DELIMITER, (int)tmtNow);
|
|
|
|
// Make header
|
|
|
|
#ifdef WIN32
|
|
memset((void *)&cmd, NULL, sizeof(cmd));
|
|
sprintf(cmd.szTranId, "%04d%02d%02d%02d%02d%02d-%.10s-%010d-%010I64d",
|
|
#else
|
|
memset((void *)&cmd, 0, sizeof(cmd));
|
|
sprintf(cmd.szTranId, "%04d%02d%02d%02d%02d%02d-%.10s-%010d-%010lld",
|
|
#endif
|
|
ptmNow->tm_year + 1900, ptmNow->tm_mon+1, ptmNow->tm_mday, ptmNow->tm_hour, ptmNow->tm_min, ptmNow->tm_sec,
|
|
szVerifyKey, (int)tmtNow, nRandom);
|
|
cmd.nMode = htonl(SDK_REQ_ANONY_DIR);
|
|
strcpy(cmd.szIssuer, SERVER_NAME);
|
|
strcpy(cmd.szServiceId, serviceId);
|
|
cmd.nLength = htonl((u_long)strlen(szAuth));
|
|
|
|
// create socket
|
|
if (isalpha(pszHost[0])) {
|
|
struct addrinfo *result;
|
|
struct addrinfo hints = {0};
|
|
|
|
hints.ai_socktype = SOCK_STREAM;
|
|
hints.ai_family = PF_UNSPEC;
|
|
|
|
if( getaddrinfo( pszHost, NULL, &hints, &result ) != 0 )
|
|
goto EXIT_FUNCTION;
|
|
|
|
sa.sin_addr.s_addr = ((struct sockaddr_in *)result->ai_addr)->sin_addr.s_addr;
|
|
freeaddrinfo(result);
|
|
}
|
|
else
|
|
sa.sin_addr.s_addr = inet_addr(pszHost);
|
|
|
|
if ((sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) == INVALID_SOCKET)
|
|
goto EXIT_FUNCTION;
|
|
|
|
sa.sin_family = AF_INET;
|
|
sa.sin_port = htons(RCTS_PORT);
|
|
|
|
/* Elenoa MOD : START */
|
|
#ifdef _WIN32
|
|
__nonblock_win32(sock);
|
|
|
|
if (connect(sock, (SOCKADDR*)&sa, sizeof(sa)) == SOCKET_ERROR)
|
|
{
|
|
|
|
if (WSAEWOULDBLOCK == WSAGetLastError())
|
|
{
|
|
fd_set wfd, efd;
|
|
struct timeval tv;
|
|
int result;
|
|
FD_ZERO(&wfd);
|
|
FD_ZERO(&efd);
|
|
FD_SET(sock, &wfd);
|
|
FD_SET(sock, &efd);
|
|
tv.tv_sec = timeout;
|
|
tv.tv_usec = 0;
|
|
result = select(0, 0, &wfd, &efd,&tv);
|
|
if (SOCKET_ERROR == result || 0 == result)
|
|
{
|
|
int nRet = WSAGetLastError();
|
|
goto EXIT_FUNCTION;
|
|
}
|
|
}
|
|
else
|
|
goto EXIT_FUNCTION;
|
|
}
|
|
|
|
#else
|
|
__nonblock(sock);
|
|
{
|
|
int i;
|
|
for (i = 0; i < (timeout * 10); i++) {
|
|
if (connect(sock, (SOCKADDR*)&sa, sizeof(sa)) != SOCKET_ERROR) {
|
|
errno = 0;
|
|
break;
|
|
}
|
|
if (errno == EISCONN)
|
|
break;
|
|
|
|
if (((i + 1) % 10) == 0)
|
|
{
|
|
shutdown(sock, 2);
|
|
close(sock);
|
|
}
|
|
usleep(100000);
|
|
//fprintf(stderr, "%d\n", i);
|
|
}
|
|
|
|
if (errno != EISCONN && errno != 0)
|
|
goto EXIT_FUNCTION;
|
|
}
|
|
#endif
|
|
|
|
// Send packet
|
|
if (_sh_send(sock, (char *)&cmd, sizeof(cmd)) == SOCKET_ERROR)
|
|
goto EXIT_FUNCTION;
|
|
|
|
if (_sh_send(sock, szAuth, (int)strlen(szAuth)) == SOCKET_ERROR)
|
|
goto EXIT_FUNCTION;
|
|
|
|
if (_sh_recv(sock, (char*)&cmd, sizeof(cmd)) == SOCKET_ERROR)
|
|
goto EXIT_FUNCTION;
|
|
|
|
cmd.nLength = ntohl(cmd.nLength);
|
|
cmd.nResult = ntohl(cmd.nResult);
|
|
if (cmd.nResult != 0x1000) {
|
|
if (cmd.nResult == 0x3000)
|
|
SetLastError(SHERRNO_UNDEFINED);
|
|
else if (cmd.nResult == 0x3001)
|
|
SetLastError(SHERRNO_AUTHORIZATION);
|
|
else if (cmd.nResult == 0x9000)
|
|
SetLastError(SHERRNO_INTERNAL);
|
|
goto EXIT_FUNCTION;
|
|
}
|
|
|
|
if (_sh_recv(sock, (char*)&nCount, 4) == SOCKET_ERROR)
|
|
{
|
|
goto EXIT_FUNCTION;
|
|
}
|
|
|
|
nCount = ntohl(nCount);
|
|
if(cnt) *cnt = nCount;
|
|
|
|
if(nCount > 0)
|
|
{
|
|
ppl = malloc(sizeof(PATHINFO_STRUCT) * nCount);
|
|
|
|
if (!ppl)
|
|
goto EXIT_FUNCTION;
|
|
|
|
|
|
if (_sh_recv(sock, (char*)ppl, sizeof(PATHINFO_STRUCT) * nCount) == SOCKET_ERROR)
|
|
{
|
|
if (ppl)
|
|
{
|
|
free(ppl);
|
|
ppl = NULL;
|
|
}
|
|
goto EXIT_FUNCTION;
|
|
}
|
|
}
|
|
|
|
|
|
closesocket(sock);
|
|
sock = INVALID_SOCKET;
|
|
|
|
EXIT_FUNCTION:
|
|
i = GetLastError();
|
|
|
|
if (pszHost)
|
|
free(pszHost);
|
|
|
|
if (sock != INVALID_SOCKET)
|
|
closesocket(sock);
|
|
|
|
SetLastError(i);
|
|
return ppl;
|
|
}
|
|
|
|
int sh_set_anonyauth(const char *userId, const char *password, const char *serviceId, int set, int sendlen, const void *sendmsg)
|
|
{
|
|
char szMD5[256], szVerifyKey[256], szPassword[128], szAuth[256];
|
|
__int64 nRandom;
|
|
struct tm *ptmNow = NULL;
|
|
time_t tmtNow;
|
|
char* pdata;
|
|
char* pSendData = NULL;
|
|
|
|
COMMAND_STRUCT cmd;
|
|
|
|
char szRecvBuf[1024], *pszUsedSpace;
|
|
int i;
|
|
int nCount = 0, ret = 0;
|
|
|
|
SOCKET sock = INVALID_SOCKET;
|
|
struct sockaddr_in sa;
|
|
|
|
int nCommand = (set ? SDK_REQ_SET_ANONY_DIR : SDK_REQ_UNSET_ANONY_DIR);
|
|
char* pszHost = (char *)sh_get_rcts_host(userId, password, serviceId);
|
|
|
|
if (!pszHost)
|
|
return 0;
|
|
|
|
pdata = strstr(pszHost,"/");
|
|
|
|
if (pdata)
|
|
*pdata = 0x00;
|
|
|
|
// get current time & random number
|
|
tmtNow = get_time_from_sntp();
|
|
|
|
|
|
srand((unsigned int)tmtNow);
|
|
nRandom = rand() * rand();
|
|
|
|
ptmNow = gmtime((const time_t *)&tmtNow);
|
|
|
|
tmtNow %= 10000000000; // MAX 10
|
|
nRandom %= 10000000000; // MAX 10
|
|
|
|
// create command struct
|
|
#ifdef WIN32
|
|
sprintf(szMD5, "%010d%010I64d%s%s", tmtNow, nRandom, PRIVATE_KEY, SERVER_NAME);
|
|
#else
|
|
sprintf(szMD5, "%010d%010lld%s%s", (int)tmtNow, nRandom, PRIVATE_KEY, SERVER_NAME);
|
|
#endif
|
|
md5_buffer(szMD5, szVerifyKey);
|
|
|
|
md5_buffer(password, szPassword);
|
|
sprintf(szMD5, "%s@%s%s%d", serviceId, userId, szPassword, (int)tmtNow);
|
|
md5_buffer(szMD5, szPassword);
|
|
|
|
sprintf(szAuth, "%s@%s%c%s%c%d", serviceId, userId, DELIMITER, szPassword, DELIMITER, (int)tmtNow);
|
|
|
|
// Make header
|
|
|
|
#ifdef WIN32
|
|
memset((void *)&cmd, NULL, sizeof(cmd));
|
|
sprintf(cmd.szTranId, "%04d%02d%02d%02d%02d%02d-%.10s-%010d-%010I64d",
|
|
#else
|
|
memset((void *)&cmd, 0, sizeof(cmd));
|
|
sprintf(cmd.szTranId, "%04d%02d%02d%02d%02d%02d-%.10s-%010d-%010lld",
|
|
#endif
|
|
ptmNow->tm_year + 1900, ptmNow->tm_mon+1, ptmNow->tm_mday, ptmNow->tm_hour, ptmNow->tm_min, ptmNow->tm_sec,
|
|
szVerifyKey, (int)tmtNow, nRandom);
|
|
|
|
cmd.nMode = htonl(nCommand);
|
|
strcpy(cmd.szIssuer, SERVER_NAME);
|
|
strcpy(cmd.szServiceId, serviceId);
|
|
cmd.nLength = htonl((u_long)strlen(szAuth) + sendlen);
|
|
|
|
if(sendlen > 0)
|
|
{
|
|
pSendData = malloc(strlen(szAuth) + sendlen);
|
|
memcpy(pSendData, szAuth, strlen(szAuth));
|
|
memcpy(pSendData+strlen(szAuth), sendmsg, sendlen);
|
|
}
|
|
|
|
// create socket
|
|
if (isalpha(pszHost[0])) {
|
|
struct addrinfo *result;
|
|
struct addrinfo hints = {0};
|
|
|
|
hints.ai_socktype = SOCK_STREAM;
|
|
hints.ai_family = PF_UNSPEC;
|
|
|
|
if( getaddrinfo( pszHost, NULL, &hints, &result ) != 0 )
|
|
goto EXIT_FUNCTION;
|
|
|
|
sa.sin_addr.s_addr = ((struct sockaddr_in *)result->ai_addr)->sin_addr.s_addr;
|
|
freeaddrinfo(result);
|
|
}
|
|
else
|
|
sa.sin_addr.s_addr = inet_addr(pszHost);
|
|
|
|
if ((sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) == INVALID_SOCKET)
|
|
goto EXIT_FUNCTION;
|
|
|
|
sa.sin_family = AF_INET;
|
|
sa.sin_port = htons(RCTS_PORT);
|
|
|
|
/* Elenoa MOD : START */
|
|
#ifdef _WIN32
|
|
__nonblock_win32(sock);
|
|
|
|
if (connect(sock, (SOCKADDR*)&sa, sizeof(sa)) == SOCKET_ERROR)
|
|
{
|
|
|
|
if (WSAEWOULDBLOCK == WSAGetLastError())
|
|
{
|
|
fd_set wfd, efd;
|
|
struct timeval tv;
|
|
int result;
|
|
FD_ZERO(&wfd);
|
|
FD_ZERO(&efd);
|
|
FD_SET(sock, &wfd);
|
|
FD_SET(sock, &efd);
|
|
tv.tv_sec = timeout;
|
|
tv.tv_usec = 0;
|
|
result = select(0, 0, &wfd, &efd,&tv);
|
|
if (SOCKET_ERROR == result || 0 == result)
|
|
{
|
|
int nRet = WSAGetLastError();
|
|
goto EXIT_FUNCTION;
|
|
}
|
|
}
|
|
else
|
|
goto EXIT_FUNCTION;
|
|
}
|
|
|
|
#else
|
|
__nonblock(sock);
|
|
{
|
|
int i;
|
|
for (i = 0; i < (timeout * 10); i++) {
|
|
if (connect(sock, (SOCKADDR*)&sa, sizeof(sa)) != SOCKET_ERROR) {
|
|
errno = 0;
|
|
break;
|
|
}
|
|
if (errno == EISCONN)
|
|
break;
|
|
|
|
if (((i + 1) % 10) == 0)
|
|
{
|
|
shutdown(sock, 2);
|
|
close(sock);
|
|
}
|
|
usleep(100000);
|
|
//fprintf(stderr, "%d\n", i);
|
|
}
|
|
|
|
if (errno != EISCONN && errno != 0)
|
|
goto EXIT_FUNCTION;
|
|
}
|
|
#endif
|
|
|
|
// Send packet
|
|
if (_sh_send(sock, (char *)&cmd, sizeof(cmd)) == SOCKET_ERROR)
|
|
goto EXIT_FUNCTION;
|
|
|
|
if (_sh_send(sock, pSendData, strlen(szAuth)+sendlen) == SOCKET_ERROR)
|
|
goto EXIT_FUNCTION;
|
|
|
|
if (_sh_recv(sock, (char*)&cmd, sizeof(cmd)) == SOCKET_ERROR)
|
|
goto EXIT_FUNCTION;
|
|
|
|
cmd.nLength = ntohl(cmd.nLength);
|
|
cmd.nResult = ntohl(cmd.nResult);
|
|
if (cmd.nResult != 0x1000) {
|
|
if (cmd.nResult == 0x3000)
|
|
SetLastError(SHERRNO_UNDEFINED);
|
|
else if (cmd.nResult == 0x3001)
|
|
SetLastError(SHERRNO_AUTHORIZATION);
|
|
else if (cmd.nResult == 0x9000)
|
|
SetLastError(SHERRNO_INTERNAL);
|
|
goto EXIT_FUNCTION;
|
|
}
|
|
|
|
closesocket(sock);
|
|
sock = INVALID_SOCKET;
|
|
ret = 1;
|
|
|
|
EXIT_FUNCTION:
|
|
i = GetLastError();
|
|
|
|
if (pszHost)
|
|
free(pszHost);
|
|
|
|
if(pSendData)
|
|
free(pSendData);
|
|
|
|
if (sock != INVALID_SOCKET)
|
|
closesocket(sock);
|
|
|
|
SetLastError(i);
|
|
return ret;
|
|
}
|
|
|
|
int sh_get_lasterror()
|
|
{
|
|
return GetLastError();
|
|
}
|
|
|
|
void sh_get_error_msg( int code, char* errstr)
|
|
{
|
|
if (code >= SHERRNO_UNDEFINED && code < SHERRNO_INVALIDCACHEFILE) {
|
|
switch (code) {
|
|
case SHERRNO_UNDEFINED:
|
|
strcpy(errstr, "알 수 없는 오류입니다.");
|
|
break;
|
|
case SHERRNO_AUTHORIZATION:
|
|
strcpy(errstr, "인증 실패입니다.");
|
|
break;
|
|
case SHERRNO_INTERNAL:
|
|
strcpy(errstr, "내부 오류 입니다.");
|
|
break;
|
|
case SHERRNO_NOSERVICE:
|
|
strcpy(errstr, "서비스가 존재하지 않습니다.");
|
|
break;
|
|
case SHERRNO_NOCACHEFILE:
|
|
strcpy(errstr, "캐쉬 파일이 없습니다.");
|
|
break;
|
|
case SHERRNO_INVALIDCACHEFILE:
|
|
strcpy(errstr, "올바르지 않는 캐쉬 파일입니다.");
|
|
break;
|
|
}
|
|
}
|
|
else {
|
|
#ifdef WIN32
|
|
char * tmp;
|
|
if (!FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
|
|
NULL, code, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR)&tmp, 0, NULL))
|
|
strcpy(errstr, "알 수 없는 오류입니다.");
|
|
else
|
|
strcpy(errstr, tmp);
|
|
|
|
LocalFree(tmp);
|
|
#else
|
|
strcpy(errstr, strerror(code));
|
|
#endif
|
|
}
|
|
} |