示例#1
0
// FIX THIS: need to unit test this.
static int do_conf_switch_to_orig_client(struct conf **globalcs,
	struct conf **cconfs, const char *orig_client, const char *buf)
{
	int ret=-1;
	int loadrc;
	struct conf **sconfs=NULL;
	if(!(sconfs=confs_alloc())
	  || confs_init(sconfs)) goto end;
	if(set_string(sconfs[OPT_CNAME], orig_client))
		goto end;
	logp("Client wants to switch to client: %s\n",
		get_string(sconfs[OPT_CNAME]));

	// Allow unit testing using a buffer.
#ifdef UTEST
	if(buf) loadrc=conf_load_overrides_buf(globalcs, sconfs, buf);
	else
#endif
		loadrc=conf_load_clientconfdir(globalcs, sconfs);
	if(loadrc)
	{
		logp("Could not load alternate config: %s",
			get_string(sconfs[OPT_CNAME]));
		goto end;
	}
	set_int(sconfs[OPT_SEND_CLIENT_CNTR],
		get_int(cconfs[OPT_SEND_CLIENT_CNTR]));

	if(!restore_client_allowed(cconfs, sconfs))
		goto end;

	if(set_string(sconfs[OPT_RESTORE_PATH],
		get_string(cconfs[OPT_RESTORE_PATH])))
			goto end;
	if(set_string(cconfs[OPT_RESTORE_PATH], NULL))
		goto end;
	set_cntr(sconfs[OPT_CNTR], get_cntr(cconfs[OPT_CNTR]));
	set_cntr(cconfs[OPT_CNTR], NULL);
	confs_free_content(cconfs);
	confs_init(cconfs);
	confs_memcpy(cconfs, sconfs);
	confs_null(sconfs);
	if(set_string(cconfs[OPT_RESTORE_CLIENT],
		get_string(cconfs[OPT_CNAME]))) goto end;
	if(set_string(cconfs[OPT_ORIG_CLIENT],
		get_string(cconfs[OPT_CNAME]))) goto end;

	logp("Switched to client %s\n", get_string(cconfs[OPT_CNAME]));
	ret=0;
end:
	confs_free(&sconfs);
	return ret;
}
示例#2
0
文件: conffile.c 项目: EmisFR/burp
// FIX THIS: need to unit test this.
int conf_switch_to_orig_client(struct conf **globalcs,
	struct conf **cconfs, const char *orig_client)
{
	int ret=-1;
	struct conf **sconfs=NULL;
	if(!(sconfs=confs_alloc())
	  || confs_init(sconfs)) goto end;
	if(set_string(sconfs[OPT_CNAME], orig_client))
		goto end;
	logp("Client wants to switch to client: %s\n",
		get_string(sconfs[OPT_CNAME]));

	if(conf_load_clientconfdir(globalcs, sconfs))
	{
		logp("Could not load alternate config: %s",
			get_string(sconfs[OPT_CNAME]));
		goto end;
	}
	set_int(sconfs[OPT_SEND_CLIENT_CNTR],
		get_int(cconfs[OPT_SEND_CLIENT_CNTR]));

	if(!restore_client_allowed(cconfs, sconfs))
		goto end;

	if(set_string(sconfs[OPT_RESTORE_PATH],
		get_string(cconfs[OPT_RESTORE_PATH])))
			goto end;
	if(set_string(cconfs[OPT_RESTORE_PATH], NULL))
		goto end;
	set_cntr(sconfs[OPT_CNTR], get_cntr(cconfs));
	set_cntr(cconfs[OPT_CNTR], NULL);
	confs_free_content(cconfs);
	confs_init(cconfs);
	confs_memcpy(cconfs, sconfs);
	confs_null(sconfs);
	if(set_string(cconfs[OPT_RESTORE_CLIENT],
		get_string(cconfs[OPT_CNAME]))) goto end;
	if(set_string(cconfs[OPT_ORIG_CLIENT],
		get_string(cconfs[OPT_CNAME]))) goto end;

