char *AtoU8s(const char *src, int max_len) { static char *buf[MAX_STATIC_ARRAY]; static u_long idx; char *&cur_buf = buf[idx++ % MAX_STATIC_ARRAY]; if (cur_buf) { delete [] cur_buf; } return (cur_buf = AtoU8(src, max_len)); }
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; }