#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 #include #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 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); // ij½¬ÆÄÀÏ¿¡ ±â·Ï 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); // ij½¬ÆÄÀÏ¿¡ ±â·Ï 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, "ij½¬ ÆÄÀÏÀÌ ¾ø½À´Ï´Ù."); break; case SHERRNO_INVALIDCACHEFILE: strcpy(errstr, "¿Ã¹Ù¸£Áö ¾Ê´Â ij½¬ ÆÄÀÏÀÔ´Ï´Ù."); 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 } }