	logp("Switched to client %s\n", get_string(cconfs[OPT_CNAME]));
	ret=0;
end:
	confs_free(&sconfs);
	return ret;
}
示例#3
0
文件: cstat.c 项目: EmisFR/burp
static
#endif
int cstat_reload_from_client_confs(struct cstat **clist,
                                   struct conf **globalcs, struct conf **cconfs)
{
    struct cstat *c;
    struct stat statp;
    static time_t global_mtime=0;
    time_t global_mtime_new=0;
    const char *globalconffile;
    int reloaded=0;

    globalconffile=get_string(globalcs[OPT_CONFFILE]);

    if(stat(globalconffile, &statp)
            || !S_ISREG(statp.st_mode))
    {
        logp("Could not stat main conf file %s: %s\n",
             globalconffile, strerror(errno));
        return -1;
    }
    global_mtime_new=statp.st_mtime;

    // FIX THIS: If '. included' conf files have changed, this code will
    // not detect them. I guess that conf.c should make a list of them.
    while(1)
    {
        for(c=*clist; c; c=c->next)
        {
            // Look at the client conf files to see if they have
            // changed, and reload bits and pieces if they have.

            if(!c->conffile) continue;
            if(stat(c->conffile, &statp)
                    || !S_ISREG(statp.st_mode))
            {
                cstat_remove(clist, &c);
                break; // Go to the beginning of the list.
            }
            if(statp.st_mtime==c->conf_mtime
                    && global_mtime_new==global_mtime)
            {
                // The conf files have not changed - no need to
                // do anything.
                continue;
            }
            c->conf_mtime=statp.st_mtime;

            confs_free_content(cconfs);
            if(set_string(cconfs[OPT_CNAME], c->name))
                return -1;
            if(conf_load_clientconfdir(globalcs, cconfs))
            {
                // If the file has junk in it, we will keep
                // trying to reload it after removal.
                // So, just deny permission to view it.
                c->permitted=0;
                continue;
            }

            if(set_cstat_from_conf(c, globalcs, cconfs))
                return -1;
            reloaded++;
        }
        // Only stop if the end of the list was not reached.
        if(!c) break;
    }
    if(global_mtime!=global_mtime_new)
        global_mtime=global_mtime_new;
    return reloaded;
}
示例#4
0
文件: bedup.c 项目: kaptk2/burp
static int iterate_over_clients(struct conf **globalcs,
	struct strlist *grouplist, const char *ext, unsigned int maxlinks)
{
	int ret=0;
	DIR *dirp=NULL;
	struct conf **cconfs=NULL;
	struct dirent *dirinfo=NULL;
	const char *globalclientconfdir=get_string(globalcs[OPT_CLIENTCONFDIR]);

	signal(SIGABRT, &sighandler);
	signal(SIGTERM, &sighandler);
	signal(SIGINT, &sighandler);

	if(!(cconfs=confs_alloc())) return -1;
	if(confs_init(cconfs)) return -1;

	if(!(dirp=opendir(globalclientconfdir)))
	{
		logp("Could not opendir '%s': %s\n",
			globalclientconfdir, strerror(errno));
		return 0;
	}
	while((dirinfo=readdir(dirp)))
	{
		char *lockfile=NULL;
		char *lockfilebase=NULL;
		char *client_lockdir=NULL;
		struct lock *lock=NULL;

		if(dirinfo->d_ino==0
		// looks_like...() also avoids '.' and '..'.
		  || looks_like_tmp_or_hidden_file(dirinfo->d_name)
		  || !is_regular_file(globalclientconfdir, dirinfo->d_name))
			continue;

		confs_free_content(cconfs);
		if(confs_init(cconfs)) return -1;

		if(set_string(cconfs[OPT_CNAME], dirinfo->d_name))
			return -1;

		if(conf_load_clientconfdir(globalcs, cconfs))
		{
			logp("could not load config for client %s\n",
				dirinfo->d_name);
			return 0;
		}

		if(grouplist)
		{
			const char *dedup_group=
				get_string(cconfs[OPT_DEDUP_GROUP]);
			if(!dedup_group
			  || !in_group(grouplist, dedup_group))
				continue;
		}

		if(!(client_lockdir=get_string(cconfs[OPT_CLIENT_LOCKDIR])))
			client_lockdir=get_string(cconfs[OPT_DIRECTORY]);

		if(!(lockfilebase=prepend(client_lockdir,
			dirinfo->d_name, "/"))
		 || !(lockfile=prepend(lockfilebase,
			BEDUP_LOCKFILE_NAME, "/")))
		{
			free_w(&lockfilebase);
			free_w(&lockfile);
			ret=-1;
			break;
		}
		free_w(&lockfilebase);

		if(!(lock=lock_alloc_and_init(lockfile)))
		{
			ret=-1;
			break;
		}
		lock_get(lock);
		free_w(&lockfile);

		if(lock->status!=GET_LOCK_GOT)
		{
			logp("Could not get %s\n", lock->path);
			continue;
		}
		logp("Got %s\n", lock->path);

		// Remember that we got that lock.
		lock_add_to_list(&locklist, lock);

		if(process_dir(get_string(cconfs[OPT_DIRECTORY]),
			dirinfo->d_name,
			ext, maxlinks, 1 /* burp mode */, 0 /* level */))
		{
			ret=-1;
			break;
		}

		ccount++;
	}
	closedir(dirp);

