BOOL TRecvDlg::DecodeDirEntry(char *buf, FileInfo *info, char *u8fname) { char *tok, *ptr, *p; ConvertShareMsgEscape(buf); // "::" -> ';' if ((tok = separate_token(buf, ':', &p)) == NULL) // header size return FALSE; if ((tok = separate_token(NULL, ':', &p)) == NULL) // fname return FALSE; WCHAR wbuf[MAX_PATH]; AtoW(tok, wbuf, MAX_PATH); WtoU8(wbuf, u8fname, MAX_PATH_U8); info->SetFnameExt(u8fname); while ((ptr = strchr(tok, '?')) != NULL) // UNICODE までの暫定 *ptr = '_'; if (strlen(tok) >= MAX_PATH_U8) return FALSE; if ((tok = separate_token(NULL, ':', &p)) == NULL) // size return FALSE; info->SetSize(hex2ll(tok)); if ((tok = separate_token(NULL, ':', &p)) == NULL) // attr return FALSE; info->SetAttr(strtoul(tok, 0, 16)); while ((tok = separate_token(NULL, ':', &p)) != NULL) // exattr { if ((ptr = strchr(tok, '=')) == NULL) continue; *ptr = 0; UINT exattr = strtoul(tok, 0, 16); UINT val = strtoul(ptr + 1, 0, 16); switch (exattr) { case IPMSG_FILE_MTIME: info->SetMtime(val); break; // case IPMSG_FILE_CREATETIME: info->SetCrtime(val); break; 現状では使わない // case IPMSG_FILE_ATIME: info->SetAtime(val); break; 現状では使わない default: break; } } return TRUE; }
void option_imp< vector<string> >::post_process() { if (popt_value) { value = separate_token(popt_value, separator); popt_value = 0; } }
/* ファイル共有(添付)情報をデコード 注意:破壊読出し。使用が終わり次第 FreeDecodeShareMsg を呼び出すこと。 */ ShareInfo *DecodeShareMsg(char *buf, BOOL enable_clip) { ShareInfo *shareInfo = new ShareInfo; FileInfo *fileInfo = NULL; char *tok, *p, *p2, *p3; char *file = separate_token(buf, FILELIST_SEPARATOR, &p); for (int i=0; file; i++, file=separate_token(NULL, FILELIST_SEPARATOR, &p)) { ConvertShareMsgEscape(file); // "::" -> ';' if ((tok = separate_token(file, ':', &p2)) == NULL) break; fileInfo = new FileInfo(atoi(tok)); if ((tok = separate_token(NULL, ':', &p2)) == NULL || strlen(tok) >= MAX_FILENAME) break; while ((p3 = strchr(tok, '?'))) // UNICODE 対応までの暫定 *p3 = '_'; if (!IsValidFileName(tok)) break; fileInfo->SetFname(tok); if ((tok = separate_token(NULL, ':', &p2)) == NULL) break; fileInfo->SetSize(hex2ll(tok)); if ((tok = separate_token(NULL, ':', &p2)) == NULL) break; fileInfo->SetMtime(strtoul(tok, 0, 16)); if ((tok = separate_token(NULL, ':', &p2))) { fileInfo->SetAttr(strtoul(tok, 0, 16)); u_int attr_type = GET_MODE(fileInfo->Attr()); if (attr_type != IPMSG_FILE_DIR && attr_type != IPMSG_FILE_REGULAR && (!enable_clip || attr_type != IPMSG_FILE_CLIPBOARD)) { delete fileInfo; fileInfo = NULL; continue; } if (attr_type == IPMSG_FILE_CLIPBOARD) { if ((tok = separate_token(NULL, ':', &p2))) { if (strtoul(tok, 0, 16) == IPMSG_FILE_CLIPBOARDPOS) { if (separate_token(tok, '=', &p3) && (tok = separate_token(NULL, '=', &p3))) { fileInfo->SetPos(strtoul(tok, 0, 16)); } } } } } else fileInfo->SetAttr(IPMSG_FILE_REGULAR); if ((shareInfo->fileCnt % BIG_ALLOC) == 0) shareInfo->fileInfo = (FileInfo **)realloc(shareInfo->fileInfo, (shareInfo->fileCnt + BIG_ALLOC) * sizeof(FileInfo *)); shareInfo->fileInfo[shareInfo->fileCnt++] = fileInfo; fileInfo = NULL; } if (fileInfo) // デコード中に抜けた delete fileInfo; if (shareInfo->fileCnt <= 0) { delete shareInfo; return NULL; } return shareInfo; }
BOOL ShareMng::GetAcceptableFileInfo(ConnectInfo *info, char *buf, AcceptFileInfo *fileInfo) { // 本当はこんなところでデコードせず、msgmng にやらせるべきだが... char *tok, *p, *user_name, *host_name; int targetID; ShareInfo *shareInfo; HostSub hostSub = { "", "", info->addr, info->port }; if ((tok = separate_token(buf, ':', &p)) == NULL || atoi(tok) != IPMSG_VERSION) return FALSE; if ((tok = separate_token(NULL, ':', &p)) == NULL) // packet no return FALSE; if ((user_name = separate_token(NULL, ':', &p)) == NULL) return FALSE; if ((host_name = separate_token(NULL, ':', &p)) == NULL) return FALSE; if ((tok = separate_token(NULL, ':', &p)) == NULL) // command return FALSE; fileInfo->command = atoi(tok); if (fileInfo->command & IPMSG_UTF8OPT) { strncpyz(hostSub.userName, user_name, MAX_NAMEBUF); strncpyz(hostSub.hostName, host_name, MAX_NAMEBUF); } else { strncpyz(hostSub.userName, AtoU8(user_name), MAX_NAMEBUF); strncpyz(hostSub.hostName, AtoU8(host_name), MAX_NAMEBUF); } if ((tok = separate_token(NULL, ':', &p)) == NULL) return FALSE; fileInfo->packetNo = strtol(tok, 0, 16); if ((tok = separate_token(NULL, ':', &p)) == NULL) return FALSE; targetID = strtol(tok, 0, 16); if (GET_MODE(fileInfo->command) == IPMSG_GETFILEDATA) { if ((tok = separate_token(NULL, ':', &p)) == NULL) return FALSE; fileInfo->offset = hex2ll(tok); } else if (GET_MODE(fileInfo->command) == IPMSG_GETDIRFILES) fileInfo->offset = 0; else return FALSE; if ((shareInfo = Search(fileInfo->packetNo)) == NULL) return FALSE; int host_cnt, file_cnt; for (host_cnt=0; host_cnt < shareInfo->hostCnt; host_cnt++) { if (IsSameHostEx(&shareInfo->host[host_cnt]->hostSub, &hostSub)) { fileInfo->host = shareInfo->host[host_cnt]; break; } } if (host_cnt == shareInfo->hostCnt) return FALSE; for (file_cnt=0; file_cnt < shareInfo->fileCnt; file_cnt++) { if (shareInfo->fileInfo[file_cnt]->Id() == targetID) { fileInfo->fileInfo = shareInfo->fileInfo[file_cnt]; if (shareInfo->transStat[shareInfo->fileCnt * host_cnt + file_cnt] != TRANS_INIT) return FALSE; // download 済み(or 最中) if (GET_MODE(fileInfo->command) != IPMSG_GETDIRFILES && GET_MODE(fileInfo->fileInfo->Attr()) == IPMSG_FILE_DIR) // dir に対して IPMSG_GETDIRFILES 以外は認めない return FALSE; fileInfo->attachTime = shareInfo->attachTime; shareInfo->transStat[shareInfo->fileCnt * host_cnt + file_cnt] = TRANS_BUSY; statDlg->Refresh(); return TRUE; } } return FALSE; }
BOOL MsgMng::ResolveMsg(RecvBuf *buf, MsgBuf *msg) { char *exStr = NULL, *tok, *p; char *exStr2 = NULL; char *userName, *hostName; int len, exLen = 0; len = (int)strlen(buf->msgBuf); // main message if (buf->size > len + 1) { // ex message (group name or attached file) exStr = buf->msgBuf + len + 1; exLen = (int)strlen(exStr); if (buf->size > len + 1 + exLen + 1) { // ex2 message (utf8 entry) exStr2 = exStr + exLen + 1; } } msg->hostSub.addr = buf->addr.sin_addr.s_addr; msg->hostSub.portNo = buf->addr.sin_port; if ((tok = separate_token(buf->msgBuf, ':', &p)) == NULL) return FALSE; if ((msg->version = atoi(tok)) != IPMSG_VERSION) return FALSE; if ((tok = separate_token(NULL, ':', &p)) == NULL) return FALSE; msg->packetNo = strtoul(tok, 0, 10); strncpyz(msg->packetNoStr, tok, sizeof(msg->packetNoStr)); // for IV if ((userName = separate_token(NULL, ':', &p)) == NULL) return FALSE; if ((hostName = separate_token(NULL, ':', &p)) == NULL) return FALSE; if ((tok = separate_token(NULL, ':', &p)) == NULL) return FALSE; msg->command = atol(tok); BOOL is_utf8 = (msg->command & IPMSG_UTF8OPT); strncpyz(msg->hostSub.userName, is_utf8 ? userName : AtoU8(userName), sizeof(msg->hostSub.userName)); strncpyz(msg->hostSub.hostName, is_utf8 ? hostName : AtoU8(hostName), sizeof(msg->hostSub.hostName)); int cnt = 0; *msg->msgBuf = 0; if ((tok = separate_token(NULL, 0, &p))) // 改行をUNIX形式からDOS形式に変換 { if (!is_utf8) { tok = AtoU8(tok); } UnixNewLineToLocal(tok, msg->msgBuf, MAX_UDPBUF); } if (exStr) { if (exStr[0] != '\n') { if ((msg->command & IPMSG_UTF8OPT) == 0) { exStr = AtoU8(exStr); } strncpyz(msg->exBuf, exStr, sizeof(msg->exBuf)); } else if (exStr2 == NULL) { exStr2 = exStr; } if (exStr2 && exStr2[0] == '\n' && (msg->command & IPMSG_CAPUTF8OPT)) { for (tok=separate_token(exStr2, '\n', &p); tok; tok=separate_token(NULL, '\n', &p)) { if (strncmp(tok, "UN:", 3) == 0) { strncpyz(msg->hostSub.userName, tok+3, sizeof(msg->hostSub.userName)); } else if (strncmp(tok, "HN:", 3) == 0) { strncpyz(msg->hostSub.hostName, tok+3, sizeof(msg->hostSub.hostName)); } else if (strncmp(tok, "NN:", 3) == 0) { switch (GET_MODE(msg->command)) { case IPMSG_BR_ENTRY: case IPMSG_BR_ABSENCE: strncpyz(msg->msgBuf, tok+3, sizeof(msg->msgBuf)); break; } } else if (strncmp(tok, "GN:", 3) == 0) { switch (GET_MODE(msg->command)) { case IPMSG_BR_ENTRY: case IPMSG_BR_ABSENCE: strncpyz(msg->exBuf, tok+3, sizeof(msg->exBuf)); break; } } } } } return TRUE; }
/* メッセージの復号化 */ BOOL TRecvDlg::DecryptMsg() { HCRYPTKEY hKey=0, hExKey=0; char *capa_hex, *skey_hex, *msg_hex, *p; BYTE skey[MAX_BUF]; int len, msgLen; HCRYPTPROV target_csp; if ((capa_hex = separate_token(msg.msgBuf, ':', &p)) == NULL) return FALSE; cryptCapa = strtoul(capa_hex, 0, 16); target_csp = (cryptCapa & IPMSG_RSA_1024) && cfg->pubKey.Key() ? cfg->hCsp : cfg->hSmallCsp; hExKey = target_csp == cfg->hCsp ? cfg->hPrivKey : cfg->hSmallPrivKey; if ((skey_hex = separate_token(NULL, ':', &p)) == NULL) return FALSE; if ((msg_hex = separate_token(NULL, 0, &p)) == NULL) return FALSE; if (cryptCapa & IPMSG_BLOWFISH_128) { // blowfish hexstr2bin_bigendian(skey_hex, skey, sizeof(skey), &len); // 公開鍵取得 if (!pCryptDecrypt(hExKey, 0, TRUE, 0, (BYTE *)skey, (DWORD *)&len)) return wsprintf(msg.msgBuf, "CryptDecrypt Err(%X)", GetLastError()), FALSE; CBlowFish bl(skey, len); hexstr2bin(msg_hex, (BYTE *)msg.msgBuf, sizeof(msg.msgBuf), &msgLen); bl.Decrypt((BYTE *)msg.msgBuf, (BYTE *)msg.msgBuf, msgLen); } else { // RC2 // Skey Blob を作る skey[0] = SIMPLEBLOB; skey[1] = CUR_BLOB_VERSION; *(WORD *)(skey + 2) = 0; *(ALG_ID *)(skey + 4) = CALG_RC2; *(ALG_ID *)(skey + 8) = CALG_RSA_KEYX; hexstr2bin_bigendian(skey_hex, skey + SKEY_HEADER_SIZE, sizeof(skey) - SKEY_HEADER_SIZE, &len); // セッションキーの import if (!pCryptImportKey(target_csp, skey, len + SKEY_HEADER_SIZE, hExKey, 0, &hKey)) return wsprintf(msg.msgBuf, "CryptImportKey Err(%X)", GetLastError()), FALSE; // メッセージの Decrypt hexstr2bin(msg_hex, (BYTE *)msg.msgBuf, sizeof(msg.msgBuf), &msgLen); if (!pCryptDecrypt(hKey, 0, TRUE, 0, (BYTE *)msg.msgBuf, (DWORD *)&msgLen)) return wsprintf(msg.msgBuf, "CryptDecrypt Err(%X)", GetLastError()), FALSE; pCryptDestroyKey(hKey); } // UNIX 形式の改行を変換 if (cryptCapa & (IPMSG_BLOWFISH_128|IPMSG_RC2_40)) MsgMng::UnixNewLineToLocal(msg.msgBuf, msg.msgBuf, sizeof(msg.msgBuf)); if ((msg.command & IPMSG_UTF8OPT) == 0) { char *u8buf = AtoU8(msg.msgBuf); int u8len = strlen(u8buf), diff=0; u8len = min(u8len, MAX_UDPBUF-1); int dif = u8len - strlen(msg.msgBuf); if (msg.exOffset && diff > 0) { memmove(msg.msgBuf + msg.exOffset + diff, msg.msgBuf + msg.exOffset, diff); } strncpyz(msg.msgBuf, u8buf, u8len+1); } return TRUE; }