// ./client_PFS <Client Name> <Server IP> <Server Port> <Private Key> <Certificate of this Client> <CA Cert> int main(int argc, char const *argv[]) { const char *keyName = argv[4]; const char *certName = argv[5]; const char *CACert = argv[6]; // ssl setup SSL_CTX *ctx; SSL *clieSSL, *p2pSSL; SSL_METHOD *meth; // Load encryption & hashing algorithms for the SSL program SSL_library_init(); // Load the error strings for SSL & CRYPTO APIs SSL_load_error_strings(); // Create an SSL_METHOD structure (choose an SSL/TLS protocol version) meth = SSLv3_method(); // Create an SSL_CTX structure ctx = SSL_CTX_new(meth); // Create an SSL_CTX structure ctx = SSL_CTX_new(meth); if(ctx == NULL) { ERR_print_errors_fp(stderr); exit(1); } // Load the client certificate into the SSL_CTX structure if(SSL_CTX_use_certificate_file(ctx, argv[5], SSL_FILETYPE_PEM) <= 0) { ERR_print_errors_fp(stderr); exit(1); } // Load the private-key corresponding to the client certificate if(SSL_CTX_use_PrivateKey_file(ctx, argv[4], SSL_FILETYPE_PEM) <= 0) { ERR_print_errors_fp(stderr); exit(1); } // Check if the client certificate and private-key matches if(!SSL_CTX_check_private_key(ctx)) { printf("Private key does not match the certificate public key\n"); exit(1); } // Load the RSA CA certificate into the SSL_CTX structure // This will allow this client to verify the server's certificate if(!SSL_CTX_load_verify_locations(ctx, argv[6], NULL)) { ERR_print_errors_fp(stderr); exit(1); } // Set flag in context to require peer (server) certificate verification SSL_CTX_set_verify(ctx, SSL_VERIFY_PEER, NULL); SSL_CTX_set_verify_depth(ctx, 1); struct sockaddr_in remoteAddr, p2pAddr; int clieSock; // for connecting to server int p2pSock; // for p2p transfer int peerSock = -1; // setup sockaddr bzero(&remoteAddr, sizeof(remoteAddr)); remoteAddr.sin_family = AF_INET; remoteAddr.sin_addr.s_addr = inet_addr(argv[2]); remoteAddr.sin_port = htons(atoi(argv[3])); bzero(&p2pAddr, sizeof(p2pAddr)); p2pAddr.sin_family = AF_INET; p2pAddr.sin_addr.s_addr = inet_addr(argv[2]); p2pAddr.sin_port = htons((int)(9500 + (argv[1][0] - 'A'))); // create socket clieSock = socket(AF_INET, SOCK_STREAM, 0); p2pSock = socket(AF_INET, SOCK_STREAM, 0); if(clieSock < 0 || p2pSock < 0){ perror("socket creation"); exit(1); } if (fcntl(p2pSock, F_SETFL, O_NDELAY)<0) { perror("error set non-block for client-p2p socket"); exit(1); } // bind socket with p2p port if(bind(p2pSock, (struct sockaddr *)&p2pAddr, sizeof(p2pAddr)) < 0){ perror("bind socket"); exit(1); } // listen on the p2p port if(listen(p2pSock, MAX) < 0){ perror("listen on the port"); exit(1); } // connect to server if(connect(clieSock, (struct sockaddr *)&remoteAddr, sizeof(remoteAddr)) < 0){ perror("connect to server"); exit(1); } // create ssl struct clieSSL = SSL_new(ctx); // Assign the socket into the SSL structure SSL_set_fd(clieSSL, clieSock); // Perform SSL Handshake on the SSL client if(SSL_connect(clieSSL) == 1) { printf("ssl connected to server\n"); } // set sockets to non-block mode if (fcntl(clieSock, F_SETFL, O_NDELAY) < 0) { perror("error set non-block for client-server socket"); exit(1); } // get local file info list FileList masterList; Packet localFileListPacket, sendCmdPacket, recvPacket; localFileListPacket.type = 1; sendCmdPacket.type = 0; struct stat st; getFileList(&(localFileListPacket.fileList)); strcpy(localFileListPacket.fileList.owner, argv[1]); strcpy(sendCmdPacket.fileList.owner, argv[1]); int i; for(i = 0; i < localFileListPacket.fileList.num; i++) { stat(localFileListPacket.fileList.files[i].fileName, &st); localFileListPacket.fileList.files[i].fileSize = st.st_size; strcpy(localFileListPacket.fileList.files[i].fileOwner, argv[1]); strcpy(localFileListPacket.fileList.files[i].ownerIP, argv[2]); localFileListPacket.fileList.files[i].ownerPort = 9500 + (argv[1][0] - 'A'); } printFileList(&(localFileListPacket.fileList)); // upload file list to server int nbytes; nbytes = SSL_write(clieSSL, &localFileListPacket, sizeof(Packet)); if(nbytes < 0){ perror("init upload"); exit(1); } char command[128]; while(1) { printf("Input command: ls, get, exit\n"); while(!kbhit()) { // no user input, recv from server nbytes = SSL_read(clieSSL, &recvPacket, sizeof(Packet)); if (nbytes > 0) { if (recvPacket.type == 0) { if (strcmp(recvPacket.cmd, "Client existed")==0) { // client already existed, quit printf("Client %s already registered with server, exiting...\n", argv[1]); exit(1); } } else {// recv file list printf("Received master file list from server\n"); copyFileList(&(masterList), &(recvPacket.fileList)); printFileList(&(masterList)); } printf("input command: ls, get, exit\n"); } // try to accept on p2p listen socket peerSock = accept(p2pSock, NULL, sizeof(struct sockaddr_in)); if(peerSock > 0) { // create p2p ssl p2pSSL = SSL_new(ctx); // Assign the socket into the SSL structure SSL_set_fd(p2pSSL, peerSock); // Perform SSL Handshake on the client recv cmd nbytes = SSL_accept(p2pSSL); if(nbytes == 1) { printf("Accpeted connection from remote client via SSL\n"); } sleep(1); // connection established // peer-2-peer connection handling int rtn = 1, fsize, size_per_send; char fname[128]; DataPacket recvDataPacket, sendDataPacket; FILE *file; // try to receive from remote peer nbytes = SSL_read(p2pSSL, &recvDataPacket, sizeof(DataPacket)); if (nbytes > 0) { // check cmd field printf("Receive command '%s' from remote peer\n", recvDataPacket.cmd); if (strstr(recvDataPacket.cmd, "get")) { // parse file name char* sec_arg = strstr(recvDataPacket.cmd, " "); strcpy(fname, sec_arg+1); file = fopen(fname, "rb"); if (file == NULL) { printf("Failed open file %s.\n", fname); strcpy(sendDataPacket.cmd, "File Not Found"); // nbytes = send(peerSock, &sendDataPacket, sizeof(DataPacket), 0); nbytes = SSL_write(p2pSSL, &sendDataPacket, sizeof(DataPacket)); if (nbytes < 0) { perror("error send cmd File Not Found to remote peer"); } rtn = 0; } strcpy(sendDataPacket.cmd, "Sending"); // nbytes = send(peerSock, &sendDataPacket, sizeof(DataPacket), 0); nbytes = SSL_write(p2pSSL, &sendDataPacket, sizeof(DataPacket)); if (nbytes < 0) { perror("error send cmd Sending to remote peer"); } struct stat st; stat(fname, &st); fsize = st.st_size; int repeats = (int) (fsize/MAXBUFFSIZE) + 1; for (i = 0; i < repeats; i++) { size_per_send = (MAXBUFFSIZE) < (fsize-i*MAXBUFFSIZE) ? (MAXBUFFSIZE):(fsize-i*MAXBUFFSIZE); int readed = fread(sendDataPacket.payload, sizeof(char), size_per_send, file); sendDataPacket.size = readed; // nbytes = send(peerSock, &sendDataPacket, sizeof(DataPacket), 0); nbytes = SSL_write(p2pSSL, &sendDataPacket, sizeof(DataPacket)); if (nbytes < 0) { perror("error send file to remote peer"); } } fclose(file); printf("File sent\n"); // receive response from reomte peer nbytes = SSL_read(p2pSSL, &recvDataPacket, sizeof(DataPacket)); if (nbytes > 0) { if (strcmp(recvDataPacket.cmd, "File received")==0) { printf("Remote peer received file %s\n", fname); } } else { perror("error recv peer file received msg"); } } else { printf("Unexpected remote command: %s\n", recvDataPacket.cmd); rtn = 0; } } else { perror("error recv in handleRemotePeerConnection"); rtn = 0; } sleep(1); close(peerSock); printf("Input command: ls, get, exit\n"); } } gets(command); // ls command if(strcmp(command, "ls") == 0) { strcpy(sendCmdPacket.cmd, command); nbytes = SSL_write(clieSSL, &sendCmdPacket, sizeof(Packet)); if(nbytes < 0) { perror("send ls command"); } } if (strcmp(command, "exit") == 0) { // deregister with server strcpy(sendCmdPacket.cmd, command); nbytes = SSL_write(clieSSL, &sendCmdPacket, sizeof(Packet)); if (nbytes < 0) { perror("send exit command"); } else { printf("Client %s exiting...\n", argv[1]); exit(1); } } if (strstr(command, "get")) { connectRemotePeer(command, &masterList, argv[1], keyName, certName, CACert); } } return 0; }
bool CExtUpdate::readBackupList(const std::string & dstPath) { char buf[PATH_MAX]; static struct stat FileInfo; vector<std::string>::iterator it; f1 = fopen(backupList.c_str(), "r"); if (f1 == NULL) { f1 = fopen(backupList.c_str(), "w"); if (f1 != NULL) { char tmp1[1024]; snprintf(tmp1, sizeof(tmp1), "Log=%d\nLogFile=%s\n\n%s\n\n", fLogEnabled, fLogfile.c_str(), defaultBackup.c_str()); fwrite(tmp1, 1, strlen(tmp1), f1); fclose(f1); } else return ErrorReset(0, "cannot create missing backuplist file: " + backupList); } f1 = fopen(backupList.c_str(), "r"); if (f1 == NULL) return ErrorReset(0, "cannot read backuplist file: " + backupList); fpos_t fz; fseek(f1, 0, SEEK_END); fgetpos(f1, &fz); fseek(f1, 0, SEEK_SET); if (fz.__pos == 0) return ErrorReset(CLOSE_F1, "backuplist filesize is 0"); size_t pos; std::string line; // read blacklist and config vars copyList.clear(); blackList.clear(); deleteList.clear(); while(fgets(buf, sizeof(buf), f1) != NULL) { std::string tmpLine; line = buf; line = trim(line); // ignore comments if (line.find_first_of("#") == 0) { // config vars if (line.find_first_of(":") == 1) { if (line.length() > 1) readConfig(line); } continue; } pos = line.find_first_of("#"); if (pos != std::string::npos) { line = line.substr(0, pos); line = trim(line); } // find blackList entry if (line.find_first_of("-") == 0) { tmpLine = line.substr(1); if ((tmpLine.length() > 1) && (lstat(tmpLine.c_str(), &FileInfo) != -1)) { if (S_ISREG(FileInfo.st_mode)) blackList.push_back(tmpLine); } } // find deleteList entry else if (line.find_first_of("~") == 0) { tmpLine = line.substr(1); if (checkSpecialFolders(tmpLine, false)) continue; tmpLine = dstPath + tmpLine; if (line.length() > 2) deleteList.push_back(tmpLine); } // find copyList entry else { tmpLine = (line.find_first_of("+") == 0) ? line.substr(1) : line; // '+' add entry = default if (checkSpecialFolders(tmpLine, true)) continue; if (tmpLine.length() > 1) copyList.push_back(tmpLine); } } fclose(f1); // read DeleteList for(it = deleteList.begin(); it != deleteList.end(); ++it) { line = *it; if ((line.find("*") != std::string::npos) || (line.find("?") != std::string::npos)) { // Wildcards WRITE_UPDATE_LOG("delete file list: %s\n", line.c_str()); deleteFileList(line.c_str()); } else if (lstat(line.c_str(), &FileInfo) != -1) { if (S_ISREG(FileInfo.st_mode)) { // File WRITE_UPDATE_LOG("delete file: %s\n", line.c_str()); unlink(line.c_str()); } else if (S_ISDIR(FileInfo.st_mode)){ // Directory WRITE_UPDATE_LOG("delete directory: %s\n", line.c_str()); FileHelpers->removeDir(line.c_str()); } } } sync(); if (get_fs_usage(mountPkt.c_str(), total, used, &bsize)) free2 = (total * bsize) / 1024 - (used * bsize) / 1024; // read copyList for(it = copyList.begin(); it != copyList.end(); ++it) { line = *it; line = trim(line); // remove '/' from line end size_t len = line.length(); pos = line.find_last_of("/"); if (len == pos+1) line = line.substr(0, pos); std::string dst = dstPath + line; if ((line.find("*") != std::string::npos) || (line.find("?") != std::string::npos)) { // Wildcards DBG_MSG("Wildcards: %s\n", dst.c_str()); WRITE_UPDATE_LOG("\n"); WRITE_UPDATE_LOG("--------------------\n"); WRITE_UPDATE_LOG("Wildcards: %s\n", dst.c_str()); copyFileList(line, dstPath); } else { if (lstat(line.c_str(), &FileInfo) != -1) { if (S_ISREG(FileInfo.st_mode)) { // one file only pos = dst.find_last_of("/"); std::string dir = dst.substr(0, pos); FileHelpers->createDir(dir.c_str(), 0755); DBG_MSG("file: %s => %s\n", line.c_str(), dst.c_str()); WRITE_UPDATE_LOG("\n"); WRITE_UPDATE_LOG("file: %s => %s\n", line.c_str(), dst.c_str()); WRITE_UPDATE_LOG("--------------------\n"); std::string save = (isBlacklistEntry(line)) ? ".save" : ""; if (!FileHelpers->copyFile(line.c_str(), (dst + save).c_str(), FileInfo.st_mode & 0x0FFF)) return ErrorReset(0, "copyFile error"); } else if (S_ISDIR(FileInfo.st_mode)) { // directory DBG_MSG("directory: %s => %s\n", line.c_str(), dst.c_str()); WRITE_UPDATE_LOG("\n"); WRITE_UPDATE_LOG("directory: %s => %s\n", line.c_str(), dst.c_str()); WRITE_UPDATE_LOG("--------------------\n"); FileHelpers->copyDir(line.c_str(), dst.c_str(), true); } } } } sync(); if (get_fs_usage(mountPkt.c_str(), total, used, &bsize)) { uint64_t flashWarning = 1000; // 1MB uint64_t flashError = 600; // 600KB char buf1[1024]; total = (total * bsize) / 1024; free3 = total - (used * bsize) / 1024; printf("##### [%s] %llu KB free org, %llu KB free after delete, %llu KB free now\n", __FUNCTION__, free1, free2, free3); memset(buf1, '\0', sizeof(buf1)); if (free3 <= flashError) { snprintf(buf1, sizeof(buf1)-1, g_Locale->getText(LOCALE_FLASHUPDATE_UPDATE_WITH_SETTINGS_ERROR), free3, total); ShowMsg(LOCALE_MESSAGEBOX_ERROR, buf1, CMessageBox::mbrOk, CMessageBox::mbOk, NEUTRINO_ICON_ERROR); flashErrorFlag = true; return false; } else if (free3 <= flashWarning) { snprintf(buf1, sizeof(buf1)-1, g_Locale->getText(LOCALE_FLASHUPDATE_UPDATE_WITH_SETTINGS_WARNING), free3, total); if (ShowMsg(LOCALE_MESSAGEBOX_INFO, buf1, CMessageBox::mbrNo, CMessageBox::mbYes | CMessageBox::mbNo, NEUTRINO_ICON_INFO) != CMessageBox::mbrYes) { flashErrorFlag = true; return false; } } } return true; }