DWORD WINAPI ScanThread(LPVOID lpParam) { int i; ROM_INFO *pRomInfo; md5_byte_t digest[16]; char tempname[100]; EnableWindow(GetDlgItem(romInfoHWND,IDC_STOP),TRUE); EnableWindow(GetDlgItem(romInfoHWND,IDC_START),FALSE); EnableWindow(GetDlgItem(romInfoHWND,IDC_CLOSE),FALSE); for (i=0;i<ItemList.ListCount;i++) { if (stopScan) break; pRomInfo = &ItemList.List[i]; sprintf(TempMessage,"%d",i+1); SetDlgItemText(romInfoHWND,IDC_CURRENT_ROM,TempMessage); SetDlgItemText(romInfoHWND,IDC_ROM_FULLPATH,pRomInfo->szFullFileName); //SendMessage( GetDlgItem(romInfoHWND, IDC_TOTAL_ROMS_PROGRESS), PBM_STEPIT, 0, 0 ); SendMessage( GetDlgItem(romInfoHWND, IDC_TOTAL_ROMS_PROGRESS), PBM_SETPOS, i+1, 0 ); strcpy(TempMessage,pRomInfo->MD5); if (!strcmp(TempMessage,"")) { calculateMD5(pRomInfo->szFullFileName,digest); MD5toString(digest,TempMessage); } strcpy(pRomInfo->MD5,TempMessage); getIniGoodNameByMD5(TempMessage,tempname); strcpy(pRomInfo->GoodName,tempname); } //SendMessage( GetDlgItem(romInfoHWND, IDC_TOTAL_ROMS_PROGRESS), PBM_SETPOS, 0, 0 ); EnableWindow(GetDlgItem(romInfoHWND,IDC_STOP),FALSE); EnableWindow(GetDlgItem(romInfoHWND,IDC_START),TRUE); EnableWindow(GetDlgItem(romInfoHWND,IDC_CLOSE),TRUE); ExitThread(dwExitCode); }
char* MD5CredentialData(const char* userName, const char* password, const char* nonce) { int len = 0, lenNonce = 0, totLen = 0; char cnonce [64]; char digest [16]; char base64 [64]; char base64Nonce [64]; char token [512]; char* md5Digest = NULL; char ch [3]; memset(digest, 0, 16); memset(base64, 0, 64); memset(base64Nonce, 0, 64); memset(cnonce, 0, 64); memset(token, 0, 512); sprintf(ch, ":"); sprintf(token, "%s:%s", userName, password); len = strlen(token); // H(username:password) calculateMD5((void*)token, len, digest); // B64(H(username:password)) len = b64_encode((char*)base64, digest, 16); // decode nonce from stored base64 to bin strcpy(cnonce, nonce); lenNonce = b64_decode(cnonce, cnonce); memcpy(base64Nonce, base64, len); memcpy(&base64Nonce[len], ch, 1); memcpy(&base64Nonce[len+1], cnonce, lenNonce); totLen = len + 1 + lenNonce; memset(digest, 0, 16); calculateMD5(base64Nonce, totLen, digest); b64_encode(base64, digest, 16); // return new value md5Digest = stringdup(base64); return md5Digest; }
void NetworkManager::createFile(const std::vector<char>& data) { std::string fileName = &data[1]; const char* absfilename = g_pathForFile(fileName.c_str()); FILE* fos = fopen(absfilename, "wb"); int pos = 1 + fileName.size() + 1; if (data.size() > pos) fwrite(&data[pos], data.size() - pos, 1, fos); fclose(fos); calculateMD5(fileName.c_str()); saveMD5(); }
int serverVerifyFile(BIO *conn, int clientid) { //receive the filename char filename[BUFFER_SIZE]; if(readString(conn, filename, sizeof(filename)) < 1) return -1; //receive the salt unsigned char salt[SALT_LENGTH]; if(readPacket(conn, (char *)salt, SALT_LENGTH) < 1) return -1; //navigate to the users directory char userDirectory[BUFFER_SIZE]; snprintf(userDirectory, sizeof(userDirectory), "./%s/%d/", SERVER_FILE_FOLDER, clientid); if(chdir(userDirectory) != 0) { perror("serverDeleteFile"); return -1; } //open the file or send 5 if file does not exits FILE *ifp = fopen(filename, "rb"); if(ifp == NULL) { if(writeInt(conn, 5) < 1) return -1; return 5; } fclose(ifp); //calculate a digest unsigned char *digest = calculateMD5(filename, salt, SALT_LENGTH); //send -1 if failed to calculate digest if(digest == NULL) { writeInt(conn, -1); return -1; } //return to main directory if(chdir("../../") != 0) { perror("serverDeleteFile"); return -1; } //send 0 to indicate no failure, and a digest is coming if(writeInt(conn, 0) < 1) return -1; //send the digest if(writePacket(conn, (char *)digest, HASH_LENGTH) < 1) return -1; return 0; }
void NetworkManager::sendFileList() { ByteBuffer buffer; // type(byte) 6 // D or F, file (zero ended string), age (int) // D or F, file (zero ended string), age (int) // .... buffer.append((char)6); std::vector<std::string> files, directories; getDirectoryListingR(resourceDirectory_.c_str(), &files, &directories); for (std::size_t i = 0; i < files.size(); ++i) { buffer.append('F'); buffer.append(files[i]); int age = fileAge(pathForFileEx(resourceDirectory_.c_str(), files[i].c_str())); buffer.append(age); std::map<std::string, std::vector<unsigned char> >::iterator iter = md5_.find(files[i]); if (iter == md5_.end()) { calculateMD5(files[i].c_str()); saveMD5(); iter = md5_.find(files[i]); } buffer.append(&iter->second[0], 16); } for (std::size_t i = 0; i < directories.size(); ++i) { buffer.append('D'); buffer.append(directories[i]); } serverSendData(buffer.data(), buffer.size()); }
string replaceParameters(const string& s, const char* r_type, const AmSipRequest& req, const string& app_param, AmUriParser& ruri_parser, AmUriParser& from_parser, AmUriParser& to_parser) { string res; bool is_replaced = false; size_t p = 0; bool is_escaped = false; // char last_char=' '; while (p<s.length()) { size_t skip_chars = 1; if (is_escaped) { switch (s[p]) { case 'r': res += '\r'; break; case 'n': res += '\n'; break; case 't': res += '\t'; break; default: res += s[p]; break; } is_escaped = false; } else { // not escaped if (s[p]=='\\') { if (p==s.length()-1) { res += '\\'; // add single \ at the end } else { is_escaped = true; is_replaced = true; } } else if ((s[p]=='$') && (s.length() >= p+1)) { is_replaced = true; p++; switch (s[p]) { case 'f': { // from if ((s.length() == p+1) || (s[p+1] == '.')) { res += req.from; break; } if (s[p+1]=='t') { // $ft - from tag res += req.from_tag; break; } if (from_parser.uri.empty()) { size_t end; if (!from_parser.parse_contact(req.from, 0, end)) { WARN("Error parsing From URI '%s'\n", req.from.c_str()); break; } from_parser.dump(); } replaceParsedParam(s, p, from_parser, res); }; break; case 't': { // to if ((s.length() == p+1) || (s[p+1] == '.')) { res += req.to; break; } if (to_parser.uri.empty()) { size_t end; if (!to_parser.parse_contact(req.to, 0, end)) { WARN("Error parsing To URI '%s'\n", req.to.c_str()); break; } } replaceParsedParam(s, p, to_parser, res); }; break; case 'r': { // r-uri if ((s.length() == p+1) || (s[p+1] == '.')) { res += req.r_uri; break; } if (ruri_parser.uri.empty()) { ruri_parser.uri = req.r_uri; if (!ruri_parser.parse_uri()) { WARN("Error parsing R-URI '%s'\n", req.r_uri.c_str()); break; } } replaceParsedParam(s, p, ruri_parser, res); }; break; case 'c': { // call-id if ((s.length() == p+1) || (s[p+1] == 'i')) { res += req.callid; break; } WARN("unknown replacement $c%c\n", s[p+1]); }; break; case 's': { // source (remote) if (s.length() < p+1) { WARN("unknown replacement $s\n"); break; } if (s[p+1] == 'i') { // $si source IP address res += req.remote_ip.c_str(); break; } else if (s[p+1] == 'p') { // $sp source port res += int2str(req.remote_port); break; } WARN("unknown replacement $s%c\n", s[p+1]); }; break; case 'R': { // received (local) if (s.length() < p+1) { WARN("unknown replacement $R\n"); break; } if (s[p+1] == 'i') { // $Ri received IP address res += req.local_ip.c_str(); break; } else if (s[p+1] == 'p') { // $Rp received port res += int2str(req.local_port); break; } else if (s[p+1] == 'f') { // $Rf received interface id res += int2str(req.local_if); } else if (s[p+1] == 'n') { // $Rn received interface name if ((req.local_if >= 0) && req.local_if < AmConfig::Ifs.size()) { res += AmConfig::Ifs[req.local_if].name; } } else if (s[p+1] == 'I') { // $RI received interface public IP if ((req.local_if >= 0) && req.local_if < AmConfig::Ifs.size()) { res += AmConfig::Ifs[req.local_if].PublicIP; } } WARN("unknown replacement $R%c\n", s[p+1]); }; break; #define case_HDR(pv_char, pv_name, hdr_name) \ case pv_char: { \ AmUriParser uri_parser; \ string m_uri = getHeader(req.hdrs, hdr_name); \ if ((s.length() == p+1) || (s[p+1] == '.')) { \ res += m_uri; \ break; \ } \ size_t end; \ if (!uri_parser.parse_contact(m_uri, 0, end)) { \ WARN("Error parsing " pv_name " URI '%s'\n", m_uri.c_str()); \ break; \ } \ if (s[p+1] == 'i') { \ res+=uri_parser.uri_user+"@"+uri_parser.uri_host; \ if (!uri_parser.uri_port.empty()) \ res+=":"+uri_parser.uri_port; \ } else { \ replaceParsedParam(s, p, uri_parser, res); \ } \ }; break; case_HDR('a', "PAI", SIP_HDR_P_ASSERTED_IDENTITY); // P-Asserted-Identity case_HDR('p', "PPI", SIP_HDR_P_PREFERRED_IDENTITY); // P-Preferred-Identity case 'P': { // app-params if (s[p+1] != '(') { WARN("Error parsing P param replacement (missing '(')\n"); break; } if (s.length()<p+3) { WARN("Error parsing P param replacement (short string)\n"); break; } size_t skip_p = p+2; for (;skip_p<s.length() && s[skip_p] != ')';skip_p++) { } if (skip_p==s.length()) { WARN("Error parsing P param replacement (unclosed brackets)\n"); break; } string param_name = s.substr(p+2, skip_p-p-2); // DBG("param_name = '%s' (skip-p - p = %d)\n", param_name.c_str(), skip_p-p); res += get_header_keyvalue(app_param, param_name); skip_chars = skip_p-p; } break; case 'H': { // header size_t name_offset = 2; if (s[p+1] != '(') { if (s[p+2] != '(') { WARN("Error parsing H header replacement (missing '(')\n"); break; } name_offset = 3; } if (s.length()<name_offset+1) { WARN("Error parsing H header replacement (short string)\n"); break; } size_t skip_p = p+name_offset; for (;skip_p<s.length() && s[skip_p] != ')';skip_p++) { } if (skip_p==s.length()) { WARN("Error parsing H header replacement (unclosed brackets)\n"); break; } string hdr_name = s.substr(p+name_offset, skip_p-p-name_offset); // DBG("param_name = '%s' (skip-p - p = %d)\n", param_name.c_str(), skip_p-p); if (name_offset == 2) { // full header res += getHeader(req.hdrs, hdr_name); } else { // parse URI and use component AmUriParser uri_parser; string m_uri = getHeader(req.hdrs, hdr_name); if ((s[p+1] == '.')) { res += m_uri; break; } size_t end; if (!uri_parser.parse_contact(m_uri, 0, end)) { WARN("Error parsing header %s URI '%s'\n", hdr_name.c_str(), m_uri.c_str()); break; } replaceParsedParam(s, p, uri_parser, res); } skip_chars = skip_p-p; } break; case 'M': { // regex map if (s[p+1] != '(') { WARN("Error parsing $M regex map replacement (missing '(')\n"); break; } if (s.length()<p+3) { WARN("Error parsing $M regex map replacement (short string)\n"); break; } size_t skip_p = p+2; skip_p = skip_to_end_of_brackets(s, skip_p); if (skip_p==s.length()) { WARN("Error parsing $M regex map replacement (unclosed brackets)\n"); skip_chars = skip_p-p; break; } string map_str = s.substr(p+2, skip_p-p-2); size_t spos = map_str.rfind("=>"); if (spos == string::npos) { skip_chars = skip_p-p; WARN("Error parsing $M regex map replacement: no => found in '%s'\n", map_str.c_str()); break; } string map_val = map_str.substr(0, spos); string map_val_replaced = replaceParameters(map_val, r_type, req, app_param, ruri_parser, from_parser, to_parser); string mapping_name = map_str.substr(spos+2); string map_res; if (SBCFactory::regex_mappings. mapRegex(mapping_name, map_val_replaced.c_str(), map_res)) { DBG("matched regex mapping '%s' (orig '%s) in '%s'\n", map_val_replaced.c_str(), map_val.c_str(), mapping_name.c_str()); res+=map_res; } else { DBG("no match in regex mapping '%s' (orig '%s') in '%s'\n", map_val_replaced.c_str(), map_val.c_str(), mapping_name.c_str()); } skip_chars = skip_p-p; } break; case '_': { // modify if (s.length()<p+4) { // $_O() WARN("Error parsing $_ modifier replacement (short string)\n"); break; } char operation = s[p+1]; if (operation != 'U' && operation != 'l' && operation != 's' && operation != '5') { WARN("Error parsing $_%c string modifier: unknown operator '%c'\n", operation, operation); } if (s[p+2] != '(') { WARN("Error parsing $U upcase replacement (missing '(')\n"); break; } size_t skip_p = p+3; skip_p = skip_to_end_of_brackets(s, skip_p); if (skip_p==s.length()) { WARN("Error parsing $_ modifier (unclosed brackets)\n"); skip_chars = skip_p-p; break; } string br_str = s.substr(p+3, skip_p-p-3); string br_str_replaced = replaceParameters(br_str, "$_*(...)", req, app_param, ruri_parser, from_parser, to_parser); br_str = br_str_replaced; switch(operation) { case 'u': // uppercase transform(br_str_replaced.begin(), br_str_replaced.end(), br_str_replaced.begin(), ::toupper); break; case 'l': // lowercase transform(br_str_replaced.begin(), br_str_replaced.end(), br_str_replaced.begin(), ::tolower); break; case 's': // size (string length) br_str_replaced = int2str((unsigned int)br_str.length()); break; case '5': // md5 br_str_replaced = calculateMD5(br_str); break; default: break; } DBG("applied operator '%c': '%s' => '%s'\n", operation, br_str.c_str(), br_str_replaced.c_str()); res+=br_str_replaced; skip_chars = skip_p-p; } break; default: { WARN("unknown replace pattern $%c%c\n", s[p], s[p+1]); }; break; }; p+=skip_chars; // skip $.X } else { res += s[p]; } } // end not escaped p++; } if (is_replaced) { DBG("%s pattern replace: '%s' -> '%s'\n", r_type, s.c_str(), res.c_str()); } return res; }
/* Generate new salt/hash combinations for verification of the given * file. I.e the client can download their file, then call this function * to give them another NUM_HASHES new verification calls */ int clientRefreshHashes(BIO *conn, char *filename) { //download the file from the server (but dont decrypt it) //this saves it as TEMP_ENCRYPTED_FILENAME int status = clientDownloadFile(conn, filename, 0); if(status != 0) return status; //we need to store NUM_HASHES salts and digests for later verification unsigned char *salts[NUM_HASHES]; unsigned char *hashes[NUM_HASHES]; //get the deatils of this file FILERECORD *record = getRecord(filename); if(record == NULL) return -1; //check the file matches the hashes we have stored //(to stop the server switching the file on us as we update the hashes) for(int i=0; i < NUM_HASHES; ++i) { unsigned char *recordHash = record->hashData[i]; unsigned char *salt = record->hashData[i] + HASH_LENGTH; unsigned char *hash = calculateMD5(TEMP_ENCRYPTED_FILENAME, salt, SALT_LENGTH); if(memcmp(recordHash, hash, HASH_LENGTH) != 0) { fprintf(stderr, "Mismatching hash for downloaded file during clientRefreshHashes()\n"); free(hash); return -1; } free(hash); } //generate new salts and hashes to give us NUM_HASHES more calls to clientVerifyFile for(int i=0; i<NUM_HASHES; ++i) { //generate a random salt salts[i] = randomBytes(SALT_LENGTH); //compute the digest for the file with that salt hashes[i] = calculateMD5(TEMP_ENCRYPTED_FILENAME, salts[i], SALT_LENGTH); if(hashes[i] == NULL) { fprintf(stderr, "Failed to calculate digest in clientRefreshHashes()\n"); return -1; } } //we no longer need the copy we downloaded unlink(TEMP_ENCRYPTED_FILENAME); //update the record with these new hashes and reset the hashIndex status = addRecord(filename, 0, hashes, salts, record->key, record->iv); if(status == -1) { fprintf(stderr, "Failed to update record for %s in clientRefreshHashes()\n", filename); return -1; } //free the salts and hashes we generated for(int i=0; i < NUM_HASHES; ++i) { free(salts[i]); free(hashes[i]); } printf("Verified the file (all %d digests match),\n", NUM_HASHES); printf("and generated %d new digests.\n", NUM_HASHES); return 0; }
int clientUploadFile(BIO *conn, char *filename) { /* CALCULATE AND STORE ANY RECORDS OF THIS FILE WE NEED * BEFORE UPLOADING IT */ FILE *ifp = fopen(filename, "rb"); if ( ifp == NULL ) return NO_SUCH_FILE; //generate key and iv for encryption unsigned char *key = randomBytes(32); unsigned char *iv = randomBytes(32); //encrypt the file int status = encryptFile(filename, TEMP_ENCRYPTED_FILENAME, key, iv); if(status == -1) { fprintf(stderr, "Failed to encrypt %s in clientUploadFile()\n", filename); return -1; } //we need to store NUM_HASHES salts and digests for later verification unsigned char *salts[NUM_HASHES]; unsigned char *hashes[NUM_HASHES]; for(int i=0; i<NUM_HASHES; ++i) { //generate a random salt salts[i] = randomBytes(SALT_LENGTH); //compute the digest for the file with that salt hashes[i] = calculateMD5(TEMP_ENCRYPTED_FILENAME, salts[i], SALT_LENGTH); if(hashes[i] == NULL) { fprintf(stderr, "Failed to calculate digest in clientUploadFile()\n"); return -1; } } //store all this data for later status = addRecord(filename, 0, hashes, salts, key, iv); if(status == -1) { fprintf(stderr, "addRecord() failed for in clientUploadFile()\n"); return -1; } //free the memory we allocated above for(int i=0; i < NUM_HASHES; ++i) { free(salts[i]); free(hashes[i]); } free(key); free(iv); /* START THE ACTUAL COMMUNICATION WITH THE SERVER */ //send the code which causes the server to call serverUploadFile() if(writeInt(conn, UPLOAD_FILE_CODE) == -1) return -1; //send the fileSize int fileSize = sizeOfFile(TEMP_ENCRYPTED_FILENAME); if(writeInt(conn, fileSize) == -1) return -1; printf("NOTE: Original size: %f MB. Encrypted size: %f MB.\n", (double)sizeOfFile(filename)/MEGABYTE, (double)fileSize/MEGABYTE); //wait for an int telling us the balance owing unsigned int fee = readInt(conn); if(fee > 0) { printf("Purchase %d more cloud dollar(s) to upload this file.\n", fee); removeRecord(filename); return -1; } else if(fee < 0) return -1; //send the file if(writeFile(conn, TEMP_ENCRYPTED_FILENAME, filename) < 1) return -1; unlink( TEMP_ENCRYPTED_FILENAME ); printf("Succesfully uploaded the file.\n"); return 0; }