// Create a new key void DCGenNewKey(UCHAR *key) { BUF *b; UINT64 tick; UCHAR hash[SHA1_SIZE]; UCHAR rand[SHA1_SIZE]; UINT i; // Validate arguments if (key == NULL) { return; } b = NewBuf(); Rand(rand, sizeof(rand)); WriteBuf(b, rand, sizeof(rand)); tick = TickHighres64(); WriteBufInt64(b, tick); tick = Tick64(); WriteBufInt64(b, tick); tick = SystemTime64(); WriteBufInt64(b, tick); GetCurrentMachineIpProcessHash(hash); WriteBuf(b, hash, sizeof(hash)); HashSha1(key, b->Buf, b->Size); Rand(rand, sizeof(rand)); for (i = 0;i < SHA1_SIZE;i++) { key[i] = key[i] ^ rand[i]; } FreeBuf(b); }
// Update pathlist void env_update_pathlist() { // Path list use allowed? if (environment->env->env_flags&ENVF_USE_PATHLIST) { APTR file; char *path; //short num; // Build environment variables //for (num=0,path="env:dopus/paths";num<2;num++,path="envarc:dopus/paths") path="env:dopus/paths"; { if ((file=OpenBuf(path,MODE_NEWFILE,4096))) { struct MinNode *node; if (IsListEmpty((struct List *)&environment->path_list.mlh_Head)) WriteBuf(file,"c:\n",3); else for (node=environment->path_list.mlh_Head;node->mln_Succ;node=node->mln_Succ) { WriteBuf(file,(char *)(node+1),-1); WriteBuf(file,"\n",1); } CloseBuf(file); } } } // Remove environment variable else { DeleteFile("env:dopus/paths"); //DeleteFile("envarc:dopus/paths"); } // Update library path list UpdatePathList(); }
// Write introduction void write_theme_intro(APTR file,char *filename) { char buf[400]; lsprintf(buf, "/* D5THEME\n\n" " %s\n\n" " Directory Opus Magellan II Theme File\n" "*/\n\n", (IPTR)FilePart(filename)); WriteBuf(file,buf,-1); // Bit that gets the ARexx port WriteBuf(file, "parse arg dopus_port apply_flags\n" "if dopus_port='' then\n" "\tdopus_port='DOPUS.1'\n" "address value dopus_port\n\n", -1); WriteBuf(file, "if apply_flags='' then\n" "\tapply_flags='PFBS'\n" "else\n" "\tapply_flags=upper(apply_flags)\n\n", -1); // Set results and failat WriteBuf(file, "options results\n" "options failat 21\n\n", -1); }
// Generate an ID attribute of Nas BUF *RadiusCreateNasId(char *name) { BUF *b; UCHAR code, size; // Validate arguments if (name == NULL) { return NULL; } if (StrLen(name) == 0 || StrLen(name) >= 128) { return NULL; } b = NewBuf(); code = 32; size = 2 + (UCHAR)StrLen(name); WriteBuf(b, &code, 1); WriteBuf(b, &size, 1); WriteBuf(b, name, StrLen(name)); return b; }
// Convert a hexadecimal string to a binary data BUF *StrToBin(char *str) { BUF *b; UINT len, i; char tmp[3]; // Validate arguments if (str == NULL) { return NULL; } len = StrLen(str); tmp[0] = 0; b = NewBuf(); for (i = 0;i < len;i++) { char c = str[i]; c = ToUpper(c); if (('0' <= c && c <= '9') || ('A' <= c && c <= 'F')) { if (tmp[0] == 0) { tmp[0] = c; tmp[1] = 0; } else if (tmp[1] == 0) { UCHAR data; char tmp2[64]; tmp[1] = c; tmp[2] = 0; StrCpy(tmp2, sizeof(tmp2), "0x"); StrCat(tmp2, sizeof(tmp2), tmp); data = (UCHAR)strtoul(tmp2, NULL, 0); WriteBuf(b, &data, 1); Zero(tmp, sizeof(tmp)); } } else if (c == ' ' || c == ',' || c == '-' || c == ':') { // Do Nothing } else { break; } } return b; }
// Create a user name attribute for Radius BUF *RadiusCreateUserName(wchar_t *username) { BUF *b; UCHAR code, size; UCHAR utf8[254]; // Validate arguments if (username == NULL) { return NULL; } // Convert the user name to a Unicode string UniToStr(utf8, sizeof(utf8), username); utf8[253] = 0; b = NewBuf(); code = 1; size = 2 + (UCHAR)StrLen(utf8); WriteBuf(b, &code, 1); WriteBuf(b, &size, 1); WriteBuf(b, utf8, StrLen(utf8)); return b; }
/** * @file DWORD WINAPI DebugComRecThread(LPVOID lpParam) * @brief 调试串口接收线程 * @param lpParam [in] * @retval TRUE */ DWORD WINAPI DebugComRecThread(LPVOID lpParam) { UCHAR byGetData[64]; DWORD dwGetDataLenght = 32; DWORD dwReadNumber = 0; CString m_CStr = _T(""); CVct6VsDlg *pDlg = (CVct6VsDlg *)lpParam; hDebugComRecThreadEnd = CreateEvent(NULL, FALSE, FALSE, NULL); bDebugComRecThreadFlag = TRUE; while(bDebugComRecThreadFlag) { if(cDebugCom.hCom != INVALID_HANDLE_VALUE) { /*! 读串口 */ if(cDebugCom.ComReadDate(cDebugCom.hCom, byGetData, dwGetDataLenght, &dwReadNumber, 0)) { ulDebugComRecCnt += dwReadNumber; /*!< 接收计数 */ CString strcnt; strcnt.Format(_T("%ld"), ulDebugComRecCnt); pDlg->m_DebugComRecCnt.SetWindowText(strcnt); /*! 将接收到的数据写入缓冲区 */ #if 0 for(UCHAR i=0; i<dwReadNumber; i++) { WriteBuf(byGetData[i]); } #endif /*! 串口16进制显示 */ byGetData[dwReadNumber] = '\0'; #if 0 UCHAR aucHexStr[256] = {'\0'}; StringToHex(aucHexStr, byGetData, dwReadNumber); m_CStr = aucHexStr; #endif m_CStr = byGetData; int len = pDlg->m_DisDebugComRec.GetWindowTextLength(); pDlg->m_DisDebugComRec.SetSel(len, len); /*!< 将插入光标放在最后 */ pDlg->m_DisDebugComRec.ReplaceSel(m_CStr); pDlg->m_DisDebugComRec.ScrollWindow(0, 0);/*!< 滚动到插入点 */ } } Sleep(1); } /*! 接收进程结束 */ SetEvent(hDebugComRecThreadEnd); return TRUE; }
// Generate the packet BUF *WpcGeneratePacket(PACK *pack, X *cert, K *key) { UCHAR hash[SHA1_SIZE]; BUF *pack_data; BUF *cert_data = NULL; BUF *sign_data = NULL; BUF *b; // Validate arguments if (pack == NULL) { return NULL; } pack_data = PackToBuf(pack); HashSha1(hash, pack_data->Buf, pack_data->Size); if (cert != NULL && key != NULL) { UCHAR sign[128]; cert_data = XToBuf(cert, false); RsaSign(sign, hash, sizeof(hash), key); sign_data = NewBuf(); WriteBuf(sign_data, sign, sizeof(sign)); SeekBuf(sign_data, 0, 0); } b = NewBuf(); WpcAddDataEntryBin(b, "PACK", pack_data->Buf, pack_data->Size); WpcAddDataEntryBin(b, "HASH", hash, sizeof(hash)); if (cert_data != NULL) { WpcAddDataEntryBin(b, "CERT", cert_data->Buf, cert_data->Size); WpcAddDataEntryBin(b, "SIGN", sign_data->Buf, sign_data->Size); } FreeBuf(pack_data); FreeBuf(cert_data); FreeBuf(sign_data); SeekBuf(b, 0, 0); return b; }
// Extract the resource from the EXE file BUF *ViExtractResource(char *exe, char *type, char *name) { HINSTANCE h; HRSRC hr; HGLOBAL hg; UINT size; void *data; BUF *buf; // Validate arguments if (exe == NULL || type == NULL || name == NULL) { return NULL; } h = LoadLibraryExA(exe, NULL, LOAD_LIBRARY_AS_DATAFILE); if (h == NULL) { return NULL; } hr = FindResourceA(h, name, type); if (hr == NULL) { FreeLibrary(h); return NULL; } hg = LoadResource(h, hr); if (hg == NULL) { FreeLibrary(h); return NULL; } size = SizeofResource(h, hr); data = (void *)LockResource(hg); buf = NewBuf(); WriteBuf(buf, data, size); FreeResource(hg); FreeLibrary(h); SeekBuf(buf, 0, 0); return buf; }
// Save palette BOOL save_theme_palette(APTR file,DOpusCallbackInfo *info,struct MsgPort *reply_port) { char buf[300],buf2[260]; // Get settings DC_CALL5(info, dc_RexxCommand, DC_REGA0, "dopus query palette", DC_REGA1, buf2, DC_REGD0, sizeof(buf2), DC_REGA2, reply_port, DC_REGD1, 0); //DC_RexxCommand(info,"dopus query palette",buf2,sizeof(buf2),reply_port,0); //info->dc_RexxCommand("dopus query palette",buf2,sizeof(buf2),reply_port,0); // Write command to rexx script lsprintf(buf,"\tdopus set palette %s\n",(IPTR)buf2); WriteBuf(file,buf,-1); return 1; }
unsigned char NRF24L01_Check(void) { unsigned char buf[5]; unsigned char i; for(i = 0; i < 5; i++) { buf[i] = 0xA5; } WriteBuf(CMD_W_REGISTER | REG_TX_ADDR, buf, 5); ReadBuf(REG_TX_ADDR, buf, 5); for(i = 0; i < 5; i++) { if(buf[i] != 0xA5) return 0; } return 1; }
// Save pens setting BOOL save_theme_pens(APTR file,DOpusCallbackInfo *info,char *type,struct MsgPort *reply_port) { char buf[150],buf2[100]; // Get settings lsprintf(buf,"dopus query pens %s",(IPTR)type); DC_CALL5(info, dc_RexxCommand, DC_REGA0, buf, DC_REGA1, buf2, DC_REGD0, sizeof(buf2), DC_REGA2, reply_port, DC_REGD1, 0); //DC_RexxCommand(info,buf,buf2,sizeof(buf2),reply_port,0); //info->dc_RexxCommand(buf,buf2,sizeof(buf2),reply_port,0); // Write command to rexx script lsprintf(buf,"\tdopus set pens %s %s\n",(IPTR)type,(IPTR)buf2); WriteBuf(file,buf,-1); return 1; }
// Get the byte[] type as a BUF BUF *CfgGetBuf(FOLDER *f, char *name) { ITEM *t; BUF *b; // Validate arguments if (f == NULL || name == NULL) { return NULL; } t = CfgFindItem(f, name); if (t == NULL) { return NULL; } b = NewBuf(); WriteBuf(b, t->Buf, t->size); SeekBuf(b, 0, 0); return b; }
// ICMPv6 近隣要請パケットのビルド BUF *BuildICMPv6NeighborSoliciation(IPV6_ADDR *src_ip, IPV6_ADDR *target_ip, UCHAR *my_mac_address, UINT id) { ICMPV6_OPTION_LIST opt; ICMPV6_OPTION_LINK_LAYER link; ICMPV6_NEIGHBOR_SOLICIATION_HEADER header; BUF *b; BUF *b2; BUF *ret; // 引数チェック if (src_ip == NULL || target_ip == NULL || my_mac_address == NULL) { return NULL; } Zero(&link, sizeof(link)); Copy(link.Address, my_mac_address, 6); Zero(&opt, sizeof(opt)); opt.SourceLinkLayer = &link; b = BuildICMPv6Options(&opt); Zero(&header, sizeof(header)); Copy(&header.TargetAddress, target_ip, sizeof(IPV6_ADDR)); b2 = NewBuf(); WriteBuf(b2, &header, sizeof(header)); WriteBufBuf(b2, b); ret = BuildICMPv6(src_ip, target_ip, 255, ICMPV6_TYPE_NEIGHBOR_SOLICIATION, 0, b2->Buf, b2->Size, id); FreeBuf(b); FreeBuf(b2); return ret; }
BUF *CfgFolderToBufTextEx(FOLDER *f, bool no_banner) { BUF *b; // Validate arguments if (f == NULL) { return NULL; } // Create a stream b = NewBuf(); // Copyright notice if (no_banner == false) { WriteBuf(b, TAG_CPYRIGHT, StrLen(TAG_CPYRIGHT)); } // Output the root folder (recursive) CfgOutputFolderText(b, f, 0); return b; }
// Generate a set of dummy IP addresses and mark void GenerateDummyIpAndMark(void *hash_seed, IPTABLES_ENTRY *e, UINT id) { PRAND *p; BUF *b; if (hash_seed == NULL || e == NULL) { return; } b = NewBuf(); WriteBufInt(b, id); WriteBuf(b, hash_seed, SHA1_SIZE); WriteBufStr(b, "20151002"); p = NewPRand(b->Buf, b->Size); FreeBuf(b); GenerateDummyIp(p, &e->DummySrcIp); GenerateDummyIp(p, &e->DummyDestIP); e->DummyMark = GenerateDummyMark(p); FreePRand(p); }
// ICMPv6 パケットのオプション値のビルド void BuildICMPv6OptionValue(BUF *b, UCHAR type, void *header_pointer, UINT total_size) { UINT packet_size; UCHAR *packet; ICMPV6_OPTION *opt; // 引数チェック if (b == NULL || header_pointer == NULL) { return; } packet_size = ((total_size + 7) / 8) * 8; packet = ZeroMalloc(packet_size); Copy(packet, header_pointer, total_size); opt = (ICMPV6_OPTION *)packet; opt->Length = (UCHAR)(packet_size / 8); opt->Type = type; WriteBuf(b, packet, packet_size); Free(packet); }
// Decode the buffer from WPC_ENTRY BUF *WpcDataEntryToBuf(WPC_ENTRY *e) { void *data; UINT data_size; UINT size; BUF *b; // Validate arguments if (e == NULL) { return NULL; } data_size = e->Size + 4096; data = Malloc(data_size); size = DecodeSafe64(data, e->Data, e->Size); b = NewBuf(); WriteBuf(b, data, size); SeekBuf(b, 0, 0); Free(data); return b; }
/** * Writes a null-terminated string to the stream. */ void IDataStream::WriteString(const char * buf) { WriteBuf(buf, std::strlen(buf) + 1); }
// Output the folder contents (Recursive, binary) void CfgOutputFolderBin(BUF *b, FOLDER *f) { UINT i; // Validate arguments if (b == NULL || f == NULL) { return; } // Folder name WriteBufStr(b, f->Name); // The number of the subfolder WriteBufInt(b, LIST_NUM(f->Folders)); // Subfolder for (i = 0;i < LIST_NUM(f->Folders);i++) { FOLDER *sub = LIST_DATA(f->Folders, i); CfgOutputFolderBin(b, sub); if ((i % 100) == 99) { YieldCpu(); } } // The number of Items WriteBufInt(b, LIST_NUM(f->Items)); // Item for (i = 0;i < LIST_NUM(f->Items);i++) { char *utf8; UINT utf8_size; ITEM *t = LIST_DATA(f->Items, i); // Item Name WriteBufStr(b, t->Name); // Type WriteBufInt(b, t->Type); switch (t->Type) { case ITEM_TYPE_INT: // Integer WriteBufInt(b, *((UINT *)t->Buf)); break; case ITEM_TYPE_INT64: // 64-bit integer WriteBufInt64(b, *((UINT64 *)t->Buf)); break; case ITEM_TYPE_BYTE: // Data size WriteBufInt(b, t->size); // Data WriteBuf(b, t->Buf, t->size); break; case ITEM_TYPE_STRING: // String utf8_size = CalcUniToUtf8((wchar_t *)t->Buf) + 1; utf8 = ZeroMalloc(utf8_size); UniToUtf8(utf8, utf8_size, (wchar_t *)t->Buf); WriteBufInt(b, StrLen(utf8)); WriteBuf(b, utf8, StrLen(utf8)); Free(utf8); break; case ITEM_TYPE_BOOL: // Boolean type if (*((bool *)t->Buf) == false) { WriteBufInt(b, 0); } else { WriteBufInt(b, 1); } break; } } }
// Encrypt the password for the Radius BUF *RadiusEncryptPassword(char *password, UCHAR *random, UCHAR *secret, UINT secret_size) { UINT n, i; BUF *buf; UCHAR c[16][16]; // Result UCHAR b[16][16]; // Result UCHAR p[16][16]; // Password // Validate arguments if (password == NULL || random == NULL || (secret_size != 0 && secret == NULL)) { return NULL; } if (StrLen(password) > 256) { // Password is too long return NULL; } // Initialize Zero(c, sizeof(c)); Zero(p, sizeof(p)); Zero(b, sizeof(b)); // Divide the password per 16 characters Copy(p, password, StrLen(password)); // Calculate the number of blocks n = StrLen(password) / 16; if ((StrLen(password) % 16) != 0) { n++; } // Encryption processing for (i = 0;i < n;i++) { // Calculation of b[i] UINT j; BUF *tmp = NewBuf(); WriteBuf(tmp, secret, secret_size); if (i == 0) { WriteBuf(tmp, random, 16); } else { WriteBuf(tmp, c[i - 1], 16); } Hash(b[i], tmp->Buf, tmp->Size, false); FreeBuf(tmp); // Calculation of c[i] for (j = 0;j < 16;j++) { c[i][j] = p[i][j] ^ b[i][j]; } } // Return the results buf = NewBuf(); WriteBuf(buf, c, n * 16); return buf; }
// Creating a new local console CONSOLE *NewLocalConsole(wchar_t *infile, wchar_t *outfile) { IO *in_io = NULL, *out_io = NULL; CONSOLE *c = ZeroMalloc(sizeof(CONSOLE)); LOCAL_CONSOLE_PARAM *p; UINT old_size = 0; #ifdef OS_WIN32 if (MsGetConsoleWidth() == 80) { //old_size = MsSetConsoleWidth(WIN32_DEFAULT_CONSOLE_WIDTH); } #endif // OS_WIN32 c->ConsoleType = CONSOLE_LOCAL; c->Free = ConsoleLocalFree; c->ReadLine = ConsoleLocalReadLine; c->ReadPassword = ConsoleLocalReadPassword; c->Write = ConsoleLocalWrite; c->GetWidth = ConsoleLocalGetWidth; c->OutputLock = NewLock(); if (UniIsEmptyStr(infile) == false) { // Input file is specified in_io = FileOpenW(infile, false); if (in_io == NULL) { wchar_t tmp[MAX_SIZE]; UniFormat(tmp, sizeof(tmp), _UU("CON_INFILE_ERROR"), infile); c->Write(c, tmp); Free(c); return NULL; } else { wchar_t tmp[MAX_SIZE]; UniFormat(tmp, sizeof(tmp), _UU("CON_INFILE_START"), infile); c->Write(c, tmp); } } if (UniIsEmptyStr(outfile) == false) { // Output file is specified out_io = FileCreateW(outfile); if (out_io == NULL) { wchar_t tmp[MAX_SIZE]; UniFormat(tmp, sizeof(tmp), _UU("CON_OUTFILE_ERROR"), outfile); c->Write(c, tmp); Free(c); if (in_io != NULL) { FileClose(in_io); } return NULL; } else { wchar_t tmp[MAX_SIZE]; UniFormat(tmp, sizeof(tmp), _UU("CON_OUTFILE_START"), outfile); c->Write(c, tmp); } } p = ZeroMalloc(sizeof(LOCAL_CONSOLE_PARAM)); c->Param = p; p->InFile = in_io; p->OutFile = out_io; p->Win32_OldConsoleWidth = old_size; if (in_io != NULL) { UINT size; void *buf; size = FileSize(in_io); buf = ZeroMalloc(size + 1); FileRead(in_io, buf, size); p->InBuf = NewBuf(); WriteBuf(p->InBuf, buf, size); Free(buf); p->InBuf->Current = 0; } return c; }
FOLDER *CfgReadW(wchar_t *name) { wchar_t tmp[MAX_SIZE]; wchar_t newfile[MAX_SIZE]; BUF *b; IO *o; UINT size; void *buf; FOLDER *f; bool delete_new = false; bool binary_file = false; bool invalid_file = false; UCHAR header[8]; // Validate arguments if (name == NULL) { return NULL; } // Generate a new file name UniFormat(newfile, sizeof(newfile), L"%s.new", name); // Generate a temporary file name UniFormat(tmp, sizeof(tmp), L"%s.log", name); // Read the new file if it exists o = FileOpenW(newfile, false); if (o == NULL) { // Read the temporary file o = FileOpenW(tmp, false); } else { delete_new = true; } if (o == NULL) { // Read the original file if there is no temporary file o = FileOpenW(name, false); } else { // Read the original file too if the size of temporary file is 0 if (FileSize(o) == 0) { invalid_file = true; } if (invalid_file) { FileClose(o); o = FileOpenW(name, false); } } if (o == NULL) { // Failed to read return NULL; } // Read into the buffer size = FileSize(o); buf = Malloc(size); FileRead(o, buf, size); b = NewBuf(); WriteBuf(b, buf, size); SeekBuf(b, 0, 0); // Close the file FileClose(o); if (delete_new) { // Delete the new file FileDeleteW(newfile); } // If the beginning 8 character of the buffer is "SEVPN_DB", it is binary file ReadBuf(b, header, sizeof(header)); if (Cmp(header, TAG_BINARY, 8) == 0) { UCHAR hash1[SHA1_SIZE], hash2[SHA1_SIZE]; binary_file = true; // Check the hash ReadBuf(b, hash1, sizeof(hash1)); Hash(hash2, ((UCHAR *)b->Buf) + 8 + SHA1_SIZE, b->Size - 8 - SHA1_SIZE, true); if (Cmp(hash1, hash2, SHA1_SIZE) != 0) { // Corrupted file invalid_file = true; FreeBuf(b); return NULL; } } SeekBuf(b, 0, 0); if (binary_file) { SeekBuf(b, 8 + SHA1_SIZE, 0); } // Convert the buffer into a folder if (binary_file == false) { // Text mode f = CfgBufTextToFolder(b); } else { // Binary mode f = CfgBufBinToFolder(b); } // Memory release Free(buf); FreeBuf(b); FileDeleteW(newfile); return f; }
/** * Writes an 8-bit value to the stream. */ void IDataStream::Write8(UInt8 inData) { WriteBuf(&inData, sizeof(UInt8)); }
// Save sound event BOOL save_theme_sound(APTR file,DOpusCallbackInfo *info,char *type,struct MsgPort *reply_port,char *build_path,APTR progress) { char buf[400],buf2[340],temp[340],*ptr; BOOL ret=1; short len; // Increment progress if (progress) SetProgressWindowTags(progress,PW_FileInc,1,TAG_END); // Get settings lsprintf(buf,"dopus query sound \"%s\"",(IPTR)type); DC_CALL5(info, dc_RexxCommand, DC_REGA0, buf, DC_REGA1, buf2, DC_REGD0, sizeof(buf2), DC_REGA2, reply_port, DC_REGD1, 0); //DC_RexxCommand(info,buf,buf2,sizeof(buf2),reply_port,0); //info->dc_RexxCommand(buf,buf2,sizeof(buf2),reply_port,0); // Build command ptr=buf2; rexx_parse_word(&ptr,temp,254); if ((len=strlen(temp))>0) { // Building theme? if (*build_path && temp[len-1]!='/' && !strchr(temp,'*') && !strchr(temp,'#') && !strchr(temp,'?')) { BPTR lock; char dest[340]; // Try to create in sounds sub-directory strcpy(dest,build_path); AddPart(dest,"Sounds",340); if ((lock=CreateDir(dest)) || IoErr()==ERROR_OBJECT_EXISTS) UnLock(lock); else strcpy(dest,build_path); // Add filename AddPart(dest,FilePart(temp),340); // Try to copy file if (theme_copy_file(temp,dest)) lsprintf(temp,"D5THEMES:%s/Sounds/%s",(IPTR)FilePart(build_path),(IPTR)FilePart(dest)); else ret=0; } lsprintf(buf,"\tdopus set sound \"\'%s\'\" \"\'%s\'\"",(IPTR)type,(IPTR)temp); } else { lsprintf(buf,"\tdopus clear sound \"\'%s\'\"",(IPTR)type); ptr=0; } // Write command to rexx script WriteBuf(file,buf,-1); if (ptr) WriteBuf(file,ptr,-1); WriteBuf(file,"\n",1); return ret; }
// IPv6 パケットヘッダ部のビルド BUF *BuildIPv6PacketHeader(IPV6_HEADER_PACKET_INFO *info, UINT *bytes_before_payload) { BUF *b; QUEUE *q; UINT bbp = 0; // 引数チェック if (info == NULL) { return NULL; } b = NewBuf(); q = NewQueueFast(); // オプションヘッダの一覧を作成 if (info->HopHeader != NULL) { InsertQueueInt(q, IPV6_HEADER_HOP); } if (info->EndPointHeader != NULL) { InsertQueueInt(q, IPV6_HEADER_ENDPOINT); } if (info->RoutingHeader != NULL) { InsertQueueInt(q, IPV6_HEADER_ROUTING); } if (info->FragmentHeader != NULL) { InsertQueueInt(q, IPV6_HEADER_FRAGMENT); } InsertQueueInt(q, info->Protocol); // IPv6 ヘッダ info->IPv6Header->NextHeader = IPv6GetNextHeaderFromQueue(q); WriteBuf(b, info->IPv6Header, sizeof(IPV6_HEADER)); // ホップバイホップオプションヘッダ if (info->HopHeader != NULL) { BuildAndAddIPv6PacketOptionHeader(b, info->HopHeader, IPv6GetNextHeaderFromQueue(q), info->HopHeaderSize); } // 終点オプションヘッダ if (info->EndPointHeader != NULL) { BuildAndAddIPv6PacketOptionHeader(b, info->EndPointHeader, IPv6GetNextHeaderFromQueue(q), info->EndPointHeaderSize); } // ルーティングヘッダ if (info->RoutingHeader != NULL) { BuildAndAddIPv6PacketOptionHeader(b, info->RoutingHeader, IPv6GetNextHeaderFromQueue(q), info->RoutingHeaderSize); } // フラグメントヘッダ if (info->FragmentHeader != NULL) { info->FragmentHeader->NextHeader = IPv6GetNextHeaderFromQueue(q); WriteBuf(b, info->FragmentHeader, sizeof(IPV6_FRAGMENT_HEADER)); } bbp = b->Size; if (info->FragmentHeader == NULL) { bbp += sizeof(IPV6_FRAGMENT_HEADER); } // ペイロード if (info->Protocol != IPV6_HEADER_NONE) { WriteBuf(b, info->Payload, info->PayloadSize); } ReleaseQueue(q); SeekBuf(b, 0, 0); // ペイロード長さ ((IPV6_HEADER *)b->Buf)->PayloadLength = Endian16(b->Size - (USHORT)sizeof(IPV6_HEADER)); if (bytes_before_payload != NULL) { // ペイロードの直前までの長さ (ただしフラグメントヘッダは必ず含まれると仮定) // を計算する *bytes_before_payload = bbp; } return b; }
// 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; }
// 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; }
// Cut out the token from string (Ignore blanks between delimiters) TOKEN_LIST *ParseTokenWithoutNullStr(char *str, char *split_chars) { LIST *o; UINT i, len; bool last_flag; BUF *b; char zero = 0; TOKEN_LIST *t; // Validate arguments if (str == NULL) { return NullToken(); } if (split_chars == NULL) { split_chars = DefaultTokenSplitChars(); } b = NewBuf(); o = NewListFast(NULL); len = StrLen(str); last_flag = false; for (i = 0;i < (len + 1);i++) { char c = str[i]; bool flag = IsCharInStr(split_chars, c); if (c == '\0') { flag = true; } if (flag == false) { WriteBuf(b, &c, sizeof(char)); } else { if (last_flag == false) { WriteBuf(b, &zero, sizeof(char)); if ((StrLen((char *)b->Buf)) != 0) { Insert(o, CopyStr((char *)b->Buf)); } ClearBuf(b); } } last_flag = flag; } t = ZeroMalloc(sizeof(TOKEN_LIST)); t->NumTokens = LIST_NUM(o); t->Token = ZeroMalloc(sizeof(char *) * t->NumTokens); for (i = 0;i < t->NumTokens;i++) { t->Token[i] = LIST_DATA(o, i); } ReleaseList(o); FreeBuf(b); return t; }
// 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; }