	locks_release_and_free(&locklist);

	confs_free(&cconfs);

	return ret;
}
示例#5
0
文件: main.c 项目: EmisFR/burp
static int process_incoming_client(struct asfd *asfd, SSL_CTX *ctx,
	const char *conffile, struct conf **confs)
{
	int cfd=-1;
	pid_t childpid;
	int pipe_rfd[2];
	int pipe_wfd[2];
	socklen_t client_length=0;
	struct sockaddr_storage client_name;
	enum asfd_fdtype fdtype=asfd->fdtype;
	int forking=get_int(confs[OPT_FORK]);

	client_length=sizeof(client_name);
	if((cfd=accept(asfd->fd,
		(struct sockaddr *)&client_name, &client_length))==-1)
	{
		// Look out, accept will get interrupted by SIGCHLDs.
		if(errno==EINTR) return 0;
		logp("accept failed on %s (%d) in %s: %s\n", asfd->desc,
			asfd->fd, __func__, strerror(errno));
		return -1;
	}
	reuseaddr(cfd);
	if(log_peer_address(&client_name))
		return -1;

	if(!forking)
		return run_child(&cfd, ctx,
			&client_name, -1, -1, conffile, forking);

	if(chld_check_counts(confs, asfd))
	{
		logp("Closing new connection.\n");
		close_fd(&cfd);
		return 0;
	}

	if(pipe(pipe_rfd)<0 || pipe(pipe_wfd)<0)
	{
		logp("pipe failed: %s", strerror(errno));
		close_fd(&cfd);
		return -1;
	}

	switch((childpid=fork()))
	{
		case -1:
			logp("fork failed: %s\n", strerror(errno));
			return -1;
		case 0:
		{
			// Child.
			int p;
			int ret;
			struct sigaction sa;
			struct async *as=asfd->as;
			async_asfd_free_all(&as);

			// Close unnecessary file descriptors.
			// Go up to FD_SETSIZE and hope for the best.
			// FIX THIS: Now that async_asfd_free_all() is doing
			// everything, double check whether this is needed.
			for(p=3; p<(int)FD_SETSIZE; p++)
			{
				if(p!=pipe_rfd[1]
				  && p!=pipe_wfd[0]
				  && p!=cfd)
					close(p);
			}

			// Set SIGCHLD back to default, so that I
			// can get sensible returns from waitpid.
			memset(&sa, 0, sizeof(sa));
			sa.sa_handler=SIG_DFL;
			sigaction(SIGCHLD, &sa, NULL);

			close(pipe_rfd[0]); // close read end
			close(pipe_wfd[1]); // close write end

			confs_free_content(confs);
			confs_init(confs);

			ret=run_child(&cfd, ctx, &client_name, pipe_rfd[1],
			  fdtype==ASFD_FD_SERVER_LISTEN_STATUS?pipe_wfd[0]:-1,
			  conffile, forking);

			close(pipe_rfd[1]);
			close(pipe_wfd[0]);
			close_fd(&cfd);
			exit(ret);
		}
		default:
			// Parent.
			close(pipe_rfd[1]); // close write end
			close(pipe_wfd[0]); // close read end
			close_fd(&cfd);

			return setup_parent_child_pipes(asfd, childpid,
				&pipe_rfd[0], &pipe_wfd[1]);
	}
}