Пример #1
0
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;
}
Пример #2
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);
    }
}
Пример #3
0
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);
    }
}
Пример #4
0
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;
}
Пример #6
0
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;
}
Пример #7
0
/**
 * @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;
}
Пример #8
0
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 */
}
Пример #9
0
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;
}
Пример #10
0
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;
}
Пример #11
0
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;
}
Пример #13
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;
}
Пример #14
0
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 */
}
Пример #15
0
/* 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;
}
Пример #16
0
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;
}