Example #1
0
static int send_file(const char *fname, int patches, const char *best, const char *datapth, unsigned long long *bytes, char cmd, int64_t winattr, int compression, struct cntr *cntr, struct config *cconf)
{
	int ret=0;
	size_t datalen=0;
	FILE *fp=NULL;
	if(open_file_for_send(NULL, &fp, best, winattr, &datalen, cntr))
		return -1;
	//logp("sending: %s\n", best);
	if(async_write(cmd, fname, strlen(fname)))
		ret=-1;
	else if(patches)
	{
		// If we did some patches, the resulting file
		// is not gzipped. Gzip it during the send. 
		ret=send_whole_file_gz(best, datapth, 1, bytes, NULL, cntr,
			9, NULL, fp, NULL, 0, -1);
	}
	else
	{
		// If it was encrypted, it may or may not have been compressed
		// before encryption. Send it as it as, and let the client
		// sort it out.
		if(cmd==CMD_ENC_FILE
		  || cmd==CMD_ENC_METADATA
		  || cmd==CMD_ENC_VSS
		  || cmd==CMD_ENC_VSS_T
		  || cmd==CMD_EFS_FILE)
		{
			ret=send_whole_file(cmd, best, datapth, 1, bytes,
				cntr, NULL, fp, NULL, 0, -1);
		}
		// It might have been stored uncompressed. Gzip it during
		// the send. If the client knew what kind of file it would be
		// receiving, this step could disappear.
		else if(!dpth_is_compressed(compression, datapth))
		{
			ret=send_whole_file_gz(best, datapth, 1, bytes,
				NULL, cntr, 9, NULL, fp, NULL, 0, -1);
		}
		else
		{
			// If we did not do some patches, the resulting
			// file might already be gzipped. Send it as it is.
			ret=send_whole_file(cmd, best, datapth, 1, bytes,
				cntr, NULL, fp, NULL, 0, -1);
		}
	}
	close_file_for_send(NULL, &fp);
	return ret;
}
Example #2
0
File: handy.c Project: goneri/burp
/* Windows will use this function, when sending a certificate signing request.
   It is not using the Windows API stuff because it needs to arrive on the
   server side without any junk in it. */
