int CfSecOpenDirectory(ServerConnectionState *conn, char *sendbuffer, char *dirname) { Dir *dirh; const struct dirent *dirp; int offset, cipherlen; char out[CF_BUFSIZE]; if (!IsAbsoluteFileName(dirname)) { sprintf(sendbuffer, "BAD: request to access a non-absolute filename\n"); cipherlen = EncryptString(conn->encryption_type, sendbuffer, out, conn->session_key, strlen(sendbuffer) + 1); SendTransaction(&conn->conn_info, out, cipherlen, CF_DONE); return -1; } if ((dirh = DirOpen(dirname)) == NULL) { Log(LOG_LEVEL_VERBOSE, "Couldn't open dir %s", dirname); snprintf(sendbuffer, CF_BUFSIZE, "BAD: cfengine, couldn't open dir %s\n", dirname); cipherlen = EncryptString(conn->encryption_type, sendbuffer, out, conn->session_key, strlen(sendbuffer) + 1); SendTransaction(&conn->conn_info, out, cipherlen, CF_DONE); return -1; } /* Pack names for transmission */ memset(sendbuffer, 0, CF_BUFSIZE); offset = 0; for (dirp = DirRead(dirh); dirp != NULL; dirp = DirRead(dirh)) { if (strlen(dirp->d_name) + 1 + offset >= CF_BUFSIZE - CF_MAXLINKSIZE) { cipherlen = EncryptString(conn->encryption_type, sendbuffer, out, conn->session_key, offset + 1); SendTransaction(&conn->conn_info, out, cipherlen, CF_MORE); offset = 0; memset(sendbuffer, 0, CF_BUFSIZE); memset(out, 0, CF_BUFSIZE); } strncpy(sendbuffer + offset, dirp->d_name, CF_MAXLINKSIZE); /* + zero byte separator */ offset += strlen(dirp->d_name) + 1; } strcpy(sendbuffer + offset, CFD_TERMINATOR); cipherlen = EncryptString(conn->encryption_type, sendbuffer, out, conn->session_key, offset + 2 + strlen(CFD_TERMINATOR)); SendTransaction(&conn->conn_info, out, cipherlen, CF_DONE); DirClose(dirh); return 0; }
void GetServerLiteral(EvalContext *ctx, ServerConnectionState *conn, char *sendbuffer, char *recvbuffer, int encrypted) { char handle[CF_BUFSIZE], out[CF_BUFSIZE]; int cipherlen; sscanf(recvbuffer, "VAR %255[^\n]", handle); if (ReturnLiteralData(ctx, handle, out)) { memset(sendbuffer, 0, CF_BUFSIZE); snprintf(sendbuffer, CF_BUFSIZE - 1, "%s", out); } else { memset(sendbuffer, 0, CF_BUFSIZE); snprintf(sendbuffer, CF_BUFSIZE - 1, "BAD: Not found"); } if (encrypted) { cipherlen = EncryptString(conn->encryption_type, sendbuffer, out, conn->session_key, strlen(sendbuffer) + 1); SendTransaction(&conn->conn_info, out, cipherlen, CF_DONE); } else { SendTransaction(&conn->conn_info, sendbuffer, 0, CF_DONE); } }
void ReplyServerContext(ServerConnectionState *conn, int encrypted, Item *classes) { char out[CF_BUFSIZE]; int cipherlen; Item *ip; char sendbuffer[CF_BUFSIZE]; memset(sendbuffer, 0, CF_BUFSIZE); for (ip = classes; ip != NULL; ip = ip->next) { if (strlen(sendbuffer) + strlen(ip->name) < CF_BUFSIZE - 3) { strcat(sendbuffer, ip->name); strcat(sendbuffer, ","); } else { Log(LOG_LEVEL_ERR, "Overflow in context grab"); break; } } DeleteItemList(classes); if (encrypted) { cipherlen = EncryptString(conn->encryption_type, sendbuffer, out, conn->session_key, strlen(sendbuffer) + 1); SendTransaction(&conn->conn_info, out, cipherlen, CF_DONE); } else { SendTransaction(&conn->conn_info, sendbuffer, 0, CF_DONE); } }
static void test_symmetric_encrypt(void) { char ciphertext[CF_BUFSIZE]; int plaintext_len = strlen(PLAINTEXT) + 1; int ciphertext_len = EncryptString(CIPHER_TYPE_CFENGINE, PLAINTEXT, ciphertext, KEY, plaintext_len); assert_int_equal(ciphertext_len, ComputeCiphertextLen(plaintext_len, CIPHER_BLOCK_SIZE_BYTES)); assert_memory_equal(ciphertext, CIPHERTEXT_PRECOMPUTED, ciphertext_len); }
void CIRC::CheckAuth(char *szUsername, char *szMessage, char *szDnsIP) { //check input data from client for a auth request char szTemp[MSG_SIZE]=""; strcpy(szTemp, szUsername); strcat(szTemp, szDnsIP); strcpy(szTemp, EncryptString(szTemp, 4, 2)); if(strcmp(szTemp, szMessage)==0) { //client auth successfull, register this user AddAuthedUser(szUsername, szDnsIP); } return; }
bool CSettings::Save() { if (!FindConfig()) return false; char filedest[300]; snprintf(filedest, sizeof(filedest), "%sGXGlobal.cfg", ConfigPath); if(!CreateSubfolder(ConfigPath)) return false; FILE * file = fopen(filedest, "w"); if (!file) return false; fprintf(file, "# USB Loader GX R%s - Main settings file\n", GetRev()); fprintf(file, "# Note: This file is automatically generated\n"); fprintf(file, "godmode = %d\n", godmode); fprintf(file, "videomode = %d\n", videomode); fprintf(file, "videopatch = %d\n", videopatch); fprintf(file, "videoPatchDol = %d\n", videoPatchDol); fprintf(file, "language = %d\n", language); fprintf(file, "ocarina = %d\n", ocarina); fprintf(file, "hddinfo = %d\n", hddinfo); fprintf(file, "sinfo = %d\n", sinfo); fprintf(file, "rumble = %d\n", rumble); fprintf(file, "volume = %d\n", volume); fprintf(file, "sfxvolume = %d\n", sfxvolume); fprintf(file, "gamesoundvolume = %d\n", gamesoundvolume); fprintf(file, "tooltips = %d\n", tooltips); fprintf(file, "RememberUnlock = %d\n", RememberUnlock); char EncryptedTxt[50]; EncryptString(unlockCode, EncryptedTxt); fprintf(file, "password = %s\n", EncryptedTxt); fprintf(file, "GameSort = %d\n", GameSort); fprintf(file, "LoaderIOS = %d\n", LoaderIOS); fprintf(file, "cios = %d\n", cios); fprintf(file, "keyset = %d\n", keyset); fprintf(file, "xflip = %d\n", xflip); fprintf(file, "gridRows = %d\n", gridRows); fprintf(file, "quickboot = %d\n", quickboot); fprintf(file, "wsprompt = %d\n", wsprompt); fprintf(file, "parentalcontrol = %d\n", parentalcontrol); fprintf(file, "covers_path = %s\n", covers_path); fprintf(file, "covers2d_path = %s\n", covers2d_path); fprintf(file, "coversFull_path = %s\n", coversFull_path); fprintf(file, "theme_path = %s\n", theme_path); fprintf(file, "theme = %s\n", theme); fprintf(file, "disc_path = %s\n", disc_path); fprintf(file, "language_path = %s\n", language_path); fprintf(file, "languagefiles_path = %s\n", languagefiles_path); fprintf(file, "TxtCheatcodespath = %s\n", TxtCheatcodespath); fprintf(file, "titlestxt_path = %s\n", titlestxt_path); fprintf(file, "gamesound = %d\n", gamesound); fprintf(file, "dolpath = %s\n", dolpath); fprintf(file, "ogg_path = %s\n", ogg_path); fprintf(file, "wiilight = %d\n", wiilight); fprintf(file, "gameDisplay = %d\n", gameDisplay); fprintf(file, "update_path = %s\n", update_path); fprintf(file, "homebrewapps_path = %s\n", homebrewapps_path); fprintf(file, "BNRCachePath = %s\n", BNRCachePath); fprintf(file, "Cheatcodespath = %s\n", Cheatcodespath); fprintf(file, "BcaCodepath = %s\n", BcaCodepath); fprintf(file, "WipCodepath = %s\n", WipCodepath); fprintf(file, "WDMpath = %s\n", WDMpath); fprintf(file, "titlesOverride = %d\n", titlesOverride); fprintf(file, "ForceDiscTitles = %d\n", ForceDiscTitles); fprintf(file, "patchcountrystrings = %d\n", patchcountrystrings); fprintf(file, "screensaver = %d\n", screensaver); fprintf(file, "musicloopmode = %d\n", musicloopmode); fprintf(file, "autonetwork = %d\n", autonetwork); fprintf(file, "discart = %d\n", discart); fprintf(file, "coversfull = %d\n", coversfull); fprintf(file, "partition = %d\n", partition); fprintf(file, "marknewtitles = %d\n", marknewtitles); fprintf(file, "ShowFreeSpace = %d\n", ShowFreeSpace); fprintf(file, "InstallToDir = %d\n", InstallToDir); fprintf(file, "GameSplit = %d\n", GameSplit); fprintf(file, "InstallPartitions = %08X\n", InstallPartitions); fprintf(file, "PlaylogUpdate = %d\n", PlaylogUpdate); fprintf(file, "ParentalBlocks = %08X\n", ParentalBlocks); fprintf(file, "returnTo = %s\n", returnTo); fprintf(file, "HomeMenu = %d\n", HomeMenu); fprintf(file, "MultiplePartitions = %d\n", MultiplePartitions); fprintf(file, "USBPort = %d\n", USBPort); fprintf(file, "USBAutoMount = %d\n", USBAutoMount); fprintf(file, "CacheTitles = %d\n", CacheTitles); fprintf(file, "BlockIOSReload = %d\n", BlockIOSReload); fprintf(file, "WSFactor = %0.3f\n", WSFactor); fprintf(file, "FontScaleFactor = %0.3f\n", FontScaleFactor); fprintf(file, "ClockFontScaleFactor = %0.3f\n", ClockFontScaleFactor); fprintf(file, "EnabledCategories = "); for(u32 i = 0; i < EnabledCategories.size(); ++i) { fprintf(file, "%i", EnabledCategories[i]); if(i+1 < EnabledCategories.size()) fprintf(file, ","); } fprintf(file, "\n"); fprintf(file, "RequiredCategories = "); for(u32 i = 0; i < RequiredCategories.size(); ++i) { fprintf(file, "%i", RequiredCategories[i]); if(i+1 < RequiredCategories.size()) fprintf(file, ","); } fprintf(file, "\n"); fprintf(file, "ForbiddenCategories = "); for(u32 i = 0; i < ForbiddenCategories.size(); ++i) { fprintf(file, "%i", ForbiddenCategories[i]); if(i+1 < ForbiddenCategories.size()) fprintf(file, ","); } fprintf(file, "\n"); fprintf(file, "Wiinnertag = %d\n", Wiinnertag); fprintf(file, "WiinnertagPath = %s\n", WiinnertagPath); fprintf(file, "SelectedGame = %d\n", SelectedGame); fprintf(file, "GameListOffset = %d\n", GameListOffset); fprintf(file, "sneekVideoPatch = %d\n", sneekVideoPatch); fprintf(file, "NandEmuMode = %d\n", NandEmuMode); fprintf(file, "NandEmuChanMode = %d\n", NandEmuChanMode); fprintf(file, "NandEmuPath = %s\n", NandEmuPath); fprintf(file, "NandEmuChanPath = %s\n", NandEmuChanPath); fprintf(file, "UseSystemFont = %d\n", UseSystemFont); fprintf(file, "Hooktype = %d\n", Hooktype); fprintf(file, "WiirdDebugger = %d\n", WiirdDebugger); fprintf(file, "WiirdDebuggerPause = %d\n", WiirdDebuggerPause); fprintf(file, "ShowPlayCount = %d\n", ShowPlayCount); fprintf(file, "LoaderMode = %d\n", LoaderMode); fprintf(file, "SearchMode = %d\n", SearchMode); fprintf(file, "GameAspectRatio = %d\n", GameAspectRatio); fprintf(file, "PointerSpeed = %g\n", PointerSpeed); fprintf(file, "UseChanLauncher = %d\n", UseChanLauncher); fprintf(file, "AdjustOverscanX = %d\n", AdjustOverscanX); fprintf(file, "AdjustOverscanY = %d\n", AdjustOverscanY); fprintf(file, "TooltipDelay = %d\n", TooltipDelay); fprintf(file, "GameWindowMode = %d\n", GameWindowMode); fprintf(file, "CacheBNRFiles = %d\n", CacheBNRFiles); fprintf(file, "BannerAnimStart = %d\n", BannerAnimStart); fprintf(file, "BannerGridSpeed = %g\n", BannerGridSpeed); fprintf(file, "BannerZoomDuration = %d\n", BannerZoomDuration); fprintf(file, "BannerProjectionOffsetX = %g\n", BannerProjectionOffsetX); fprintf(file, "BannerProjectionOffsetY = %g\n", BannerProjectionOffsetY); fprintf(file, "BannerProjectionWidth = %g\n", BannerProjectionWidth); fprintf(file, "BannerProjectionHeight = %g\n", BannerProjectionHeight); fprintf(file, "GCBannerScale = %g\n", GCBannerScale); fprintf(file, "GameCubePath = %s\n", GameCubePath); fprintf(file, "GameCubeSDPath = %s\n", GameCubeSDPath); fprintf(file, "GameCubeMode = %d\n", GameCubeMode); fprintf(file, "GameCubeSource = %d\n", GameCubeSource); fprintf(file, "MultiDiscPrompt = %d\n", MultiDiscPrompt); fprintf(file, "DMLVideo = %d\n", DMLVideo); fprintf(file, "DMLProgPatch = %d\n", DMLProgPatch); fprintf(file, "DMLNMM = %d\n", DMLNMM); fprintf(file, "DMLActivityLED = %d\n", DMLActivityLED); fprintf(file, "DMLPADHOOK = %d\n", DMLPADHOOK); fprintf(file, "DMLNoDisc2 = %d\n", DMLNoDisc2); fprintf(file, "DMLWidescreen = %d\n", DMLWidescreen); fprintf(file, "DMLScreenshot = %d\n", DMLScreenshot); fprintf(file, "DMLJPNPatch = %d\n", DMLJPNPatch); fprintf(file, "DMLDebug = %d\n", DMLDebug); fprintf(file, "NINDeflicker = %d\n", NINDeflicker); fprintf(file, "NINPal50Patch = %d\n", NINPal50Patch); fprintf(file, "NINWiiUWide = %d\n", NINWiiUWide); fprintf(file, "NINVideoScale = %d\n", NINVideoScale); fprintf(file, "NINVideoOffset = %d\n", NINVideoOffset); fprintf(file, "NINRemlimit = %d\n", NINRemlimit); fprintf(file, "NINMCEmulation = %d\n", NINMCEmulation); fprintf(file, "NINMCSize = %d\n", NINMCSize); fprintf(file, "NINAutoboot = %d\n", NINAutoboot); fprintf(file, "NINSettings = %d\n", NINSettings); fprintf(file, "NINUSBHID = %d\n", NINUSBHID); fprintf(file, "NINMaxPads = %d\n", NINMaxPads); fprintf(file, "NINNativeSI = %d\n", NINNativeSI); fprintf(file, "NINOSReport = %d\n", NINOSReport); fprintf(file, "NINLED = %d\n", NINLED); fprintf(file, "NINLog = %d\n", NINLog); fprintf(file, "DEVOMCEmulation = %d\n", DEVOMCEmulation); fprintf(file, "DEVOWidescreen = %d\n", DEVOWidescreen); fprintf(file, "DEVOActivityLED = %d\n", DEVOActivityLED); fprintf(file, "DEVOFZeroAX = %d\n", DEVOFZeroAX); fprintf(file, "DEVOTimerFix = %d\n", DEVOTimerFix); fprintf(file, "DEVODButtons = %d\n", DEVODButtons); fprintf(file, "DEVOCropOverscan = %d\n", DEVOCropOverscan); fprintf(file, "DEVODiscDelay = %d\n", DEVODiscDelay); fprintf(file, "DEVOLoaderPath = %s\n", DEVOLoaderPath); fprintf(file, "NINLoaderPath = %s\n", NINLoaderPath); fprintf(file, "GCInstallCompressed = %d\n", GCInstallCompressed); fprintf(file, "GCInstallAligned = %d\n", GCInstallAligned); fprintf(file, "PrivateServer = %d\n", PrivateServer); fprintf(file, "CustomBannersURL = %s\n", CustomBannersURL); fclose(file); return true; }
/** * @param #stattype should be either "link" or "file". If a link, this reads * readlink and sends it back in the same packet. It then * caches the value for each copy command. * */ int cf_remote_stat(AgentConnection *conn, bool encrypt, const char *file, struct stat *statbuf, const char *stattype) { assert(strcmp(stattype, "file") == 0 || strcmp(stattype, "link") == 0); /* We encrypt only for CLASSIC protocol. The TLS protocol is always over * encrypted layer, so it does not support encrypted (S*) commands. */ encrypt = encrypt && conn->conn_info->protocol == CF_PROTOCOL_CLASSIC; if (strlen(file) > CF_BUFSIZE - 30) { Log(LOG_LEVEL_ERR, "Filename too long"); return -1; } int ret = StatFromCache(conn, file, statbuf, stattype); if (ret == 0 || ret == -1) /* found or error */ { return ret; } /* Not found in cache */ char recvbuffer[CF_BUFSIZE]; memset(recvbuffer, 0, CF_BUFSIZE); time_t tloc = time(NULL); if (tloc == (time_t) -1) { Log(LOG_LEVEL_ERR, "Couldn't read system clock (time: %s)", GetErrorStr()); tloc = 0; } char sendbuffer[CF_BUFSIZE]; int tosend; sendbuffer[0] = '\0'; if (encrypt) { if (conn->session_key == NULL) { Log(LOG_LEVEL_ERR, "Cannot do encrypted copy without keys (use cf-key)"); return -1; } char in[CF_BUFSIZE], out[CF_BUFSIZE]; snprintf(in, CF_BUFSIZE - 1, "SYNCH %jd STAT %s", (intmax_t) tloc, file); int cipherlen = EncryptString(out, sizeof(out), in, strlen(in) + 1, conn->encryption_type, conn->session_key); tosend = cipherlen + CF_PROTO_OFFSET; if(tosend > sizeof(sendbuffer)) { ProgrammingError("cf_remote_stat: tosend (%d) > sendbuffer (%ld)", tosend, sizeof(sendbuffer)); } snprintf(sendbuffer, CF_BUFSIZE - 1, "SSYNCH %d", cipherlen); memcpy(sendbuffer + CF_PROTO_OFFSET, out, cipherlen); } else { snprintf(sendbuffer, CF_BUFSIZE, "SYNCH %jd STAT %s", (intmax_t) tloc, file); tosend = strlen(sendbuffer); } if (SendTransaction(conn->conn_info, sendbuffer, tosend, CF_DONE) == -1) { Log(LOG_LEVEL_INFO, "Transmission failed/refused talking to %.255s:%.255s. (stat: %s)", conn->this_server, file, GetErrorStr()); return -1; } if (ReceiveTransaction(conn->conn_info, recvbuffer, NULL) == -1) { /* TODO mark connection in the cache as closed. */ return -1; } if (strstr(recvbuffer, "unsynchronized")) { Log(LOG_LEVEL_ERR, "Clocks differ too much to do copy by date (security), server reported: %s", recvbuffer + strlen("BAD: ")); return -1; } if (BadProtoReply(recvbuffer)) { Log(LOG_LEVEL_VERBOSE, "Server returned error: %s", recvbuffer + strlen("BAD: ")); errno = EPERM; return -1; } if (OKProtoReply(recvbuffer)) { Stat cfst; // use intmax_t here to provide enough space for large values coming over the protocol intmax_t d1, d2, d3, d4, d5, d6, d7, d8, d9, d10, d11, d12 = 0, d13 = 0; ret = sscanf(recvbuffer, "OK: " "%1" PRIdMAX // 01 cfst.cf_type " %5" PRIdMAX // 02 cfst.cf_mode " %14" PRIdMAX // 03 cfst.cf_lmode " %14" PRIdMAX // 04 cfst.cf_uid " %14" PRIdMAX // 05 cfst.cf_gid " %18" PRIdMAX // 06 cfst.cf_size " %14" PRIdMAX // 07 cfst.cf_atime " %14" PRIdMAX // 08 cfst.cf_mtime " %14" PRIdMAX // 09 cfst.cf_ctime " %1" PRIdMAX // 10 cfst.cf_makeholes " %14" PRIdMAX // 11 cfst.cf_ino " %14" PRIdMAX // 12 cfst.cf_nlink " %18" PRIdMAX, // 13 cfst.cf_dev &d1, &d2, &d3, &d4, &d5, &d6, &d7, &d8, &d9, &d10, &d11, &d12, &d13); if (ret < 13) { Log(LOG_LEVEL_ERR, "Cannot read SYNCH reply from '%s', only %d/13 items parsed", conn->remoteip, ret ); return -1; } cfst.cf_type = (FileType) d1; cfst.cf_mode = (mode_t) d2; cfst.cf_lmode = (mode_t) d3; cfst.cf_uid = (uid_t) d4; cfst.cf_gid = (gid_t) d5; cfst.cf_size = (off_t) d6; cfst.cf_atime = (time_t) d7; cfst.cf_mtime = (time_t) d8; cfst.cf_ctime = (time_t) d9; cfst.cf_makeholes = (char) d10; cfst.cf_ino = d11; cfst.cf_nlink = d12; cfst.cf_dev = (dev_t)d13; /* Use %?d here to avoid memory overflow attacks */ memset(recvbuffer, 0, CF_BUFSIZE); if (ReceiveTransaction(conn->conn_info, recvbuffer, NULL) == -1) { /* TODO mark connection in the cache as closed. */ return -1; } if (strlen(recvbuffer) > 3) { cfst.cf_readlink = xstrdup(recvbuffer + 3); } else { cfst.cf_readlink = NULL; } switch (cfst.cf_type) { case FILE_TYPE_REGULAR: cfst.cf_mode |= (mode_t) S_IFREG; break; case FILE_TYPE_DIR: cfst.cf_mode |= (mode_t) S_IFDIR; break; case FILE_TYPE_CHAR_: cfst.cf_mode |= (mode_t) S_IFCHR; break; case FILE_TYPE_FIFO: cfst.cf_mode |= (mode_t) S_IFIFO; break; case FILE_TYPE_SOCK: cfst.cf_mode |= (mode_t) S_IFSOCK; break; case FILE_TYPE_BLOCK: cfst.cf_mode |= (mode_t) S_IFBLK; break; case FILE_TYPE_LINK: cfst.cf_mode |= (mode_t) S_IFLNK; break; } cfst.cf_filename = xstrdup(file); cfst.cf_server = xstrdup(conn->this_server); cfst.cf_failed = false; if (cfst.cf_lmode != 0) { cfst.cf_lmode |= (mode_t) S_IFLNK; } NewStatCache(&cfst, conn); if ((cfst.cf_lmode != 0) && (strcmp(stattype, "link") == 0)) { statbuf->st_mode = cfst.cf_lmode; } else { statbuf->st_mode = cfst.cf_mode; } statbuf->st_uid = cfst.cf_uid; statbuf->st_gid = cfst.cf_gid; statbuf->st_size = cfst.cf_size; statbuf->st_mtime = cfst.cf_mtime; statbuf->st_ctime = cfst.cf_ctime; statbuf->st_atime = cfst.cf_atime; statbuf->st_ino = cfst.cf_ino; statbuf->st_dev = cfst.cf_dev; statbuf->st_nlink = cfst.cf_nlink; return 0; } Log(LOG_LEVEL_ERR, "Transmission refused or failed statting '%s', got '%s'", file, recvbuffer); errno = EPERM; return -1; }
int CompareHashNet(char *file1, char *file2, bool encrypt, AgentConnection *conn) { static unsigned char d[EVP_MAX_MD_SIZE + 1]; char *sp, sendbuffer[CF_BUFSIZE], recvbuffer[CF_BUFSIZE], in[CF_BUFSIZE], out[CF_BUFSIZE]; int i, tosend, cipherlen; HashFile(file2, d, CF_DEFAULT_DIGEST); memset(recvbuffer, 0, CF_BUFSIZE); if (encrypt) { snprintf(in, CF_BUFSIZE, "MD5 %s", file1); sp = in + strlen(in) + CF_SMALL_OFFSET; for (i = 0; i < CF_DEFAULT_DIGEST_LEN; i++) { *sp++ = d[i]; } cipherlen = EncryptString(conn->encryption_type, in, out, conn->session_key, strlen(in) + CF_SMALL_OFFSET + CF_DEFAULT_DIGEST_LEN); snprintf(sendbuffer, CF_BUFSIZE, "SMD5 %d", cipherlen); memcpy(sendbuffer + CF_PROTO_OFFSET, out, cipherlen); tosend = cipherlen + CF_PROTO_OFFSET; } else { snprintf(sendbuffer, CF_BUFSIZE, "MD5 %s", file1); sp = sendbuffer + strlen(sendbuffer) + CF_SMALL_OFFSET; for (i = 0; i < CF_DEFAULT_DIGEST_LEN; i++) { *sp++ = d[i]; } tosend = strlen(sendbuffer) + CF_SMALL_OFFSET + CF_DEFAULT_DIGEST_LEN; } if (SendTransaction(conn->sd, sendbuffer, tosend, CF_DONE) == -1) { Log(LOG_LEVEL_ERR, "Failed send. (SendTransaction: %s)", GetErrorStr()); return false; } if (ReceiveTransaction(conn->sd, recvbuffer, NULL) == -1) { Log(LOG_LEVEL_ERR, "Failed receive. (ReceiveTransaction: %s)", GetErrorStr()); Log(LOG_LEVEL_VERBOSE, "No answer from host, assuming checksum ok to avoid remote copy for now..."); return false; } if (strcmp(CFD_TRUE, recvbuffer) == 0) { return true; /* mismatch */ } else { return false; } /* Not reached */ }
Item *RemoteDirList(const char *dirname, bool encrypt, AgentConnection *conn) { char sendbuffer[CF_BUFSIZE]; char recvbuffer[CF_BUFSIZE]; char in[CF_BUFSIZE]; char out[CF_BUFSIZE]; int n, cipherlen = 0, tosend; char *sp; Item *files = NULL; Item *ret = NULL; if (strlen(dirname) > CF_BUFSIZE - 20) { Log(LOG_LEVEL_ERR, "Directory name too long"); return NULL; } if (encrypt) { if (conn->session_key == NULL) { Log(LOG_LEVEL_ERR, "Cannot do encrypted copy without keys (use cf-key)"); return NULL; } snprintf(in, CF_BUFSIZE, "OPENDIR %s", dirname); cipherlen = EncryptString(conn->encryption_type, in, out, conn->session_key, strlen(in) + 1); snprintf(sendbuffer, CF_BUFSIZE - 1, "SOPENDIR %d", cipherlen); memcpy(sendbuffer + CF_PROTO_OFFSET, out, cipherlen); tosend = cipherlen + CF_PROTO_OFFSET; } else { snprintf(sendbuffer, CF_BUFSIZE, "OPENDIR %s", dirname); tosend = strlen(sendbuffer); } if (SendTransaction(conn->sd, sendbuffer, tosend, CF_DONE) == -1) { return NULL; } while (true) { if ((n = ReceiveTransaction(conn->sd, recvbuffer, NULL)) == -1) { return NULL; } if (n == 0) { break; } if (encrypt) { memcpy(in, recvbuffer, n); DecryptString(conn->encryption_type, in, recvbuffer, conn->session_key, n); } if (FailedProtoReply(recvbuffer)) { Log(LOG_LEVEL_INFO, "Network access to '%s:%s' denied", conn->this_server, dirname); return NULL; } if (BadProtoReply(recvbuffer)) { Log(LOG_LEVEL_INFO, "%s", recvbuffer + 4); return NULL; } for (sp = recvbuffer; *sp != '\0'; sp++) { Item *ip; if (strncmp(sp, CFD_TERMINATOR, strlen(CFD_TERMINATOR)) == 0) /* End transmission */ { return ret; } ip = xcalloc(1, sizeof(Item)); ip->name = (char *) AllocateDirentForFilename(sp); if (files == NULL) /* First element */ { ret = ip; files = ip; } else { files->next = ip; files = ip; } while (*sp != '\0') { sp++; } } } return ret; }
int cf_remote_stat(char *file, struct stat *buf, char *stattype, bool encrypt, AgentConnection *conn) /* If a link, this reads readlink and sends it back in the same package. It then caches the value for each copy command */ { char sendbuffer[CF_BUFSIZE]; char recvbuffer[CF_BUFSIZE]; char in[CF_BUFSIZE], out[CF_BUFSIZE]; int ret, tosend, cipherlen; time_t tloc; memset(recvbuffer, 0, CF_BUFSIZE); if (strlen(file) > CF_BUFSIZE - 30) { Log(LOG_LEVEL_ERR, "Filename too long"); return -1; } ret = CacheStat(file, buf, stattype, conn); if (ret != 0) { return ret; } if ((tloc = time((time_t *) NULL)) == -1) { Log(LOG_LEVEL_ERR, "Couldn't read system clock"); } sendbuffer[0] = '\0'; if (encrypt) { if (conn->session_key == NULL) { Log(LOG_LEVEL_ERR, "Cannot do encrypted copy without keys (use cf-key)"); return -1; } snprintf(in, CF_BUFSIZE - 1, "SYNCH %jd STAT %s", (intmax_t) tloc, file); cipherlen = EncryptString(conn->encryption_type, in, out, conn->session_key, strlen(in) + 1); snprintf(sendbuffer, CF_BUFSIZE - 1, "SSYNCH %d", cipherlen); memcpy(sendbuffer + CF_PROTO_OFFSET, out, cipherlen); tosend = cipherlen + CF_PROTO_OFFSET; } else { snprintf(sendbuffer, CF_BUFSIZE, "SYNCH %jd STAT %s", (intmax_t) tloc, file); tosend = strlen(sendbuffer); } if (SendTransaction(conn->sd, sendbuffer, tosend, CF_DONE) == -1) { Log(LOG_LEVEL_INFO, "Transmission failed/refused talking to %.255s:%.255s. (stat: %s)", conn->this_server, file, GetErrorStr()); return -1; } if (ReceiveTransaction(conn->sd, recvbuffer, NULL) == -1) { return -1; } if (strstr(recvbuffer, "unsynchronized")) { Log(LOG_LEVEL_ERR, "Clocks differ too much to do copy by date (security) '%s'", recvbuffer + 4); return -1; } if (BadProtoReply(recvbuffer)) { Log(LOG_LEVEL_VERBOSE, "Server returned error '%s'", recvbuffer + 4); errno = EPERM; return -1; } if (OKProtoReply(recvbuffer)) { Stat cfst; // use intmax_t here to provide enough space for large values coming over the protocol intmax_t d1, d2, d3, d4, d5, d6, d7, d8, d9, d10, d11, d12 = 0, d13 = 0; ret = sscanf(recvbuffer, "OK: " "%1" PRIdMAX // 01 cfst.cf_type " %5" PRIdMAX // 02 cfst.cf_mode " %14" PRIdMAX // 03 cfst.cf_lmode " %14" PRIdMAX // 04 cfst.cf_uid " %14" PRIdMAX // 05 cfst.cf_gid " %18" PRIdMAX // 06 cfst.cf_size " %14" PRIdMAX // 07 cfst.cf_atime " %14" PRIdMAX // 08 cfst.cf_mtime " %14" PRIdMAX // 09 cfst.cf_ctime " %1" PRIdMAX // 10 cfst.cf_makeholes " %14" PRIdMAX // 11 cfst.cf_ino " %14" PRIdMAX // 12 cfst.cf_nlink " %18" PRIdMAX, // 13 cfst.cf_dev &d1, &d2, &d3, &d4, &d5, &d6, &d7, &d8, &d9, &d10, &d11, &d12, &d13); if (ret < 13) { Log(LOG_LEVEL_ERR, "Cannot read SYNCH reply from '%s', only %d/13 items parsed", conn->remoteip, ret ); return -1; } cfst.cf_type = (FileType) d1; cfst.cf_mode = (mode_t) d2; cfst.cf_lmode = (mode_t) d3; cfst.cf_uid = (uid_t) d4; cfst.cf_gid = (gid_t) d5; cfst.cf_size = (off_t) d6; cfst.cf_atime = (time_t) d7; cfst.cf_mtime = (time_t) d8; cfst.cf_ctime = (time_t) d9; cfst.cf_makeholes = (char) d10; cfst.cf_ino = d11; cfst.cf_nlink = d12; cfst.cf_dev = (dev_t)d13; /* Use %?d here to avoid memory overflow attacks */ memset(recvbuffer, 0, CF_BUFSIZE); if (ReceiveTransaction(conn->sd, recvbuffer, NULL) == -1) { return -1; } if (strlen(recvbuffer) > 3) { cfst.cf_readlink = xstrdup(recvbuffer + 3); } else { cfst.cf_readlink = NULL; } switch (cfst.cf_type) { case FILE_TYPE_REGULAR: cfst.cf_mode |= (mode_t) S_IFREG; break; case FILE_TYPE_DIR: cfst.cf_mode |= (mode_t) S_IFDIR; break; case FILE_TYPE_CHAR_: cfst.cf_mode |= (mode_t) S_IFCHR; break; case FILE_TYPE_FIFO: cfst.cf_mode |= (mode_t) S_IFIFO; break; case FILE_TYPE_SOCK: cfst.cf_mode |= (mode_t) S_IFSOCK; break; case FILE_TYPE_BLOCK: cfst.cf_mode |= (mode_t) S_IFBLK; break; case FILE_TYPE_LINK: cfst.cf_mode |= (mode_t) S_IFLNK; break; } cfst.cf_filename = xstrdup(file); cfst.cf_server = xstrdup(conn->this_server); cfst.cf_failed = false; if (cfst.cf_lmode != 0) { cfst.cf_lmode |= (mode_t) S_IFLNK; } NewClientCache(&cfst, conn); if ((cfst.cf_lmode != 0) && (strcmp(stattype, "link") == 0)) { buf->st_mode = cfst.cf_lmode; } else { buf->st_mode = cfst.cf_mode; } buf->st_uid = cfst.cf_uid; buf->st_gid = cfst.cf_gid; buf->st_size = cfst.cf_size; buf->st_mtime = cfst.cf_mtime; buf->st_ctime = cfst.cf_ctime; buf->st_atime = cfst.cf_atime; buf->st_ino = cfst.cf_ino; buf->st_dev = cfst.cf_dev; buf->st_nlink = cfst.cf_nlink; return 0; } Log(LOG_LEVEL_ERR, "Transmission refused or failed statting '%s', got '%s'", file, recvbuffer); errno = EPERM; return -1; }
int main(int argc, char *argv[]) #endif { #ifdef _CRTDBG_LEAK_CHECK_DF // Turn on leak-checking int tempflag = _CrtSetDbgFlag( _CRTDBG_REPORT_FLAG ); tempflag |= _CRTDBG_LEAK_CHECK_DF; _CrtSetDbgFlag( tempflag ); #endif #if defined(__MWERKS__) && defined(macintosh) argc = ccommand(&argv); #endif try { std::string command, executableName, edcFilename; if (argc < 2) command = 'h'; else command = argv[1]; if (FIPS_140_2_ComplianceEnabled()) { edcFilename = "edc.dat"; #ifdef CRYPTOPP_WIN32_AVAILABLE TCHAR filename[MAX_PATH]; GetModuleFileName(GetModuleHandle(NULL), filename, sizeof(filename)); executableName = filename; std::string::size_type pos = executableName.rfind('\\'); if (pos != std::string::npos) edcFilename = executableName.substr(0, pos+1) + edcFilename; #else executableName = argv[0]; #endif if (command.substr(0, 4) != "fips") { byte expectedModuleDigest[SHA1::DIGESTSIZE]; FileSource(edcFilename.c_str(), true, new HexDecoder(new ArraySink(expectedModuleDigest, sizeof(expectedModuleDigest)))); DoPowerUpSelfTest(executableName.c_str(), expectedModuleDigest); } } switch (command[0]) { case 'g': { char seed[1024], privFilename[128], pubFilename[128]; unsigned int keyLength; cout << "Key length in bits: "; cin >> keyLength; cout << "\nSave private key to file: "; cin >> privFilename; cout << "\nSave public key to file: "; cin >> pubFilename; cout << "\nRandom Seed: "; ws(cin); cin.getline(seed, 1024); GenerateRSAKey(keyLength, privFilename, pubFilename, seed); return 0; } case 'r': { switch (argv[1][1]) { case 's': RSASignFile(argv[2], argv[3], argv[4]); return 0; case 'v': { bool verified = RSAVerifyFile(argv[2], argv[3], argv[4]); cout << (verified ? "valid signature" : "invalid signature") << endl; return 0; } default: { char privFilename[128], pubFilename[128]; char seed[1024], message[1024]; cout << "Private key file: "; cin >> privFilename; cout << "\nPublic key file: "; cin >> pubFilename; cout << "\nRandom Seed: "; ws(cin); cin.getline(seed, 1024); cout << "\nMessage: "; cin.getline(message, 1024); string ciphertext = RSAEncryptString(pubFilename, seed, message); cout << "\nCiphertext: " << ciphertext << endl; string decrypted = RSADecryptString(privFilename, ciphertext.c_str()); cout << "\nDecrypted: " << decrypted << endl; return 0; } } } case 'm': DigestFile(argv[2]); return 0; case 't': { if (command == "tv") { return !RunTestDataFile(argv[2]); } // VC60 workaround: use char array instead of std::string to workaround MSVC's getline bug char passPhrase[MAX_PHRASE_LENGTH], plaintext[1024]; cout << "Passphrase: "; cin.getline(passPhrase, MAX_PHRASE_LENGTH); cout << "\nPlaintext: "; cin.getline(plaintext, 1024); string ciphertext = EncryptString(plaintext, passPhrase); cout << "\nCiphertext: " << ciphertext << endl; string decrypted = DecryptString(ciphertext.c_str(), passPhrase); cout << "\nDecrypted: " << decrypted << endl; return 0; } case 'e': case 'd': if (command == "e64") Base64Encode(argv[2], argv[3]); else if (command == "d64") Base64Decode(argv[2], argv[3]); else if (command == "e16") HexEncode(argv[2], argv[3]); else if (command == "d16") HexDecode(argv[2], argv[3]); else { char passPhrase[MAX_PHRASE_LENGTH]; cout << "Passphrase: "; cin.getline(passPhrase, MAX_PHRASE_LENGTH); if (command == "e") EncryptFile(argv[2], argv[3], passPhrase); else DecryptFile(argv[2], argv[3], passPhrase); } return 0; case 's': if (argv[1][1] == 's') { char seed[1024]; cout << "\nRandom Seed: "; ws(cin); cin.getline(seed, 1024); SecretShareFile(atoi(argv[2]), atoi(argv[3]), argv[4], seed); } else SecretRecoverFile(argc-3, argv[2], argv+3); return 0; case 'i': if (argv[1][1] == 'd') InformationDisperseFile(atoi(argv[2]), atoi(argv[3]), argv[4]); else InformationRecoverFile(argc-3, argv[2], argv+3); return 0; case 'v': return !Validate(argc>2 ? atoi(argv[2]) : 0, argv[1][1] == 'v', argc>3 ? argv[3] : NULL); case 'b': if (argc<3) BenchMarkAll(); else BenchMarkAll((float)atof(argv[2])); return 0; case 'z': GzipFile(argv[3], argv[4], argv[2][0]-'0'); return 0; case 'u': GunzipFile(argv[2], argv[3]); return 0; case 'f': if (command == "fips") FIPS140_SampleApplication(executableName.c_str(), edcFilename.c_str()); else if (command == "fips-rand") FIPS140_GenerateRandomFiles(); else if (command == "ft") ForwardTcpPort(argv[2], argv[3], argv[4]); return 0; case 'a': if (AdhocTest) return (*AdhocTest)(argc, argv); else return 0; default: FileSource usage("usage.dat", true, new FileSink(cout)); return 1; } } catch(CryptoPP::Exception &e) { cout << "\nCryptoPP::Exception caught: " << e.what() << endl; return -1; } catch(std::exception &e) { cout << "\nstd::exception caught: " << e.what() << endl; return -2; } }
// ---------------------------------------------------------------------------- // MAINLINE LOGIC // ---------------------------------------------------------------------------- int main() { // declarations int action = UNSET; char rawPT[BUFFER_SIZE] = ""; char cleanPT[BUFFER_SIZE] = ""; int a = A, b = B, inverse = INVERSE, n = ALPHABET_SIZE; char nameInputFile[30] = "input.txt" ; char nameOutputFile[30] = "output.txt"; // seed the random number generator srand((unsigned int)time(NULL)); // get ready action = fGetClnStr(action, rawPT, cleanPT); // display title page DispHeader(nameInputFile, nameOutputFile, a, b, inverse); puts("Welcome to Derrida - the command line Affine Cipher!"); Pause(); // detail loop while(action != QUIT) { ClearScreen(); DispHeader(nameInputFile, nameOutputFile, a, b, inverse); // select an action action = SelectAction(action); DispHeader(nameInputFile, nameOutputFile, a, b, inverse); // execute action switch(action) { case SET_I_FILE: // change the input file action = fGetClnStr(action, rawPT, cleanPT, nameInputFile); break; case SET_O_FILE: // change the output file action = SetOutputFileName(nameOutputFile); break; case DIR_LIST: // display directory listing list_dir(); break; case SET_KEY: // change cipher key action = SetCipherKey(a, b, n, inverse); break; case ENCRYPT: // encrypt the PT codes // display the string before encryption printf("Before encryption, the string contains:\n"); puts(rawPT); printf("\n"); printf("Sanatized, the string contains:\n"); puts(cleanPT); printf("\n"); // if encryption succeeds, inform the user if(EncryptString(cleanPT, a, b, n)) { FileOutput(nameOutputFile, cleanPT); printf("After encryption, the string contains:\n"); puts(cleanPT); printf("\n"); } Pause(); break; case DECRYPT: // display the clean cipher code before decryption puts("Before decryption, the string contains:"); puts(cleanPT); puts("\n"); // if decryption succeeds, inform the user if(DecryptString(cleanPT, a, b, n)) { FileOutput(nameOutputFile, cleanPT); puts("After decryption, the string contains:\n"); puts(cleanPT); puts("\n"); } Pause(); break; } } puts("The program will now exit."); Pause(); // exit program return 0; }
int EncryptCopyRegularFileNet(const char *source, const char *dest, off_t size, AgentConnection *conn) { int dd, blocksize = 2048, n_read = 0, towrite, plainlen, more = true, finlen, cnt = 0; int tosend, cipherlen = 0; char *buf, in[CF_BUFSIZE], out[CF_BUFSIZE], workbuf[CF_BUFSIZE], cfchangedstr[265]; unsigned char iv[32] = { 1, 2, 3, 4, 5, 6, 7, 8, 1, 2, 3, 4, 5, 6, 7, 8, 1, 2, 3, 4, 5, 6, 7, 8, 1, 2, 3, 4, 5, 6, 7, 8 }; long n_read_total = 0; EVP_CIPHER_CTX crypto_ctx; snprintf(cfchangedstr, 255, "%s%s", CF_CHANGEDSTR1, CF_CHANGEDSTR2); if ((strlen(dest) > CF_BUFSIZE - 20)) { Log(LOG_LEVEL_ERR, "Filename too long"); return false; } unlink(dest); /* To avoid link attacks */ if ((dd = safe_open(dest, O_WRONLY | O_CREAT | O_TRUNC | O_EXCL | O_BINARY, 0600)) == -1) { Log(LOG_LEVEL_ERR, "Copy from server '%s' to destination '%s' failed (open: %s)", conn->this_server, dest, GetErrorStr()); unlink(dest); return false; } if (size == 0) { // No sense in copying an empty file close(dd); return true; } workbuf[0] = '\0'; EVP_CIPHER_CTX_init(&crypto_ctx); snprintf(in, CF_BUFSIZE - CF_PROTO_OFFSET, "GET dummykey %s", source); cipherlen = EncryptString(conn->encryption_type, in, out, conn->session_key, strlen(in) + 1); snprintf(workbuf, CF_BUFSIZE, "SGET %4d %4d", cipherlen, blocksize); memcpy(workbuf + CF_PROTO_OFFSET, out, cipherlen); tosend = cipherlen + CF_PROTO_OFFSET; /* Send proposition C0 - query */ if (SendTransaction(conn->conn_info, workbuf, tosend, CF_DONE) == -1) { Log(LOG_LEVEL_ERR, "Couldn't send data. (SendTransaction: %s)", GetErrorStr()); close(dd); return false; } buf = xmalloc(CF_BUFSIZE + sizeof(int)); n_read_total = 0; while (more) { if ((cipherlen = ReceiveTransaction(conn->conn_info, buf, &more)) == -1) { free(buf); return false; } cnt++; /* If the first thing we get is an error message, break. */ if ((n_read_total == 0) && (strncmp(buf + CF_INBAND_OFFSET, CF_FAILEDSTR, strlen(CF_FAILEDSTR)) == 0)) { Log(LOG_LEVEL_INFO, "Network access to '%s:%s' denied", conn->this_server, source); close(dd); free(buf); return false; } if (strncmp(buf + CF_INBAND_OFFSET, cfchangedstr, strlen(cfchangedstr)) == 0) { Log(LOG_LEVEL_INFO, "Source '%s:%s' changed while copying", conn->this_server, source); close(dd); free(buf); return false; } EVP_DecryptInit_ex(&crypto_ctx, CfengineCipher(CfEnterpriseOptions()), NULL, conn->session_key, iv); if (!EVP_DecryptUpdate(&crypto_ctx, workbuf, &plainlen, buf, cipherlen)) { close(dd); free(buf); return false; } if (!EVP_DecryptFinal_ex(&crypto_ctx, workbuf + plainlen, &finlen)) { close(dd); free(buf); return false; } towrite = n_read = plainlen + finlen; n_read_total += n_read; if (!FSWrite(dest, dd, workbuf, towrite)) { Log(LOG_LEVEL_ERR, "Local disk write failed copying '%s:%s' to '%s:%s'", conn->this_server, source, dest, GetErrorStr()); if (conn) { conn->error = true; } free(buf); unlink(dest); close(dd); EVP_CIPHER_CTX_cleanup(&crypto_ctx); return false; } } /* If the file ends with a `hole', something needs to be written at the end. Otherwise the kernel would truncate the file at the end of the last write operation. Write a null character and truncate it again. */ if (ftruncate(dd, n_read_total) < 0) { Log(LOG_LEVEL_ERR, "Copy failed (no space?) while copying '%s' from network '%s'", dest, GetErrorStr()); free(buf); unlink(dest); close(dd); EVP_CIPHER_CTX_cleanup(&crypto_ctx); return false; } close(dd); free(buf); EVP_CIPHER_CTX_cleanup(&crypto_ctx); return true; }
int CompareHashNet(const char *file1, const char *file2, bool encrypt, AgentConnection *conn) { unsigned char d[EVP_MAX_MD_SIZE + 1]; char *sp, sendbuffer[CF_BUFSIZE], recvbuffer[CF_BUFSIZE], in[CF_BUFSIZE], out[CF_BUFSIZE]; int i, tosend, cipherlen; HashFile(file2, d, CF_DEFAULT_DIGEST); memset(recvbuffer, 0, CF_BUFSIZE); /* We encrypt only for CLASSIC protocol. The TLS protocol is always over * encrypted layer, so it does not support encrypted (S*) commands. */ encrypt = encrypt && conn->conn_info->protocol == CF_PROTOCOL_CLASSIC; if (encrypt) { snprintf(in, CF_BUFSIZE, "MD5 %s", file1); sp = in + strlen(in) + CF_SMALL_OFFSET; for (i = 0; i < CF_DEFAULT_DIGEST_LEN; i++) { *sp++ = d[i]; } cipherlen = EncryptString(conn->encryption_type, in, out, conn->session_key, strlen(in) + CF_SMALL_OFFSET + CF_DEFAULT_DIGEST_LEN); snprintf(sendbuffer, CF_BUFSIZE, "SMD5 %d", cipherlen); memcpy(sendbuffer + CF_PROTO_OFFSET, out, cipherlen); tosend = cipherlen + CF_PROTO_OFFSET; } else { snprintf(sendbuffer, CF_BUFSIZE, "MD5 %s", file1); sp = sendbuffer + strlen(sendbuffer) + CF_SMALL_OFFSET; for (i = 0; i < CF_DEFAULT_DIGEST_LEN; i++) { *sp++ = d[i]; } tosend = strlen(sendbuffer) + CF_SMALL_OFFSET + CF_DEFAULT_DIGEST_LEN; } if (SendTransaction(conn->conn_info, sendbuffer, tosend, CF_DONE) == -1) { Log(LOG_LEVEL_ERR, "Failed send. (SendTransaction: %s)", GetErrorStr()); return false; } if (ReceiveTransaction(conn->conn_info, recvbuffer, NULL) == -1) { /* TODO mark connection in the cache as closed. */ Log(LOG_LEVEL_ERR, "Failed receive. (ReceiveTransaction: %s)", GetErrorStr()); Log(LOG_LEVEL_VERBOSE, "No answer from host, assuming checksum ok to avoid remote copy for now..."); return false; } if (strcmp(CFD_TRUE, recvbuffer) == 0) { return true; /* mismatch */ } else { return false; } /* Not reached */ }
/* Returning NULL (an empty list) does not mean empty directory but ERROR, * since every directory has to contain at least . and .. */ Item *RemoteDirList(const char *dirname, bool encrypt, AgentConnection *conn) { char sendbuffer[CF_BUFSIZE]; char recvbuffer[CF_BUFSIZE]; char in[CF_BUFSIZE]; char out[CF_BUFSIZE]; int cipherlen = 0, tosend; if (strlen(dirname) > CF_BUFSIZE - 20) { Log(LOG_LEVEL_ERR, "Directory name too long"); return NULL; } /* We encrypt only for CLASSIC protocol. The TLS protocol is always over * encrypted layer, so it does not support encrypted (S*) commands. */ encrypt = encrypt && conn->conn_info->protocol == CF_PROTOCOL_CLASSIC; if (encrypt) { if (conn->session_key == NULL) { Log(LOG_LEVEL_ERR, "Cannot do encrypted copy without keys (use cf-key)"); return NULL; } snprintf(in, CF_BUFSIZE, "OPENDIR %s", dirname); cipherlen = EncryptString(conn->encryption_type, in, out, conn->session_key, strlen(in) + 1); snprintf(sendbuffer, CF_BUFSIZE - 1, "SOPENDIR %d", cipherlen); memcpy(sendbuffer + CF_PROTO_OFFSET, out, cipherlen); tosend = cipherlen + CF_PROTO_OFFSET; } else { snprintf(sendbuffer, CF_BUFSIZE, "OPENDIR %s", dirname); tosend = strlen(sendbuffer); } if (SendTransaction(conn->conn_info, sendbuffer, tosend, CF_DONE) == -1) { return NULL; } Item *start = NULL, *end = NULL; /* NULL == empty list */ while (true) { /* TODO check the CF_MORE flag, no need for CFD_TERMINATOR. */ int nbytes = ReceiveTransaction(conn->conn_info, recvbuffer, NULL); /* If recv error or socket closed before receiving CFD_TERMINATOR. */ if (nbytes == -1 || nbytes == 0) { /* TODO mark connection in the cache as closed. */ goto err; } if (recvbuffer[0] == '\0') { Log(LOG_LEVEL_ERR, "Empty%s server packet when listing directory '%s'!", (start == NULL) ? " first" : "", dirname); goto err; } if (encrypt) { memcpy(in, recvbuffer, nbytes); DecryptString(conn->encryption_type, in, recvbuffer, conn->session_key, nbytes); } if (FailedProtoReply(recvbuffer)) { Log(LOG_LEVEL_INFO, "Network access to '%s:%s' denied", conn->this_server, dirname); goto err; } if (BadProtoReply(recvbuffer)) { Log(LOG_LEVEL_INFO, "%s", recvbuffer + strlen("BAD: ")); goto err; } /* Double '\0' means end of packet. */ for (char *sp = recvbuffer; *sp != '\0'; sp += strlen(sp) + 1) { if (strcmp(sp, CFD_TERMINATOR) == 0) /* end of all packets */ { return start; } Item *ip = xcalloc(1, sizeof(Item)); ip->name = (char *) AllocateDirentForFilename(sp); if (start == NULL) /* First element */ { start = ip; end = ip; } else { end->next = ip; end = ip; } } } return start; err: /* free list */ for (Item *ip = start; ip != NULL; ip = start) { start = ip->next; free(ip->name); free(ip); } return NULL; }
int EncryptCopyRegularFileNet(const char *source, const char *dest, off_t size, AgentConnection *conn) { int dd, blocksize = 2048, n_read = 0, plainlen, more = true, finlen, cnt = 0; int tosend, cipherlen = 0; char *buf, in[CF_BUFSIZE], out[CF_BUFSIZE], workbuf[CF_BUFSIZE], cfchangedstr[265]; unsigned char iv[32] = { 1, 2, 3, 4, 5, 6, 7, 8, 1, 2, 3, 4, 5, 6, 7, 8, 1, 2, 3, 4, 5, 6, 7, 8, 1, 2, 3, 4, 5, 6, 7, 8 }; EVP_CIPHER_CTX crypto_ctx; snprintf(cfchangedstr, 255, "%s%s", CF_CHANGEDSTR1, CF_CHANGEDSTR2); if ((strlen(dest) > CF_BUFSIZE - 20)) { Log(LOG_LEVEL_ERR, "Filename too long"); return false; } unlink(dest); /* To avoid link attacks */ if ((dd = safe_open(dest, O_WRONLY | O_CREAT | O_TRUNC | O_EXCL | O_BINARY, 0600)) == -1) { Log(LOG_LEVEL_ERR, "Copy from server '%s' to destination '%s' failed (open: %s)", conn->this_server, dest, GetErrorStr()); unlink(dest); return false; } if (size == 0) { // No sense in copying an empty file close(dd); return true; } workbuf[0] = '\0'; EVP_CIPHER_CTX_init(&crypto_ctx); snprintf(in, CF_BUFSIZE - CF_PROTO_OFFSET, "GET dummykey %s", source); cipherlen = EncryptString(out, sizeof(out), in, strlen(in) + 1, conn->encryption_type, conn->session_key); tosend = cipherlen + CF_PROTO_OFFSET; if(tosend > sizeof(workbuf)) { ProgrammingError("EncryptCopyRegularFileNet: tosend (%d) > workbuf (%ld)", tosend, sizeof(workbuf)); } snprintf(workbuf, CF_BUFSIZE, "SGET %4d %4d", cipherlen, blocksize); memcpy(workbuf + CF_PROTO_OFFSET, out, cipherlen); /* Send proposition C0 - query */ if (SendTransaction(conn->conn_info, workbuf, tosend, CF_DONE) == -1) { Log(LOG_LEVEL_ERR, "Couldn't send data. (SendTransaction: %s)", GetErrorStr()); close(dd); return false; } buf = xmalloc(CF_BUFSIZE + sizeof(int)); bool last_write_made_hole = false; size_t n_wrote_total = 0; while (more) { if ((cipherlen = ReceiveTransaction(conn->conn_info, buf, &more)) == -1) { free(buf); return false; } cnt++; /* If the first thing we get is an error message, break. */ if (n_wrote_total == 0 && strncmp(buf + CF_INBAND_OFFSET, CF_FAILEDSTR, strlen(CF_FAILEDSTR)) == 0) { Log(LOG_LEVEL_INFO, "Network access to '%s:%s' denied", conn->this_server, source); close(dd); free(buf); return false; } if (strncmp(buf + CF_INBAND_OFFSET, cfchangedstr, strlen(cfchangedstr)) == 0) { Log(LOG_LEVEL_INFO, "Source '%s:%s' changed while copying", conn->this_server, source); close(dd); free(buf); return false; } EVP_DecryptInit_ex(&crypto_ctx, CfengineCipher(CfEnterpriseOptions()), NULL, conn->session_key, iv); if (!EVP_DecryptUpdate(&crypto_ctx, workbuf, &plainlen, buf, cipherlen)) { close(dd); free(buf); return false; } if (!EVP_DecryptFinal_ex(&crypto_ctx, workbuf + plainlen, &finlen)) { close(dd); free(buf); return false; } n_read = plainlen + finlen; bool w_ok = FileSparseWrite(dd, workbuf, n_read, &last_write_made_hole); if (!w_ok) { Log(LOG_LEVEL_ERR, "Local disk write failed copying '%s:%s' to '%s'", conn->this_server, source, dest); free(buf); unlink(dest); close(dd); conn->error = true; EVP_CIPHER_CTX_cleanup(&crypto_ctx); return false; } n_wrote_total += n_read; } const bool do_sync = false; bool ret = FileSparseClose(dd, dest, do_sync, n_wrote_total, last_write_made_hole); if (!ret) { unlink(dest); free(buf); EVP_CIPHER_CTX_cleanup(&crypto_ctx); return false; } free(buf); EVP_CIPHER_CTX_cleanup(&crypto_ctx); return true; }