// Load color information from stream, note that PokeMini_OnLoadColorFile callback isn't called! int PokeMini_LoadColorStream(TPokeMini_StreamIO stream, void *stream_ptr) { uint8_t hdr[4], vcod[4], reserved[16]; uint32_t maptiles, mapoffset, bytespertile; int i, readbytes; // Check header DATAREADFROMFILE(hdr, 4); // ID if ((hdr[0] != 'M') || (hdr[1] != 'I') || (hdr[2] != 'N') || (hdr[3] != 'c')) return 0; DATAREADFROMFILE(vcod, 4); // VCode if (vcod[0] != 0x01) return 0; // Only version 1 supported if (vcod[1] > 0x01) return 0; // Only color type 0 and 1 are valid PRCColorFlags = vcod[2]; PokeMini_ColorFormat = vcod[1]; DATAREADFROMFILE(&maptiles, 4); // Number of map tiles maptiles = Endian32(maptiles); DATAREADFROMFILE(&mapoffset, 4); // Map offset in tiles mapoffset = Endian32(mapoffset); DATAREADFROMFILE(reserved, 16); // Reserved area // PM ROM Max is 2MB, that's 256K Map Tiles if (maptiles > 262144) return 0; if (mapoffset > 262144) return 0; if (PokeMini_ColorFormat == 1) bytespertile = 8; else bytespertile = 2; // Free existing color information PokeMini_FreeColorInfo(); PRCColorOffset = 0; PRCColorTop = (uint8_t *)0; // Create and load map PRCColorMap = (uint8_t *)malloc(maptiles * bytespertile); for (i=0; i<maptiles * bytespertile; i++) PRCColorMap[i] = 0x00; readbytes = stream(PRCColorMap, maptiles * bytespertile, stream_ptr); // Setup offset and top PRCColorOffset = mapoffset * bytespertile; PRCColorTop = (uint8_t *)PRCColorMap + (maptiles * bytespertile); // Version 0.4.5 have old color palette, remap colors to the new one if (!(PRCColorFlags & 1)) { for (i=0; i<maptiles * bytespertile; i++) { PRCColorMap[i] = RemapMINC10_11[PRCColorMap[i] & 15] | (PRCColorMap[i] & 0xF0); } } return (readbytes > 0); }
// Generate an ID from GUID UINT Win32EthGenIdFromGuid(char *guid) { char tmp[MAX_SIZE]; UCHAR hash[SHA1_SIZE]; UINT i; // Validate arguments if (guid == NULL) { return 0; } StrCpy(tmp, sizeof(tmp), guid); Trim(tmp); StrUpper(tmp); HashSha1(hash, tmp, StrLen(tmp)); Copy(&i, hash, sizeof(UINT)); i = Endian32(i); if (i == 0) { i = 1; } return i; }
// チェックサム計算 USHORT CalcChecksumForIPv6(IPV6_ADDR *src_ip, IPV6_ADDR *dest_ip, UCHAR protocol, void *data, UINT size) { UCHAR *tmp; UINT tmp_size; IPV6_PSEUDO_HEADER *ph; USHORT ret; // 引数チェック if (data == NULL && size != 0) { return 0; } tmp_size = size + sizeof(IPV6_PSEUDO_HEADER); tmp = ZeroMalloc(tmp_size); ph = (IPV6_PSEUDO_HEADER *)tmp; Copy(&ph->SrcAddress, src_ip, sizeof(IPV6_ADDR)); Copy(&ph->DestAddress, dest_ip, sizeof(IPV6_ADDR)); ph->UpperLayerPacketSize = Endian32(size); ph->NextHeader = protocol; Copy(((UCHAR *)tmp) + sizeof(IPV6_PSEUDO_HEADER), data, size); ret = IpChecksum(tmp, tmp_size); Free(tmp); return ret; }
// An UDP packet has been received void UDPReceivedPacket(CEDAR *cedar, SOCK *s, IP *ip, UINT port, void *data, UINT size) { SESSION *session; UINT *key32; UCHAR *buf; CONNECTION *c; // Validate arguments if (s == NULL || ip == NULL || data == NULL || size == 0 || cedar == NULL) { return; } if (size < 16) { // Ignore since the packet size is not enough return; } buf = (UCHAR *)data; key32 = (UINT *)(buf + 4); // Get the session from the Key32 value session = GetSessionFromUDPEntry(cedar, Endian32(*key32)); if (session == NULL) { Debug("Invalid UDP Session Key 32: 0x%X\n", *key32); return; } c = session->Connection; // Write the data PutUDPPacketData(c, buf, size); // Rewrite the UDP socket associated with the connection Lock(c->lock); { if (c->Protocol == CONNECTION_UDP) { if (c->Udp->s != s) { if (c->Udp->s != NULL) { ReleaseSock(c->Udp->s); } AddRef(s->ref); c->Udp->s = s; } Copy(&c->Udp->ip, ip, sizeof(UINT)); c->Udp->port = port; } } Unlock(c->lock); // Invoke the Cancel Cancel(session->Cancel1); // Release the session ReleaseSession(session); }
// Listener thread void ElListenerProc(THREAD *thread, void *param) { TCP_ACCEPTED_PARAM *data = (TCP_ACCEPTED_PARAM *)param; EL *e; SOCK *s; UCHAR rand[SHA1_SIZE]; UCHAR pass1[SHA1_SIZE], pass2[SHA1_SIZE]; // Validate arguments if (data == NULL || thread == NULL) { return; } e = (EL *)data->r->ThreadParam; s = data->s; AddRef(s->ref); SetTimeout(s, 5000); LockList(e->AdminThreadList); { AddRef(thread->ref); AddRef(s->ref); Insert(e->AdminThreadList, thread); Insert(e->AdminSockList, s); } UnlockList(e->AdminThreadList); NoticeThreadInit(thread); // Submit a challenge Rand(rand, sizeof(rand)); SendAll(s, rand, sizeof(rand), false); // Receive a response SecurePassword(pass1, e->HashedPassword, rand); Zero(pass2, sizeof(pass2)); RecvAll(s, pass2, sizeof(pass2), false); if (Cmp(pass1, pass2, SHA1_SIZE) != 0) { // Password incorrect bool code = false; code = Endian32(code); SendAll(s, &code, sizeof(code), false); } else { // Password match bool code = true; RPC *r; code = Endian32(code); SendAll(s, &code, sizeof(code), false); SetTimeout(s, INFINITE); // Start operation as a RPC server r = StartRpcServer(s, ElRpcServer, e); RpcServer(r); RpcFree(r); } Disconnect(s); ReleaseSock(s); LockList(e->AdminThreadList); { if (Delete(e->AdminThreadList, thread)) { ReleaseThread(thread); } if (Delete(e->AdminSockList, s)) { ReleaseSock(s); } } UnlockList(e->AdminThreadList); }
// RPC client connect UINT EcConnect(char *host, UINT port, char *password, RPC **rpc) { SOCK *s; UCHAR password_hash[SHA1_SIZE]; UCHAR rand[SHA1_SIZE]; UCHAR response[SHA1_SIZE]; bool retcode; // Validate arguments if (host == NULL) { host = "localhost"; } if (port == 0) { port = EL_ADMIN_PORT; } if (password == NULL) { password = ""; } if (rpc == NULL) { return ERR_INTERNAL_ERROR; } // Connect to the server s = Connect(host, port); if (s == NULL) { // Connection failure return ERR_CONNECT_FAILED; } SetTimeout(s, 5000); // Hash the password Hash(password_hash, password, StrLen(password), true); // Receive the random number Zero(rand, sizeof(rand)); RecvAll(s, rand, sizeof(rand), false); SecurePassword(response, password_hash, rand); // Send a response SendAll(s, response, sizeof(response), false); // Receive results retcode = false; if (RecvAll(s, &retcode, sizeof(retcode), false) == false) { // Disconnect ReleaseSock(s); return ERR_PROTOCOL_ERROR; } retcode = Endian32(retcode); if (retcode == false) { // Password incorrect ReleaseSock(s); return ERR_AUTH_FAILED; } // Successful connection SetTimeout(s, INFINITE); *rpc = StartRpcClient(s, NULL); ReleaseSock(s); return ERR_NO_ERROR; }
// Save emulator state int PokeMini_SaveSSFile(const char *statefile, const char *romfile) { FILE *fo; char PMiniStr[256]; uint32_t PMiniID, StatTime, BSize; // Open file fo = fopen(statefile, "wb"); if (fo == NULL) { if (PokeMini_OnSaveStateFile) PokeMini_OnSaveStateFile(statefile, -1); return 0; } // Write content fwrite((void *)"PokeMiniStat", 1, 12, fo); // Write File ID PMiniID = PokeMini_ID; fwrite(&PMiniID, 1, 4, fo); // Write State ID memset(PMiniStr, 0, 128); strcpy(PMiniStr, romfile); fwrite(PMiniStr, 1, 128, fo); // Write ROM related to state StatTime = Endian32((uint32_t)time(NULL)); fwrite(&StatTime, 1, 4, fo); // Write Time // Read State Structure // - RAM fwrite((void *)"RAM-", 1, 4, fo); BSize = Endian32(0x1000); fwrite(&BSize, 1, 4, fo); fwrite(PM_RAM, 1, 0x1000, fo); // - Registers I/O fwrite((void *)"REG-", 1, 4, fo); BSize = Endian32(256); fwrite(&BSize, 1, 4, fo); fwrite(PM_IO, 1, 256, fo); // - CPU Interface fwrite((void *)"CPU-", 1, 4, fo); MinxCPU_SaveState(fo); // - IRQ Interface fwrite((void *)"IRQ-", 1, 4, fo); MinxIRQ_SaveState(fo); // - Timers Interface fwrite((void *)"TMR-", 1, 4, fo); MinxTimers_SaveState(fo); // - Parallel IO Interface fwrite((void *)"PIO-", 1, 4, fo); MinxIO_SaveState(fo); // - PRC Interface fwrite((void *)"PRC-", 1, 4, fo); MinxPRC_SaveState(fo); // - Color PRC Interface fwrite((void *)"CPM-", 1, 4, fo); MinxColorPRC_SaveState(fo); // - LCD Interface fwrite((void *)"LCD-", 1, 4, fo); MinxLCD_SaveState(fo); // - Audio Interface fwrite((void *)"AUD-", 1, 4, fo); MinxAudio_SaveState(fo); // - EOF fwrite((void *)"END-", 1, 4, fo); BSize = Endian32(0); fwrite(&BSize, 1, 4, fo); fclose(fo); // Callback if (PokeMini_OnSaveStateFile) PokeMini_OnSaveStateFile(statefile, 1); return 1; }
// Load emulator state int PokeMini_LoadSSFile(const char *statefile) { FILE *fi; int readbytes; char PMiniStr[128]; uint32_t PMiniID, StatTime, BSize; // Open file fi = fopen(statefile, "rb"); if (fi == NULL) { if (PokeMini_OnLoadStateFile) PokeMini_OnLoadStateFile(statefile, -1); return 0; } // Read content PMiniStr[12] = 0; readbytes = fread(PMiniStr, 1, 12, fi); // Read File ID if ((readbytes != 12) || strcmp(PMiniStr, "PokeMiniStat")) { if (PokeMini_OnLoadStateFile) PokeMini_OnLoadStateFile(statefile, -2); return 0; } readbytes = fread(&PMiniID, 1, 4, fi); // Read State ID PMiniID = Endian32(PMiniID); if ((readbytes != 4) || (PMiniID != PokeMini_ID)) { if (PokeMini_OnLoadStateFile) PokeMini_OnLoadStateFile(statefile, -3); return 0; } readbytes = fread(PMiniStr, 1, 128, fi); // Read ROM related to state (discarded) if (readbytes != 128) { if (PokeMini_OnLoadStateFile) PokeMini_OnLoadStateFile(statefile, -4); return 0; } readbytes = fread(&StatTime, 1, 4, fi); // Read Time StatTime = Endian32(StatTime); if (readbytes != 4) { if (PokeMini_OnLoadStateFile) PokeMini_OnLoadStateFile(statefile, -4); return 0; } // Read State Structure PMiniStr[4] = 0; while (!feof(fi)) { readbytes = fread(PMiniStr, 1, 4, fi); if (readbytes != 4) { if (PokeMini_OnLoadStateFile) PokeMini_OnLoadStateFile(statefile, -5); return 0; } readbytes = fread(&BSize, 1, 4, fi); BSize = Endian32(BSize); if (readbytes != 4) { if (PokeMini_OnLoadStateFile) PokeMini_OnLoadStateFile(statefile, -5); return 0; } if (!strcmp(PMiniStr, "RAM-")) { // RAM readbytes = fread(PM_RAM, 1, 0x1000, fi); if ((BSize != 0x1000) || (readbytes != 0x1000)) { if (PokeMini_OnLoadStateFile) PokeMini_OnLoadStateFile(statefile, -5); return 0; } } else if (!strcmp(PMiniStr, "REG-")) { // Register I/O readbytes = fread(PM_IO, 1, 256, fi); if ((BSize != 256) || (readbytes != 256)) { if (PokeMini_OnLoadStateFile) PokeMini_OnLoadStateFile(statefile, -5); return 0; } } else if (!strcmp(PMiniStr, "CPU-")) { // CPU if (!MinxCPU_LoadState(fi, BSize)) { if (PokeMini_OnLoadStateFile) PokeMini_OnLoadStateFile(statefile, -5); return 0; } } else if (!strcmp(PMiniStr, "IRQ-")) { // IRQ if (!MinxIRQ_LoadState(fi, BSize)) { if (PokeMini_OnLoadStateFile) PokeMini_OnLoadStateFile(statefile, -5); return 0; } } else if (!strcmp(PMiniStr, "TMR-")) { // Timers if (!MinxTimers_LoadState(fi, BSize)) { if (PokeMini_OnLoadStateFile) PokeMini_OnLoadStateFile(statefile, -5); return 0; } } else if (!strcmp(PMiniStr, "PIO-")) { // Parallel IO if (!MinxIO_LoadState(fi, BSize)) { if (PokeMini_OnLoadStateFile) PokeMini_OnLoadStateFile(statefile, -5); return 0; } } else if (!strcmp(PMiniStr, "PRC-")) { // PRC if (!MinxPRC_LoadState(fi, BSize)) { if (PokeMini_OnLoadStateFile) PokeMini_OnLoadStateFile(statefile, -5); return 0; } } else if (!strcmp(PMiniStr, "CPM-")) { // Color PRC if (!MinxColorPRC_LoadState(fi, BSize)) { if (PokeMini_OnLoadStateFile) PokeMini_OnLoadStateFile(statefile, -5); return 0; } } else if (!strcmp(PMiniStr, "LCD-")) { // LCD if (!MinxLCD_LoadState(fi, BSize)) { if (PokeMini_OnLoadStateFile) PokeMini_OnLoadStateFile(statefile, -5); return 0; } } else if (!strcmp(PMiniStr, "LCD-")) { // Audio if (!MinxAudio_LoadState(fi, BSize)) { if (PokeMini_OnLoadStateFile) PokeMini_OnLoadStateFile(statefile, -5); return 0; } } else if (!strcmp(PMiniStr, "END-")) { break; } } fclose(fi); // Update RTC if requested if (CommandLine.updatertc == 1) { MinxTimers.SecTimerCnt += (uint32_t)time(NULL) - StatTime; } // Syncronize with host time PokeMini_SyncHostTime(); // Callback if (PokeMini_OnLoadStateFile) PokeMini_OnLoadStateFile(statefile, 1); return 1; }
// Attempts Radius authentication (with specifying retry interval and multiple server) bool RadiusLogin(CONNECTION *c, char *server, UINT port, UCHAR *secret, UINT secret_size, wchar_t *username, char *password, UINT interval, UCHAR *mschap_v2_server_response_20) { UCHAR random[MD5_SIZE]; UCHAR id; BUF *encrypted_password = NULL; BUF *user_name = NULL; //IP ip; bool ret = false; TOKEN_LIST *token; UINT i; LIST *ip_list; IPC_MSCHAP_V2_AUTHINFO mschap; bool is_mschap; char client_ip_str[MAX_SIZE]; static UINT packet_id = 0; // Validate arguments if (server == NULL || port == 0 || (secret_size != 0 && secret == NULL) || username == NULL || password == NULL) { return false; } Zero(client_ip_str, sizeof(client_ip_str)); if (c != NULL && c->FirstSock != NULL) { IPToStr(client_ip_str, sizeof(client_ip_str), &c->FirstSock->RemoteIP); } // Parse the MS-CHAP v2 authentication data Zero(&mschap, sizeof(mschap)); is_mschap = ParseAndExtractMsChapV2InfoFromPassword(&mschap, password); // Split the server into tokens token = ParseToken(server, " ,;\t"); // Get the IP address of the server ip_list = NewListFast(NULL); for(i = 0; i < token->NumTokens; i++) { IP *tmp_ip = Malloc(sizeof(IP)); if (GetIP(tmp_ip, token->Token[i])) { Add(ip_list, tmp_ip); } else if (GetIPEx(tmp_ip, token->Token[i], true)) { Add(ip_list, tmp_ip); } else { Free(tmp_ip); } } FreeToken(token); if(LIST_NUM(ip_list) == 0) { ReleaseList(ip_list); return false; } // Random number generation Rand(random, sizeof(random)); // ID generation id = (UCHAR)(packet_id % 254 + 1); packet_id++; if (is_mschap == false) { // Encrypt the password encrypted_password = RadiusEncryptPassword(password, random, secret, secret_size); if (encrypted_password == NULL) { // Encryption failure ReleaseList(ip_list); return false; } } // Generate the user name packet user_name = RadiusCreateUserName(username); if (user_name != NULL) { // Generate a password packet BUF *user_password = (is_mschap ? NULL : RadiusCreateUserPassword(encrypted_password->Buf, encrypted_password->Size)); BUF *nas_id = RadiusCreateNasId(CEDAR_SERVER_STR); if (is_mschap || user_password != NULL) { UINT64 start; UINT64 next_send_time; UCHAR tmp[MAX_SIZE]; UINT recv_buf_size = 32768; UCHAR *recv_buf = MallocEx(recv_buf_size, true); // Generate an UDP packet BUF *p = NewBuf(); UCHAR type = 1; SOCK *sock; USHORT sz = 0; UINT pos = 0; BOOL *finish = ZeroMallocEx(sizeof(BOOL) * LIST_NUM(ip_list), true); Zero(tmp, sizeof(tmp)); WriteBuf(p, &type, 1); WriteBuf(p, &id, 1); WriteBuf(p, &sz, 2); WriteBuf(p, random, 16); WriteBuf(p, user_name->Buf, user_name->Size); if (is_mschap == false) { UINT ui; // PAP WriteBuf(p, user_password->Buf, user_password->Size); WriteBuf(p, nas_id->Buf, nas_id->Size); // Service-Type ui = Endian32(2); RadiusAddValue(p, 6, 0, 0, &ui, sizeof(ui)); // NAS-Port-Type ui = Endian32(5); RadiusAddValue(p, 61, 0, 0, &ui, sizeof(ui)); // Tunnel-Type ui = Endian32(1); RadiusAddValue(p, 64, 0, 0, &ui, sizeof(ui)); // Tunnel-Medium-Type ui = Endian32(1); RadiusAddValue(p, 65, 0, 0, &ui, sizeof(ui)); // Calling-Station-Id RadiusAddValue(p, 31, 0, 0, client_ip_str, StrLen(client_ip_str)); // Tunnel-Client-Endpoint RadiusAddValue(p, 66, 0, 0, client_ip_str, StrLen(client_ip_str)); } else { // MS-CHAP v2 static UINT session_id = 0; USHORT us; UINT ui; char *ms_ras_version = "MSRASV5.20"; UCHAR ms_chapv2_response[50]; // Acct-Session-Id us = Endian16(session_id % 254 + 1); session_id++; RadiusAddValue(p, 44, 0, 0, &us, sizeof(us)); // NAS-IP-Address if (c != NULL && c->FirstSock != NULL && c->FirstSock->IPv6 == false) { ui = IPToUINT(&c->FirstSock->LocalIP); RadiusAddValue(p, 4, 0, 0, &ui, sizeof(ui)); } // Service-Type ui = Endian32(2); RadiusAddValue(p, 6, 0, 0, &ui, sizeof(ui)); // MS-RAS-Vendor ui = Endian32(311); RadiusAddValue(p, 26, 311, 9, &ui, sizeof(ui)); // MS-RAS-Version RadiusAddValue(p, 26, 311, 18, ms_ras_version, StrLen(ms_ras_version)); // NAS-Port-Type ui = Endian32(5); RadiusAddValue(p, 61, 0, 0, &ui, sizeof(ui)); // Tunnel-Type ui = Endian32(1); RadiusAddValue(p, 64, 0, 0, &ui, sizeof(ui)); // Tunnel-Medium-Type ui = Endian32(1); RadiusAddValue(p, 65, 0, 0, &ui, sizeof(ui)); // Calling-Station-Id RadiusAddValue(p, 31, 0, 0, client_ip_str, StrLen(client_ip_str)); // Tunnel-Client-Endpoint RadiusAddValue(p, 66, 0, 0, client_ip_str, StrLen(client_ip_str)); // MS-RAS-Client-Version RadiusAddValue(p, 26, 311, 35, ms_ras_version, StrLen(ms_ras_version)); // MS-RAS-Client-Name RadiusAddValue(p, 26, 311, 34, client_ip_str, StrLen(client_ip_str)); // MS-CHAP-Challenge RadiusAddValue(p, 26, 311, 11, mschap.MsChapV2_ServerChallenge, sizeof(mschap.MsChapV2_ServerChallenge)); // MS-CHAP2-Response Zero(ms_chapv2_response, sizeof(ms_chapv2_response)); Copy(ms_chapv2_response + 2, mschap.MsChapV2_ClientChallenge, 16); Copy(ms_chapv2_response + 2 + 16 + 8, mschap.MsChapV2_ClientResponse, 24); RadiusAddValue(p, 26, 311, 25, ms_chapv2_response, sizeof(ms_chapv2_response)); // NAS-ID WriteBuf(p, nas_id->Buf, nas_id->Size); } SeekBuf(p, 0, 0); WRITE_USHORT(((UCHAR *)p->Buf) + 2, (USHORT)p->Size); // Create a socket sock = NewUDPEx(0, IsIP6(LIST_DATA(ip_list, pos))); // Transmission process start start = Tick64(); if(interval < RADIUS_RETRY_INTERVAL) { interval = RADIUS_RETRY_INTERVAL; } else if(interval > RADIUS_RETRY_TIMEOUT) { interval = RADIUS_RETRY_TIMEOUT; } next_send_time = start + (UINT64)interval; while (true) { UINT server_port; UINT recv_size; //IP server_ip; SOCKSET set; UINT64 now; SEND_RETRY: //SendTo(sock, &ip, port, p->Buf, p->Size); SendTo(sock, LIST_DATA(ip_list, pos), port, p->Buf, p->Size); Debug("send to host:%u\n", pos); next_send_time = Tick64() + (UINT64)interval; RECV_RETRY: now = Tick64(); if (next_send_time <= now) { // Switch the host to refer pos++; pos = pos % LIST_NUM(ip_list); goto SEND_RETRY; } if ((start + RADIUS_RETRY_TIMEOUT) < now) { // Time-out break; } InitSockSet(&set); AddSockSet(&set, sock); Select(&set, (UINT)(next_send_time - now), NULL, NULL); recv_size = RecvFrom(sock, LIST_DATA(ip_list, pos), &server_port, recv_buf, recv_buf_size); if (recv_size == 0) { Debug("Radius recv_size 0\n"); finish[pos] = TRUE; for(i = 0; i < LIST_NUM(ip_list); i++) { if(finish[i] == FALSE) { // Switch the host to refer pos++; pos = pos % LIST_NUM(ip_list); goto SEND_RETRY; } } // Failure break; } else if (recv_size == SOCK_LATER) { // Waiting goto RECV_RETRY; } else { // Check such as the IP address if (/*Cmp(&server_ip, &ip, sizeof(IP)) != 0 || */server_port != port) { goto RECV_RETRY; } // Success if (recv_buf[0] == 2) { ret = true; if (is_mschap && mschap_v2_server_response_20 != NULL) { // Cutting corners Zurukko UCHAR signature[] = {0x1A, 0x33, 0x00, 0x00, 0x01, 0x37, 0x1A, 0x2D, 0x00, 0x53, 0x3D, }; UINT i = SearchBin(recv_buf, 0, recv_buf_size, signature, sizeof(signature)); if (i == INFINITE || ((i + sizeof(signature) + 40) > recv_buf_size)) { ret = false; } else { char tmp[MAX_SIZE]; BUF *b; Zero(tmp, sizeof(tmp)); Copy(tmp, recv_buf + i + sizeof(signature), 40); b = StrToBin(tmp); if (b != NULL && b->Size == 20) { WHERE; Copy(mschap_v2_server_response_20, b->Buf, 20); } else { WHERE; ret = false; } FreeBuf(b); } } } break; } } Free(finish); // Release the socket ReleaseSock(sock); FreeBuf(p); FreeBuf(user_password); Free(recv_buf); } FreeBuf(nas_id); FreeBuf(user_name); } // Release the ip_list for(i = 0; i < LIST_NUM(ip_list); i++) { IP *tmp_ip = LIST_DATA(ip_list, i); Free(tmp_ip); } ReleaseList(ip_list); // Release the memory FreeBuf(encrypted_password); return ret; }
// RPC internal call PACK *RpcCallInternal(RPC *r, PACK *p) { BUF *b; UINT size; PACK *ret; void *tmp; // Validate arguments if (r == NULL || p == NULL) { return NULL; } if (r->Sock == NULL) { return NULL; } b = PackToBuf(p); size = Endian32(b->Size); SendAdd(r->Sock, &size, sizeof(UINT)); SendAdd(r->Sock, b->Buf, b->Size); FreeBuf(b); if (SendNow(r->Sock, r->Sock->SecureMode) == false) { return NULL; } if (RecvAll(r->Sock, &size, sizeof(UINT), r->Sock->SecureMode) == false) { return NULL; } size = Endian32(size); if (size > MAX_PACK_SIZE) { return NULL; } tmp = MallocEx(size, true); if (RecvAll(r->Sock, tmp, size, r->Sock->SecureMode) == false) { Free(tmp); return NULL; } b = NewBuf(); WriteBuf(b, tmp, size); SeekBuf(b, 0, 0); Free(tmp); ret = BufToPack(b); if (ret == NULL) { FreeBuf(b); return NULL; } FreeBuf(b); return ret; }
// Wait for the next RPC call bool RpcRecvNextCall(RPC *r) { UINT size; void *tmp; SOCK *s; BUF *b; PACK *p; PACK *ret; // Validate arguments if (r == NULL) { return false; } s = r->Sock; if (RecvAll(s, &size, sizeof(UINT), s->SecureMode) == false) { return false; } size = Endian32(size); if (size > MAX_PACK_SIZE) { return false; } tmp = MallocEx(size, true); if (RecvAll(s, tmp, size, s->SecureMode) == false) { Free(tmp); return false; } b = NewBuf(); WriteBuf(b, tmp, size); SeekBuf(b, 0, 0); Free(tmp); p = BufToPack(b); FreeBuf(b); if (p == NULL) { return false; } ret = CallRpcDispatcher(r, p); FreePack(p); if (ret == NULL) { ret = PackError(ERR_NOT_SUPPORTED); } b = PackToBuf(ret); FreePack(ret); size = Endian32(b->Size); SendAdd(s, &size, sizeof(UINT)); SendAdd(s, b->Buf, b->Size); if (SendNow(s, s->SecureMode) == false) { FreeBuf(b); return false; } FreeBuf(b); return true; }
// Send void UdpAccelSend(UDP_ACCEL *a, UCHAR *data, UINT data_size, bool compressed, UINT max_size, bool high_priority) { UCHAR tmp[UDP_ACCELERATION_TMP_BUF_SIZE]; UCHAR *buf; UINT size; UCHAR key[UDP_ACCELERATION_PACKET_KEY_SIZE]; UINT64 ui64; USHORT us; UCHAR c; UINT current_size; UINT ui32; bool fatal_error = false; UINT r; // Validate arguments if (a == NULL || (data_size != 0 && data == NULL)) { return; } if (max_size == 0) { max_size = INFINITE; } buf = tmp; size = 0; // IV if (a->PlainTextMode == false) { // IV Copy(buf, a->NextIv, UDP_ACCELERATION_PACKET_IV_SIZE); buf += UDP_ACCELERATION_PACKET_IV_SIZE; size += UDP_ACCELERATION_PACKET_IV_SIZE; // Calculate the key UdpAccelCalcKey(key, a->MyKey, a->NextIv); if (false) { char tmp1[256]; char tmp2[256]; char tmp3[256]; BinToStr(tmp1, sizeof(tmp1), a->MyKey, sizeof(a->MyKey)); BinToStr(tmp2, sizeof(tmp2), a->NextIv, UDP_ACCELERATION_PACKET_IV_SIZE); BinToStr(tmp3, sizeof(tmp3), key, sizeof(key)); Debug("My Key : %s\n" "IV : %s\n" "Comm Key: %s\n", tmp1, tmp2, tmp3); } } // Cookie ui32 = Endian32(a->YourCookie); Copy(buf, &ui32, sizeof(UINT)); buf += sizeof(UINT); size += sizeof(UINT); // My Tick ui64 = Endian64(a->Now == 0 ? 1ULL : a->Now); Copy(buf, &ui64, sizeof(UINT64)); buf += sizeof(UINT64); size += sizeof(UINT64); // Your Tick ui64 = Endian64(a->LastRecvYourTick); Copy(buf, &ui64, sizeof(UINT64)); buf += sizeof(UINT64); size += sizeof(UINT64); // Size us = Endian16(data_size); Copy(buf, &us, sizeof(USHORT)); buf += sizeof(USHORT); size += sizeof(USHORT); // Compress Flag c = (compressed ? 1 : 0); Copy(buf, &c, sizeof(UCHAR)); buf += sizeof(UCHAR); size += sizeof(UCHAR); // Data if (data_size >= 1) { Copy(buf, data, data_size); buf += data_size; size += data_size; } if (a->PlainTextMode == false) { static UCHAR zero[UDP_ACCELERATION_PACKET_IV_SIZE] = {0}; CRYPT *c; current_size = UDP_ACCELERATION_PACKET_IV_SIZE + sizeof(UINT) + sizeof(UINT64) * 2 + sizeof(USHORT) + sizeof(UCHAR) + data_size + UDP_ACCELERATION_PACKET_IV_SIZE; if (current_size < max_size) { // Padding UCHAR pad[UDP_ACCELERATION_MAX_PADDING_SIZE]; UINT pad_size = MIN(max_size - current_size, UDP_ACCELERATION_MAX_PADDING_SIZE); pad_size = rand() % pad_size; Zero(pad, sizeof(pad)); Copy(buf, pad, pad_size); buf += pad_size; size += pad_size; } // Verify Copy(buf, zero, UDP_ACCELERATION_PACKET_IV_SIZE); buf += UDP_ACCELERATION_PACKET_IV_SIZE; size += UDP_ACCELERATION_PACKET_IV_SIZE; // Encryption c = NewCrypt(key, UDP_ACCELERATION_PACKET_KEY_SIZE); Encrypt(c, tmp + UDP_ACCELERATION_PACKET_IV_SIZE, tmp + UDP_ACCELERATION_PACKET_IV_SIZE, size - UDP_ACCELERATION_PACKET_IV_SIZE); FreeCrypt(c); // Next Iv Copy(a->NextIv, buf - UDP_ACCELERATION_PACKET_IV_SIZE, UDP_ACCELERATION_PACKET_IV_SIZE); } // Send SetSockHighPriority(a->UdpSock, high_priority); r = SendTo(a->UdpSock, &a->YourIp, a->YourPort, tmp, size); if (r == 0 && a->UdpSock->IgnoreSendErr == false) { fatal_error = true; Debug("Error: SendTo: %r %u %u\n", &a->YourIp, a->YourPort, size); WHERE; } if (data_size == 0) { if (UdpAccelIsSendReady(a, true) == false) { if ((a->YourPortByNatTServer != 0) && (a->YourPort != a->YourPortByNatTServer)) { r = SendTo(a->UdpSock, &a->YourIp, a->YourPortByNatTServer, tmp, size); if (r == 0 && a->UdpSock->IgnoreSendErr == false) { fatal_error = true; WHERE; } } } } if (data_size == 0) { if (IsZeroIP(&a->YourIp2) == false && CmpIpAddr(&a->YourIp, &a->YourIp2) != 0) { if (UdpAccelIsSendReady(a, true) == false) { // When the KeepAlive, if the opponent may be behind a NAT, // send the packet to the IP address of outside of the NAT r = SendTo(a->UdpSock, &a->YourIp2, a->YourPort, tmp, size); if (r == 0 && a->UdpSock->IgnoreSendErr == false) { fatal_error = true; WHERE; } if ((a->YourPortByNatTServer != 0) && (a->YourPort != a->YourPortByNatTServer)) { r = SendTo(a->UdpSock, &a->YourIp2, a->YourPortByNatTServer, tmp, size); if (r == 0 && a->UdpSock->IgnoreSendErr == false) { fatal_error = true; WHERE; } } } } } if (fatal_error) { a->FatalError = true; WHERE; } //Debug("UDP Send: %u\n", size); }
void NmEditVhOptionUpdate(HWND hWnd, SM_HUB *r) { VH_OPTION t; bool ok = true; // Validate arguments if (hWnd == NULL || r == NULL) { return; } NmEditVhOptionFormToVH(hWnd, &t); if (IsZero(t.MacAddress, 6)) { ok = false; } if (IPToUINT(&t.Ip) == 0 || IPToUINT(&t.Mask) == 0) { ok = false; } if (IpIsFilled(hWnd, E_IP) == false || IpIsFilled(hWnd, E_MASK) == false) { ok = false; } if (IsHostIPAddress4(&t.Ip) == false || IsSubnetMask4(&t.Mask) == false) { ok = false; } if (t.UseNat) { if (t.Mtu < 64 || t.Mtu > 1500) { ok = false; } if (t.NatTcpTimeout < (NAT_TCP_MIN_TIMEOUT / 1000) || t.NatTcpTimeout > (NAT_TCP_MAX_TIMEOUT / 1000)) { ok = false; } if (t.NatUdpTimeout < (NAT_UDP_MIN_TIMEOUT / 1000) || t.NatUdpTimeout > (NAT_UDP_MAX_TIMEOUT / 1000)) { ok = false; } } if (t.UseDhcp) { if (IpIsFilled(hWnd, E_DHCP_START) == false || IpIsFilled(hWnd, E_DHCP_END) == false || IpIsFilled(hWnd, E_DHCP_MASK) == false) { ok = false; } if (IpGetFilledNum(hWnd, E_GATEWAY) != 0 && IpGetFilledNum(hWnd, E_GATEWAY) != 4) { ok = false; } if (IpGetFilledNum(hWnd, E_DNS) != 0 && IpGetFilledNum(hWnd, E_DNS) != 4) { ok = false; } if (IpGetFilledNum(hWnd, E_DNS2) != 0 && IpGetFilledNum(hWnd, E_DNS2) != 4) { ok = false; } if (IPToUINT(&t.DhcpLeaseIPStart) == 0 || IPToUINT(&t.DhcpLeaseIPEnd) == 0 || IPToUINT(&t.DhcpSubnetMask) == 0) { ok = false; } if (t.DhcpExpireTimeSpan < 15) { ok = false; } if (Endian32(IPToUINT(&t.DhcpLeaseIPStart)) > Endian32(IPToUINT(&t.DhcpLeaseIPEnd))) { ok = false; } if (IsHostIPAddress4(&t.DhcpLeaseIPStart) == false || IsHostIPAddress4(&t.DhcpLeaseIPEnd) == false) { ok = false; } if (IsSubnetMask4(&t.DhcpSubnetMask) == false) { ok = false; } } SetEnable(hWnd, E_MTU, t.UseNat); SetEnable(hWnd, E_TCP, t.UseNat); SetEnable(hWnd, E_UDP, t.UseNat); SetEnable(hWnd, E_DHCP_START, t.UseDhcp); SetEnable(hWnd, E_DHCP_END, t.UseDhcp); SetEnable(hWnd, E_DHCP_MASK, t.UseDhcp); SetEnable(hWnd, E_EXPIRES, t.UseDhcp); SetEnable(hWnd, E_GATEWAY, t.UseDhcp); SetEnable(hWnd, E_DNS, t.UseDhcp); SetEnable(hWnd, E_DNS2, t.UseDhcp); SetEnable(hWnd, E_DOMAIN, t.UseDhcp); SetEnable(hWnd, IDOK, ok); }