int send_a_file(const char *path, struct cntr *p1cntr)
{
	int ret=0;
	FILE *fp=NULL;
	unsigned long long bytes=0;
	if(open_file_for_send(NULL, &fp, path, 0, p1cntr)
	  || send_whole_file_gz(path, "datapth", 0, &bytes, NULL,
		p1cntr, 9, // compression
		NULL, fp, NULL, 0))
	{
		ret=-1;
		goto end;
	}
	logp("Sent %s\n", path);
end:
	close_file_for_send(NULL, &fp);
	return ret;
}
Example #3
0
static int do_backup_phase2_client(struct config *conf, int resume, struct cntr *p1cntr, struct cntr *cntr)
{
	int ret=0;
	int quit=0;
	char cmd;
	char *buf=NULL;
	size_t len=0;
	char attribs[MAXSTRING];
	// For efficiency, open Windows files for the VSS data, and do not
	// close them until another time around the loop, when the actual
	// data is read.
	BFILE bfd;
	// Windows VSS headers tell us how much file
	// data to expect.
	size_t datalen=0;
#ifdef HAVE_WIN32
	binit(&bfd, 0);
#endif

	struct sbuf sb;

	init_sbuf(&sb);

	if(!resume)
	{
		// Only do this bit if the server did not tell us to resume.
		if(async_write_str(CMD_GEN, "backupphase2")
		  || async_read_expect(CMD_GEN, "ok"))
			return -1;
	}
	else if(conf->send_client_counters)
	{
		// On resume, the server might update the client with the
 		// counters.
		if(recv_counters(p1cntr, cntr))
			return -1;	
	}

	while(!quit)
	{
		if(async_read(&cmd, &buf, &len))
		{
			ret=-1;
			quit++;
		}
		else if(buf)
		{
			//logp("now: %c:%s\n", cmd, buf);
			if(cmd==CMD_DATAPTH)
			{
				sb.datapth=buf;
				buf=NULL;
				continue;
			}
			else if(cmd==CMD_STAT)
			{
				// Ignore the stat data - we will fill it
				// in again. Some time may have passed by now,
				// and it is best to make it as fresh as
				// possible.
				free(buf);
				buf=NULL;
				continue;
			}
			else if(cmd==CMD_FILE
			  || cmd==CMD_ENC_FILE
			  || cmd==CMD_METADATA
			  || cmd==CMD_ENC_METADATA
			  || cmd==CMD_VSS
			  || cmd==CMD_ENC_VSS
			  || cmd==CMD_VSS_T
			  || cmd==CMD_ENC_VSS_T
			  || cmd==CMD_EFS_FILE)
			{
				int forget=0;
				int64_t winattr=0;
				struct stat statbuf;
				char *extrameta=NULL;
				size_t elen=0;
				unsigned long long bytes=0;
				FILE *fp=NULL;
				int compression=conf->compression;

				sb.path=buf;
				buf=NULL;

#ifdef HAVE_WIN32
				if(win32_lstat(sb.path, &statbuf, &winattr))
#else
				if(lstat(sb.path, &statbuf))
#endif
				{
					logw(cntr, "Path has vanished: %s", sb.path);
					if(forget_file(&sb, cmd, cntr))
					{
						ret=-1;
						quit++;
					}
					free_sbuf(&sb);
					continue;
				}

				if(conf->min_file_size
				  && statbuf.st_size<
					(boffset_t)conf->min_file_size
				  && (cmd==CMD_FILE
				  || cmd==CMD_ENC_FILE
				  || cmd==CMD_EFS_FILE))
				{
					logw(cntr, "File size decreased below min_file_size after initial scan: %c:%s", cmd, sb.path);
					forget++;
				}
				else if(conf->max_file_size
				  && statbuf.st_size>
					(boffset_t)conf->max_file_size
				  && (cmd==CMD_FILE
				  || cmd==CMD_ENC_FILE
				  || cmd==CMD_EFS_FILE))
				{
					logw(cntr, "File size increased above max_file_size after initial scan: %c:%s", cmd, sb.path);
					forget++;
				}

				if(!forget)
				{
					compression=in_exclude_comp(conf->excom,
					  conf->excmcount, sb.path,
					  conf->compression);
					encode_stat(attribs,
					  &statbuf, winattr, compression);
					if(open_file_for_send(
#ifdef HAVE_WIN32
						&bfd, NULL,
#else
						NULL, &fp,
#endif
						sb.path, winattr,
						&datalen, cntr))
							forget++;
				}

				if(forget)
				{
					if(forget_file(&sb, cmd, cntr))
					{
						ret=-1;
						quit++;
					}
					free_sbuf(&sb);
					continue;
				}

				if(cmd==CMD_METADATA
				  || cmd==CMD_ENC_METADATA
				  || cmd==CMD_VSS
				  || cmd==CMD_ENC_VSS
#ifdef HAVE_WIN32
				  || conf->strip_vss
#endif
				  )
				{
					if(get_extrameta(
#ifdef HAVE_WIN32
						&bfd,
#else
						NULL,
#endif
						sb.path,
						&statbuf, &extrameta, &elen,
						winattr, cntr,
						&datalen))
					{
						logw(cntr, "Meta data error for %s", sb.path);
						free_sbuf(&sb);
						close_file_for_send(&bfd, &fp);
						continue;
					}
					if(extrameta)
					{
#ifdef HAVE_WIN32
						if(conf->strip_vss)
						{
							free(extrameta);
							extrameta=NULL;
							elen=0;
						}
#endif
					}
					else
					{
						logw(cntr, "No meta data after all: %s", sb.path);
						free_sbuf(&sb);
						close_file_for_send(&bfd, &fp);
						continue;
					}
				}

				if(cmd==CMD_FILE && sb.datapth)
				{
					unsigned long long sentbytes=0;
					// Need to do sig/delta stuff.
					if(async_write_str(CMD_DATAPTH, sb.datapth)
					  || async_write_str(CMD_STAT, attribs)
					  || async_write_str(CMD_FILE, sb.path)
					  || load_signature_and_send_delta(
						&bfd, fp,
						&bytes, &sentbytes, cntr,
						datalen))
					{
						logp("error in sig/delta for %s (%s)\n", sb.path, sb.datapth);
						ret=-1;
						quit++;
					}
					else
					{
						do_filecounter(cntr, CMD_FILE_CHANGED, 1);
						do_filecounter_bytes(cntr, bytes);
						do_filecounter_sentbytes(cntr, sentbytes);
					}
				}
				else
				{
					//logp("need to send whole file: %s\n",
					//	sb.path);
					// send the whole file.

					if((async_write_str(CMD_STAT, attribs)
					  || async_write_str(cmd, sb.path))
					  || send_whole_file_w(cmd, sb.path,
						NULL, 0, &bytes,
						conf->encryption_password,
						cntr, compression,
						&bfd, fp,
						extrameta, elen,
						datalen))
					{
						ret=-1;
						quit++;
					}
					else
					{
						do_filecounter(cntr, cmd, 1);
						do_filecounter_bytes(cntr, bytes);
						do_filecounter_sentbytes(cntr, bytes);
					}
				}
#ifdef HAVE_WIN32
				// If using Windows do not close bfd - it needs
				// to stay open to read VSS/file data/VSS.
				// It will get closed either when given a
				// different file path, or when this function
				// exits.
				
				//if(cmd!=CMD_VSS
				// && cmd!=CMD_ENC_VSS)
				//	close_file_for_send(&bfd, NULL);
#else
				close_file_for_send(NULL, &fp);
#endif
				free_sbuf(&sb);
				if(extrameta) free(extrameta);
			}
			else if(cmd==CMD_WARNING)
			{
				do_filecounter(cntr, cmd, 0);
				free(buf);
				buf=NULL;
			}
			else if(cmd==CMD_GEN && !strcmp(buf, "backupphase2end"))
			{
				if(async_write_str(CMD_GEN, "okbackupphase2end"))
					ret=-1;
				quit++;
			}
			else
			{
				logp("unexpected cmd from server: %c %s\n",
					cmd, buf);
				ret=-1;
				quit++;
				free(buf);
				buf=NULL;
			}
		}
	}
#ifdef HAVE_WIN32
	// It is possible for a bfd to still be open.
	close_file_for_send(&bfd, NULL);
#endif
	return ret;
}
Example #4
0
static int do_backup_phase2_client(struct config *conf, int resume, struct cntr *cntr)
{
    int ret=0;
    int quit=0;
    char cmd;
    char *buf=NULL;
    size_t len=0;
    char attribs[MAXSTRING];

    struct sbuf sb;

    init_sbuf(&sb);

    if(!resume)
    {
        // Only do this bit if the server did not tell us to resume.
        if(async_write_str(CMD_GEN, "backupphase2")
                || async_read_expect(CMD_GEN, "ok"))
            return -1;
    }

    while(!quit)
    {
        if(async_read(&cmd, &buf, &len))
        {
            ret=-1;
            quit++;
        }
        else if(buf)
        {
            //logp("now: %c:%s\n", cmd, buf);
            if(cmd==CMD_DATAPTH)
            {
                sb.datapth=buf;
                buf=NULL;
                continue;
            }
            else if(cmd==CMD_STAT)
            {
                // Ignore the stat data - we will fill it
                // in again. Some time may have passed by now,
                // and it is best to make it as fresh as
                // possible.
                free(buf);
                buf=NULL;
                continue;
            }
            else if(cmd==CMD_FILE
                    || cmd==CMD_ENC_FILE
                    || cmd==CMD_METADATA
                    || cmd==CMD_ENC_METADATA
                    || cmd==CMD_EFS_FILE)
            {
                int forget=0;
                int64_t winattr=0;
                struct stat statbuf;
                char *extrameta=NULL;
                size_t elen=0;
                unsigned long long bytes=0;
                BFILE bfd;
                FILE *fp=NULL;

                sb.path=buf;
                buf=NULL;

#ifdef HAVE_WIN32
                if(win32_lstat(sb.path, &statbuf, &winattr))
#else
                if(lstat(sb.path, &statbuf))
#endif
                {
                    logw(cntr, "Path has vanished: %s", sb.path);
                    if(forget_file(&sb, cmd, cntr))
                    {
                        ret=-1;
                        quit++;
                    }
                    free_sbuf(&sb);
                    continue;
                }

                if(conf->min_file_size
                        && statbuf.st_size<(boffset_t)conf->min_file_size)
                {
                    logw(cntr, "File size decreased below min_file_size after initial scan: %s", sb.path);
                    forget++;
                }
                else if(conf->max_file_size
                        && statbuf.st_size>(boffset_t)conf->max_file_size)
                {
                    logw(cntr, "File size increased above max_file_size after initial scan: %s", sb.path);
                    forget++;
                }

                if(!forget)
                {
                    encode_stat(attribs, &statbuf, winattr);
                    if(open_file_for_send(&bfd, &fp,
                                          sb.path, winattr, cntr))
                        forget++;
                }

                if(forget)
                {
                    if(forget_file(&sb, cmd, cntr))
                    {
                        ret=-1;
                        quit++;
                    }
                    free_sbuf(&sb);
                    continue;
                }

                if(cmd==CMD_METADATA
                        || cmd==CMD_ENC_METADATA)
                {
                    if(get_extrameta(sb.path,
                                     &statbuf, &extrameta, &elen,
                                     cntr))
                    {
                        logw(cntr, "Meta data error for %s", sb.path);
                        free_sbuf(&sb);
                        close_file_for_send(&bfd, &fp);
                        continue;
                    }
                    if(!extrameta)
                    {
                        logw(cntr, "No meta data after all: %s", sb.path);
                        free_sbuf(&sb);
                        close_file_for_send(&bfd, &fp);
                        continue;
                    }
                }

                if(cmd==CMD_FILE && sb.datapth)
                {
                    unsigned long long sentbytes=0;
                    // Need to do sig/delta stuff.
                    if(async_write_str(CMD_DATAPTH, sb.datapth)
                            || async_write_str(CMD_STAT, attribs)
                            || async_write_str(CMD_FILE, sb.path)
                            || load_signature_and_send_delta(
                                &bfd, fp,
                                &bytes, &sentbytes, cntr))
                    {
                        logp("error in sig/delta for %s (%s)\n", sb.path, sb.datapth);
                        ret=-1;
                        quit++;
                    }
                    else
                    {
                        do_filecounter(cntr, CMD_FILE_CHANGED, 1);
                        do_filecounter_bytes(cntr, bytes);
                        do_filecounter_sentbytes(cntr, sentbytes);
                    }
                }
                else
                {
                    //logp("need to send whole file: %s\n",
                    //	sb.path);
                    // send the whole file.
                    if(async_write_str(CMD_STAT, attribs)
                            || async_write_str(cmd, sb.path)
                            || send_whole_file_w(cmd, sb.path,
                                                 NULL, 0, &bytes,
                                                 conf->encryption_password,
                                                 cntr, conf->compression,
                                                 &bfd, fp,
                                                 extrameta, elen))
                    {
                        ret=-1;
                        quit++;
                    }
                    else
                    {
                        do_filecounter(cntr, cmd, 1);
                        do_filecounter_bytes(cntr, bytes);
                        do_filecounter_sentbytes(cntr, bytes);
                    }
                }
                close_file_for_send(&bfd, &fp);
                free_sbuf(&sb);
                if(extrameta) free(extrameta);
            }
            else if(cmd==CMD_WARNING)
            {
                do_filecounter(cntr, cmd, 0);
                free(buf);
                buf=NULL;
            }
            else if(cmd==CMD_GEN && !strcmp(buf, "backupphase2end"))
            {
                if(async_write_str(CMD_GEN, "okbackupphase2end"))
                    ret=-1;
                quit++;
            }
            else
            {
                logp("unexpected cmd from server: %c %s\n",
                     cmd, buf);
                ret=-1;
                quit++;
                free(buf);
                buf=NULL;
            }
        }
    }
    return ret;
}