Ejemplo n.º 1
0
char * zurl(const char * url, char * opt){
		const char * host = get_host(url);
		const char * uri = get_uri(url);
		unsigned int m,n;
		m = n = 0;
		struct field * data = get_data(uri,&m);
		struct field * params = get_params(uri,&n);
		char * buffer = http_request("GET", host, uri, HTTP_EDITION,
				params, m, data, n,1);
		free_kv(data,m);
		free_kv(params,n);
		return buffer;
}
Ejemplo n.º 2
0
void exithandler(void)
{
    if (main_kv)
        free_kv(&main_kv);
    if (fd)
        fclose(fd);
    if (hosts)
        fclose(hosts);
}
Ejemplo n.º 3
0
/* delete a HashTable instance */
void hash_table_delete(HashTable* ht)
{
	if (ht) {
		if (ht->table) {
			int i = 0;
			for (i = 0; i<TABLE_SIZE; i++) {
				struct kv* p = ht->table[i];
				struct kv* q = NULL;
				while (p) {
					q = p->next;
					free_kv(p);
					p = q;
				}
			}
			free(ht->table);
			ht->table = NULL;
		}
		free(ht);
	}
}
Ejemplo n.º 4
0
/* remove a value indexed by key */
void hash_table_rm(HashTable* ht, char* key)
{
	int i = hash_33(key) % TABLE_SIZE;
	
	struct kv* p = ht->table[i];
	struct kv* prep = p;
	while (p) {
		if (strcmp(key, p->key) == 0) {
			free_kv(p);
			if (p == prep) {
				ht->table[i] = NULL;
			}
			else {
				prep->next = p->next;
			}
		}
		prep = p;
		p = p->next;
	}
}
Ejemplo n.º 5
0
int main(int argc, char **argv)
{
    int flag_test = 0;
    int flag_flush = 0;
    int flag_repair = 0;
    int enabled_green = 0;
    int transparent_green = 0;
    int enabled_blue = 0;
    int transparent_blue = 0;
    int enabled_ovpn = 0;
    int transparent_ovpn = 0;
    struct stat st;
    NODEKV *squid_kv = NULL;
    char buffer[STRING_SIZE];
    char proxy_port[STRING_SIZE];
    NODEKV *ipsec_kv = NULL;
    char enabled_IPsec[STRING_SIZE] = "";

    static struct option long_options[] =
    {
        { "flush", no_argument, 0, 'f' },
        { "repair", no_argument, 0, 'r' },
        { "test", no_argument, 0, 't' },
        { "verbose", no_argument, 0, 'v' },
        { "help", no_argument, 0, 'h' },
        { 0, 0, 0, 0}
    };
    int c;
    int option_index = 0;

    if (!(initsetuid()))
        exit(1);

    while ((c = getopt_long(argc, argv, "frtv", long_options, &option_index)) != -1) {
        switch (c) {
        case 't':              /* test first */
            flag_test = 1;
            break;
        case 'f':              /* flush cache */
            flag_flush = 1;
            break;
        case 'r':              /* repair cache */
            flag_repair = 1;
            break;
        case 'v':              /* verbose */
            flag_verbose++;
            break;
        case 'h':
            usage(argv[0], 0);
        default:
            fprintf(stderr, "unknown option\n");
            usage(argv[0], 1);
        }
    }


    /* Retrieve the Squid pid file */
    if ((access("/var/run/squid.pid", F_OK) == -1) && flag_test) {
        verbose_printf(1, "Squid not running, no need to start\n");
        exit(0);                /* Not running, no need to start with -t */
    }

    if (access("/var/run/squid.pid", F_OK) != -1) {
        /* Kill running squid */
        verbose_printf(1, "Flush squid iptables chain ... \n");
        safe_system("/sbin/iptables -t nat -F SQUID");
        verbose_printf(1, "Shutdown squid ... \n");
        safe_system("/usr/sbin/squid -k shutdown >/dev/null 2>/dev/null");
        c = 0;
        while ((c++ < 15) && (access("/var/run/squid.pid", F_OK) != -1)) {
            sleep(1);
        }

        if (access("/var/run/squid.pid", F_OK) != -1) {
            verbose_printf(1, "Really shutdown squid ... \n");
            safe_system("/usr/bin/killall -9 squid >/dev/null 2>/dev/null");
        }
    }
    if (access("/var/run/squid.pid", F_OK) != -1) {
        verbose_printf(2, "Remove leftover PID file ... \n");
        unlink("/var/run/squid.pid");
    }

    /* See if we need to flush/repair the cache */
    if (flag_flush) {
        struct passwd *pw;
        if ((pw = getpwnam("squid"))) {
            endpwent();         /* probably paranoia, but just in case.. */
            verbose_printf(1, "Flushing proxy cache ... \n");
            unpriv_system("/bin/rm -rf /var/log/cache/*", pw->pw_uid, pw->pw_gid);
        }
        else {
            fprintf(stderr, "User squid not found, cache not flushed\n");
            endpwent();
        }
    }

    int saferestart = 0;
    if (flag_repair) {
        struct passwd *pw;
        if ((pw = getpwnam("squid"))) {
            endpwent();         /* probably paranoia, but just in case.. */
            verbose_printf(1, "Repairing proxy cache ... \n");
            if (stat("/var/log/cache/swap.state", &st) == 0) {
                unpriv_system("/bin/rm -f /var/log/cache/swap.state", pw->pw_uid, pw->pw_gid);
            }
            saferestart = 1;
        }
        else {
            fprintf(stderr, "User squid not found, cache not repaired\n");
            endpwent();
        }
    }

    verbose_printf(1, "Reading Proxy settings ... \n");
    if (read_kv_from_file(&squid_kv, "/var/ipcop/proxy/settings") != SUCCESS) {
        fprintf(stderr, "Cannot read proxy settings\n");
        exit(1);
    }

    /* See if proxy is enabled and / or transparent */
    if (test_kv(squid_kv, "ENABLED_GREEN_1", "on") == SUCCESS) {
        enabled_green = 1;
    }
    if (test_kv(squid_kv, "TRANSPARENT_GREEN_1", "on") == SUCCESS) {
        transparent_green = 1;
    }
    if (test_kv(squid_kv, "ENABLED_BLUE_1", "on") == SUCCESS) {
        enabled_blue = 1;
    }
    if (test_kv(squid_kv, "TRANSPARENT_BLUE_1", "on") == SUCCESS) {
        transparent_blue = 1;
    }
    if (test_kv(squid_kv, "ENABLED_OVPN", "on") == SUCCESS) {
        enabled_ovpn = 1;
    }
    if (test_kv(squid_kv, "TRANSPARENT_OVPN", "on") == SUCCESS) {
        transparent_ovpn = 1;
    }

    /* Retrieve the proxy port */
    if (transparent_green || transparent_blue || transparent_ovpn) {
        if (find_kv_default(squid_kv, "PROXY_PORT", proxy_port) != SUCCESS) {
            strcpy(proxy_port, "8080");
        }
        else {
            if (strspn(proxy_port, NUMBERS) != strlen(proxy_port)) {
                fprintf(stderr, "Invalid proxy port: %s, defaulting to 8080\n", proxy_port);
                strcpy(proxy_port, "8080");
            }
        }
    }
    free_kv(&squid_kv);

    if (!enabled_green && !enabled_blue && !enabled_ovpn) {
        verbose_printf(1, "Proxy not enabled ... exit ... \n");
        return 0;
    }

    /* We can't start squid if .conf is missing */
    if (access("/var/ipcop/proxy/squid.conf", F_OK) == -1) {
        fprintf(stderr, "Configuration file squid.conf not found\n");
        exit(1);
    }

    /* Fetch ethernet/settings, exit on error */
    read_ethernet_settings(1);


    if (enabled_green || enabled_blue || enabled_ovpn) {
        /* rebuild firewall rules, proxy port may be different now */
        verbose_printf(1, "Rebuild firewall rules ... \n");
        safe_system("/usr/local/bin/setfwrules --ipcop");

        verbose_printf(1, "Create swap directories ... \n");
        if (safe_system("/usr/sbin/squid -s -z 2>/dev/null")) {
            verbose_printf(1, "Error creating swap directories ... \n");
        }
        verbose_printf(1, "Starting squid ... \n");
        if (saferestart)
            safe_system("/usr/sbin/squid -s -S");
        else
            safe_system("/usr/sbin/squid -s");
    }

    /* static (green/blue) interfaces must exist if transparence is requested */
    if (transparent_green && enabled_green && !ipcop_ethernet.count[GREEN]) {
        fprintf(stderr, "No GREEN device, not running transparent\n");
        exit(1);
    }

    if (transparent_blue && enabled_blue && !ipcop_ethernet.count[BLUE]) {
        fprintf(stderr, "No BLUE device, not running transparent\n");
        exit(1);
    }

    /* TODO: test for OpenVPN device if ovpn transparent is selected? */
    /* For now we use fixed tun0 and expect it to be present. */

    /* disable transparence for known IPsec networks */
    verbose_printf(1, "Reading IPsec settings ... \n");
    if (read_kv_from_file(&ipsec_kv, "/var/ipcop/ipsec/settings") != SUCCESS) {
        fprintf(stderr, "Cannot read IPsec settings\n");
        exit(1);
    }
    find_kv_default(ipsec_kv, "ENABLED_RED_1", enabled_IPsec);
    if (strcmp(enabled_IPsec, "on")) {
        find_kv_default(ipsec_kv, "ENABLED_BLUE_1", enabled_IPsec);
    }
    free_kv(&ipsec_kv);

    if (!strcmp(enabled_IPsec, "on")) {
        setdirectipsec (enabled_green && transparent_green,
                    enabled_blue && transparent_blue);
    }

    /*  TODO: disable transparence for OpenVPN networks, but only for
        OpenVPN net-2-net which we currently have not implemented */

    /* choose RED destination: 'localip' or 'red_netaddress/red_netmask' */
    char destination[STRING_SIZE] = "";
    if (strcmp(ipcop_ethernet.red_type[1], "STATIC") == 0) {
        snprintf(destination, STRING_SIZE, "%s/%s", ipcop_ethernet.address[RED][1], ipcop_ethernet.netmask[RED][1]);
    }
    else {
        if (ipcop_ethernet.red_address[1][0] && VALID_IP(ipcop_ethernet.red_address[1])) {
            snprintf(destination, STRING_SIZE, "%s", ipcop_ethernet.red_address[1]);
        }
    }

    /* RED may be down */
    if (!strlen(destination)) {
        verbose_printf(1, "Cannot determine RED network.\n");
    }
    else {
        verbose_printf(2, "Dest IP is set to: %s\n", destination);
    }

    /* install the transparency rules */
    /* green transparent ? */
    if (transparent_green && enabled_green) {
        /* direct http GREEN-->RED network */
        verbose_printf(1, "Setting transparent iptables rule for GREEN ... \n");
        if (snprintf(buffer, STRING_SIZE - 1,
                     "/sbin/iptables -t nat -A SQUID -i %s -p tcp -d %s --dport 80 -j RETURN",
                     ipcop_ethernet.device[GREEN][1], destination) >= STRING_SIZE) {
            fprintf(stderr, "Command too long\n");
            exit(1);
        }
        if (strlen(destination))
            safe_system(buffer);        /* only id known RED */

        /* install the redirect for other port http destinations from green */
        if (snprintf(buffer, STRING_SIZE - 1,
                     "/sbin/iptables -t nat -A SQUID -i %s -p tcp --dport 80 -j REDIRECT --to-port %s",
                     ipcop_ethernet.device[GREEN][1], proxy_port) >= STRING_SIZE) {
            fprintf(stderr, "Command too long\n");
            exit(1);
        }
        safe_system(buffer);
    }
    /* blue transparent ? */
    if (transparent_blue && enabled_blue) {
        /* direct http BLUE-->RED network */
        verbose_printf(1, "Setting transparent iptables rule for BLUE ... \n");
        if (snprintf(buffer, STRING_SIZE - 1,
                     "/sbin/iptables -t nat -A SQUID -i %s -p tcp -d %s --dport 80 -j RETURN",
                     ipcop_ethernet.device[BLUE][1], destination) >= STRING_SIZE) {
            fprintf(stderr, "Command too long\n");
            exit(1);
        }
        if (strlen(destination))
            safe_system(buffer);        /* only id known RED */

        /* install the redirect for other port http destinations from blue */
        if (snprintf(buffer, STRING_SIZE - 1,
                     "/sbin/iptables -t nat -A SQUID -i %s -p tcp --dport 80 -j REDIRECT --to-port %s",
                     ipcop_ethernet.device[BLUE][1], proxy_port) >= STRING_SIZE) {
            fprintf(stderr, "Command too long\n");
            exit(1);
        }
        safe_system(buffer);
    }
    /* OpenVPN roadwarriors transparent ? */
    if (transparent_ovpn && enabled_ovpn) {
        /* direct http OpenVPN-->RED network */
        verbose_printf(1, "Setting transparent iptables rule for OpenVPN RW ... \n");
        if (snprintf(buffer, STRING_SIZE - 1,
                     "/sbin/iptables -t nat -A SQUID -i %s -p tcp -d %s --dport 80 -j RETURN",
                     "tun0", destination) >= STRING_SIZE) {
            fprintf(stderr, "Command too long\n");
            exit(1);
        }
        if (strlen(destination))
            safe_system(buffer);        /* only id known RED */

        /* install the redirect for other port http destinations from OpenVPN */
        if (snprintf(buffer, STRING_SIZE - 1,
                     "/sbin/iptables -t nat -A SQUID -i %s -p tcp --dport 80 -j REDIRECT --to-port %s",
                     "tun0", proxy_port) >= STRING_SIZE) {
            fprintf(stderr, "Command too long\n");
            exit(1);
        }
        safe_system(buffer);
    }

    return 0;
}
Ejemplo n.º 6
0
int main(int argc, char **argv)
{
    int flag_boot = 0;
    int fd, config_fd, rc, pid;
    char buffer[STRING_SIZE_LARGE], command[STRING_SIZE_LARGE] = "/bin/sed -e '";
    NODEKV *ssh_kv = NULL;
    int enabled = 0;

    static struct option long_options[] =
    {
        { "boot", no_argument, 0, 'b' },
        { "verbose", no_argument, 0, 'v' },
        { "help", no_argument, 0, 'h' },
        { 0, 0, 0, 0}
    };
    int c;
    int option_index = 0;

    if (!(initsetuid()))
        exit(1);

    while ((c = getopt_long(argc, argv, "bv", long_options, &option_index)) != -1) {
        switch (c) {
        case 'b':              /* booting */
            flag_boot = 1;
            break;
        case 'v':              /* verbose */
            flag_verbose++;
            break;
        case 'h':
            usage(argv[0], 0);
        default:
            fprintf(stderr, "unknown option\n");
            usage(argv[0], 1);
        }
    }

    verbose_printf(1, "Reading SSHd settings ... \n");
    if (read_kv_from_file(&ssh_kv, "/var/ipcop/remote/settings") != SUCCESS) {
        fprintf(stderr, "Cannot read remote access settings\n");
        exit(1);
    }

    /* By using O_CREAT with O_EXCL open() will fail if the file already exists,
     * this prevents 2 copies of restartssh both trying to edit the config file
     * at once. It also prevents race conditions, but these shouldn't be
     * possible as /etc/ssh/ should only be writable by root anyhow
     */

    if ((config_fd = open("/etc/ssh/sshd_config.new", O_WRONLY | O_CREAT | O_EXCL, 0644)) == -1) {
        perror("Unable to open new config file");
        free_kv(&ssh_kv);
        exit(1);
    }

    verbose_printf(1, "Rebuilding SSHd config ... \n");
    if (test_kv(ssh_kv, "ENABLE_SSH_PROTOCOL1", "on") == SUCCESS)
        strlcat(command, "s/^Protocol .*$/Protocol 2,1/;", STRING_SIZE_LARGE - 1);
    else
        strlcat(command, "s/^Protocol .*$/Protocol 2/;", STRING_SIZE_LARGE - 1);

    if (test_kv(ssh_kv, "ENABLE_SSH_KEYS", "off") == SUCCESS)
        strlcat(command, "s/^RSAAuthentication .*$/RSAAuthentication no/;"
                "s/^PubkeyAuthentication .*$/PubkeyAuthentication no/;", STRING_SIZE_LARGE - 1);
    else
        strlcat(command, "s/^RSAAuthentication .*$/RSAAuthentication yes/;"
                "s/^PubkeyAuthentication .*$/PubkeyAuthentication yes/;", STRING_SIZE_LARGE - 1);

    if (test_kv(ssh_kv, "ENABLE_SSH_PASSWORDS", "off") == SUCCESS)
        strlcat(command, "s/^PasswordAuthentication .*$/PasswordAuthentication no/;", STRING_SIZE_LARGE - 1);
    else
        strlcat(command, "s/^PasswordAuthentication .*$/PasswordAuthentication yes/;", STRING_SIZE_LARGE - 1);

    if (test_kv(ssh_kv, "ENABLE_SSH_PORTFW", "on") == SUCCESS)
        strlcat(command, "s/^AllowTcpForwarding .*$/AllowTcpForwarding yes/", STRING_SIZE_LARGE - 1);
    else
        strlcat(command, "s/^AllowTcpForwarding .*$/AllowTcpForwarding no/", STRING_SIZE_LARGE - 1);

    if (test_kv(ssh_kv, "ENABLE_SSH", "on") == SUCCESS)
        enabled = 1;

    free_kv(&ssh_kv);

    snprintf(buffer, STRING_SIZE_LARGE - 1, "' /etc/ssh/sshd_config >&%d", config_fd);
    strlcat(command, buffer, STRING_SIZE_LARGE - 1);

    if ((rc = unpriv_system(command, 99, 99)) != 0) {
        fprintf(stderr, "sed returned bad exit code: %d\n", rc);
        close(config_fd);
        unlink("/etc/ssh/sshd_config.new");
        exit(1);
    }
    close(config_fd);
    if (rename("/etc/ssh/sshd_config.new", "/etc/ssh/sshd_config") != 0) {
        perror("Unable to replace old config file");
        unlink("/etc/ssh/sshd_config.new");
        exit(1);
    }

    memset(buffer, 0, STRING_SIZE_LARGE);

    verbose_printf(1, "Shutdown SSHd ... \n");
    if ((fd = open("/var/run/sshd.pid", O_RDONLY)) != -1) {
        if ((read(fd, buffer, STRING_SIZE_LARGE - 1) == -1) && !flag_boot) {
            fprintf(stderr, "Couldn't read from pid file\n");
        }
        else {
            pid = atoi(buffer);
            if (pid <= 1)
                fprintf(stderr, "Bad pid value\n");
            else {
                if (kill(pid, SIGTERM) == -1)
                    fprintf(stderr, "Unable to send SIGTERM\n");
                else
                    unlink("/var/run/sshd.pid");
            }
        }
        close(fd);
    }
    else {
        if (!flag_boot && (errno != ENOENT)) {
            perror("Unable to open pid file");
            exit(1);
        }
    }

    if (enabled) {
        verbose_printf(1, "Starting SSHd ... \n");
        safe_system("/usr/sbin/sshd");

        /* Give SSHd some time to start */
        sleep(1);

        if (access("/var/run/sshd.pid", F_OK) == -1) {
            fprintf(stderr, "Couldn't read from pid file, SSHd not running?\n");
        }
        else if (flag_verbose >= 2) {
            safe_system("echo -n \"SSHd running with PID \" && cat /var/run/sshd.pid");
        }
    }

    return 0;
}
Ejemplo n.º 7
0
int main(int argc, char *argv[])
{
    char hostname[STRING_SIZE] = "";
    char domainname[STRING_SIZE] = "";
    char buffer[STRING_SIZE];
    char string[STRING_SIZE];
    char *active, *ip, *host, *domain;

    static struct option long_options[] = {
        { "nosighup", no_argument, &flag_nosighup, 1 },
        { "verbose", no_argument, 0, 'v'},
        { "help", no_argument, 0, 'h'},
        {0, 0, 0, 0}
    };
    int c;
    int option_index = 0;

    if (!(initsetuid()))
        exit(1);

    while ((c = getopt_long(argc, argv, "hv", long_options, &option_index)) != -1) {
        switch (c) {
        case 0:
            break;
        case 'v':              /* verbose */
            flag_verbose++;
            break;
        case 'h':
            usage(argv[0], 0);
        default:
            fprintf(stderr, "unknown option\n");
            usage(argv[0], 1);
        }
    }

    atexit(exithandler);

    memset(buffer, 0, STRING_SIZE);

    /* Fetch ethernet/settings, exit on error */
    read_ethernet_settings(1);

    if (read_kv_from_file(&main_kv, "/var/ipcop/main/settings") != SUCCESS) {
        fprintf(stderr, "Couldn't read main settings\n");
        exit(1);
    }
    strcpy(hostname, SNAME);
    find_kv_default(main_kv, "HOSTNAME", hostname);
    find_kv_default(main_kv, "DOMAINNAME", domainname);
    free_kv(&main_kv);
    main_kv = NULL;

    if (!(fd = fopen("/var/ipcop/main/hosts", "r"))) {
        fprintf(stderr, "Couldn't open main hosts file\n");
        exit(1);
    }
    snprintf(string, STRING_SIZE, "/etc/hosts");
    if (!(hosts = fopen(string, "w"))) {
        fprintf(stderr, "Couldn't open /etc/hosts file\n");
        fclose(fd);
        fd = NULL;
        exit(1);
    }
    fprintf(hosts, "127.0.0.1\tlocalhost\n");

    if (strlen(domainname))
        fprintf(hosts, "%s\t%s.%s\t%s\n", ipcop_ethernet.address[GREEN][1], hostname, domainname, hostname);
    else
        fprintf(hosts, "%s\t%s\n", ipcop_ethernet.address[GREEN][1], hostname);

    while (fgets(buffer, STRING_SIZE, fd)) {
        buffer[strlen(buffer) - 1] = 0;
        if (buffer[0] == ',')
            continue;           /* disabled if empty field      */
        active = strtok(buffer, ",");
        if (strcmp(active, "off") == 0)
            continue;           /* or 'off'                     */

        ip = strtok(NULL, ",");
        host = strtok(NULL, ",");
        domain = strtok(NULL, ",");

        if (!(ip && host))
            continue;           /* bad line ? skip              */

        if (!VALID_IP(ip)) {
            fprintf(stderr, "Bad IP: %s\n", ip);
            continue;           /* bad ip, continue             */
        }

        if (strspn(host, LETTERS_NUMBERS "-") != strlen(host)) {
            fprintf(stderr, "Bad Host: %s\n", host);
            continue;           /* bad name, continue           */
        }

        if (domain)
            fprintf(hosts, "%s\t%s.%s\t%s\n", ip, host, domain, host);
        else
            fprintf(hosts, "%s\t%s\n", ip, host);
    }
    fclose(fd);
    fd = NULL;
    fclose(hosts);
    hosts = NULL;

    if (flag_nosighup) {
        verbose_printf(1, "Restart dnsmasq... \n");
        safe_system("/etc/rc.d/rc.dnsmasq --restart");
    }
    else {
        verbose_printf(1, "Send SIGHUP to dnsmasq... \n");
        safe_system("/etc/rc.d/rc.dnsmasq --sighup");
    }
    
    return 0;
}
Ejemplo n.º 8
0
int main(int argc, char *argv[])
{
    int tempfd;
    char command[STRING_SIZE];
    char filename[STRING_SIZE];
    char buffer[STRING_SIZE];
    char *timestamp = NULL;
    FILE *fd;
    NODEKV *kv_old = NULL;
    NODEKV *kv_new = NULL;
    char port_gui[STRING_SIZE];
    char port_ssh[STRING_SIZE];

    static struct option long_options[] =
    {
        { "hardware", no_argument, &flag_hardware, 1 },
        { "hostname", required_argument, &flag_hostname, 1 },
        { "import", no_argument, &flag_import, 1 },
        { "restore", required_argument, &flag_restore, 1},
        { "verbose", no_argument, 0, 'v' },
        { "help", no_argument, 0, 'h' },
        { 0, 0, 0, 0}
    };
    int c;
    int option_index = 0;
    char *opt_filename = NULL;

    while ((c = getopt_long(argc, argv, "r:v", long_options, &option_index)) != -1) {
        switch (c) {
        case 0:
            if (!strcmp("hostname", long_options[option_index].name)) {
                strcpy(hostname, optarg);
            }
            else if (!strcmp("restore", long_options[option_index].name)) {
                opt_filename = strdup(optarg);
            }
            break;
        case 'v':       /* verbose */
            flag_verbose++;
            break;
        case 'h':
            usage(argv[0], 0);
        default:
            fprintf(stderr, "unknown option\n");
            usage(argv[0], BACKUP_ERR_PARM);
        }
    }

    if (!flag_import && !flag_restore) {
        /* need at least one of import or restore */
        usage(argv[0], 1);
    }

    /* Init setuid */
    if (!(initsetuid()))
        exit(BACKUP_ERR_SUID);

    if (!flag_hostname) {
        gethostname(hostname, STRING_SIZE - 1);
    }

    if (flag_restore) {
        /* check filename valid, full file name length */
        if (strlen(opt_filename) != (strlen(MOUNTPOINT "/-YYYY-MM-DD_HH-MM-SS.dat")+ strlen(hostname))) {
            fprintf(stderr, "ipcoprscfg : bad file name\n");
            fprintf(stderr, "%s\n", hostname);
            fprintf(stderr, "%s\n", opt_filename);
            exit(BACKUP_ERR_FILENAME);
        }
        /* file in the path */
        if (!strstr(opt_filename, MOUNTPOINT)) {
            fprintf(stderr, "ipcoprscfg : wrong path\n");
            exit(BACKUP_ERR_PATHNAME);
        }
        /* and exist */
        if (access(opt_filename, F_OK) == -1) {
            fprintf(stderr, "Missing backup\n");
            exit(BACKUP_ERR_DAT);
        }
        strcpy(filename, opt_filename);
    }
    else {
        snprintf(filename, STRING_SIZE - 1, MOUNTPOINT "/%s.dat", hostname);
    }

    /* key file and encrypted .dat are required */
    if (access(BACKUP_KEY, F_OK) == -1) {
        fprintf(stderr, "Missing encryption key\n");
        exit(BACKUP_ERR_DECRYPT);
    }

    /* now exithandler will have something to do */
    atexit(exithandler);

    /* decrypt .dat file to /tmp/hostname.tar.gz */
    snprintf(command, STRING_SIZE - 1,
             "/usr/bin/openssl des3 -d -salt "
             "-in %s " "-out /tmp/%s.tar.gz " "-kfile " BACKUP_KEY "> /dev/null 2> /dev/null", filename, hostname);
    if (safe_system(command)) {
        fprintf(stderr, "Couldn't decrypt %s.dat archive\n", hostname);
        exit(BACKUP_ERR_DECRYPT);
    }

    /* create temporary directory for testing untar */
    strcpy(tmpdir, "/tmp/cfg_XXXXXX");
    if (mkdtemp(tmpdir) == NULL) {
        exit(BACKUP_ERR_ANY);
    }

    /* Start (test) untarring files from compressed archive */
    snprintf(command, STRING_SIZE - 1, "/bin/tar -C %s -xzvf /tmp/%s.tar.gz > /dev/null 2> /dev/null", tmpdir,
             hostname);
    if (safe_system(command)) {
        fprintf(stderr, "Invalid archive\n");
        exit(BACKUP_ERR_UNTARTST);
    }

    /* Backup version OK ? */
    if (testbackupversion(tmpdir) != SUCCESS) {
        fprintf(stderr, "No version or invalid version in archive\n");
        exit(BACKUP_ERR_VERSION);
    }


    /* If in import mode, read tagfile if include
     * or parse backup to read newest file time change */
    if (flag_import) {
        snprintf(filename, STRING_SIZE - 1, "%s/var/ipcop/backup.dat.time", tmpdir);
        if (access(filename, F_OK) == -1) {
            /* without tagfile include */
            strcpy(tmpdatefile, "/tmp/date.XXXXXX");
            if (!(tempfd = mkstemp(tmpdatefile)) > 0) {
                fprintf(stderr, "Couldn't create temporary file.\n");
                exit(BACKUP_ERR_ANY);
            }
            /* Parse all files of a backup 
             * to read last modification date.
             * The most recent date is written on tmp file */
            snprintf(command, STRING_SIZE - 1,
                     "/usr/bin/find %s -type f -exec "
                     "/bin/ls --time-style=+%%Y-%%m-%%d_%%H-%%M-%%S -l {} \\; | "
                     "/usr/bin/awk '{print $6}' | " "/usr/bin/sort -rn | /bin/head -n 1 >%s", tmpdir, tmpdatefile);
            if (safe_system(command)) {
                fprintf(stderr, "Couldn't write tmpdatefile\n");
                exit(BACKUP_ERR_ANY);
            }
            /* read the date */
            if (!(fd = fopen(tmpdatefile, "r"))) {
                perror("ipcoprscfg : Failed opening file tagfile");
                exit(BACKUP_ERR_ANY);
            }
            if (fgets(buffer, STRING_SIZE, fd)) {
                if (buffer[strlen(buffer) - 1] == '\n')
                    buffer[strlen(buffer) - 1] = '\0';
            }
            fclose(fd);
            timestamp = strtok(buffer, " ");
            /* Write tagfile for backup */
            snprintf(filename, STRING_SIZE - 1, MOUNTPOINT "/%s-%s.dat.time", hostname, timestamp);
            writetagfile(filename, timestamp);
        }
        else {
            /* date is available to be read directly */
            if (!(fd = fopen(filename, "r"))) {
                perror("ipcoprscfg : Failed opening file tagfile");
                exit(BACKUP_ERR_ANY);
            }
            if (fgets(buffer, STRING_SIZE, fd)) {
                timestamp = strtok(buffer, " ");
            }
            fclose(fd);

            /* Moving from ext3 to FAT system, system warn not
             * able to preserve ownership, change before */
            if (chown(filename, 99, 99)) {
                fprintf(stderr, "Couldn't chown .dat.time file\n");
                exit(BACKUP_ERR_ANY);
            }
            snprintf(command, STRING_SIZE - 1,
                     "/bin/mv %s " MOUNTPOINT "/%s-%s.dat.time", filename, hostname, timestamp);
            if (safe_system(command)) {
                perror("Failed to copy tagfile");
                exit(BACKUP_ERR_ANY);
            }
        }
        /* backup is valid, move to a name with date */
        snprintf(filename, STRING_SIZE - 1, MOUNTPOINT "/%s.dat", hostname);
        snprintf(command, STRING_SIZE - 1, "/bin/mv %s " MOUNTPOINT "/%s-%s.dat", filename, hostname, timestamp);
        if (safe_system(command)) {
            perror("Failed to copy backup");
            exit(BACKUP_ERR_ANY);
        }
        exit(0);
    }

    /* uncompress archive */
    snprintf(command, STRING_SIZE - 1, "/bin/gunzip -d -f /tmp/%s.tar.gz", hostname);
    safe_system(command);

    /* remove hardware specific settings */
    if (flag_hardware == 0) {
        snprintf(command, STRING_SIZE - 1,
                 "/bin/tar --delete --file=/tmp/%s.tar -T /var/ipcop/backup/exclude.hardware", hostname);
        safe_system(command);
    }

    /* get current ports for GUI and ssh */
    if (read_kv_from_file(&kv_old, "/var/ipcop/main/settings") == SUCCESS) {
        if (find_kv_default(kv_old, "GUIPORT", port_gui) != SUCCESS) {
            strcpy(port_gui, "8443");
        }
        if (find_kv_default(kv_old, "SSHPORT", port_ssh) != SUCCESS) {
            strcpy(port_ssh, "8022");
        }

        free_kv(&kv_old);
    }

    /* Start (real) untarring files from compressed archive */
    snprintf(command, STRING_SIZE - 1,
             "/bin/tar -X /var/ipcop/backup/exclude.system -C / -xvf /tmp/%s.tar &>/dev/null", hostname);
    if (safe_system(command)) {
        fprintf(stderr, "Error restoring archive\n");
        exit(BACKUP_ERR_UNTAR);
    }
    else {
        /* TODO: here we will need to add mechanism for upgrade from 1.4.xx configuration files */

        /* get new ports for GUI and ssh and check for modifications */
        if (read_kv_from_file(&kv_new, "/var/ipcop/main/settings") == SUCCESS) {
            if (test_kv(kv_new, "GUIPORT", port_gui) != SUCCESS) {
                find_kv_default(kv_new, "GUIPORT", port_gui);
                snprintf(command, STRING_SIZE, "/usr/local/bin/setreservedports.pl --nocheck --gui %s", port_gui);
                safe_system(command);
            }
            if (test_kv(kv_new, "SSHPORT", port_ssh) != SUCCESS) {
                find_kv_default(kv_new, "SSHPORT", port_ssh);
                snprintf(command, STRING_SIZE, "/usr/local/bin/setreservedports.pl --nocheck --ssh %s", port_ssh);
                safe_system(command);
            }

            free_kv(&kv_new);
        }

        if (safe_system("/usr/local/bin/upgrade.sh &>/dev/null")) {
            fprintf(stderr, "Error upgrading data from backup!\n");
            exit(BACKUP_ERR_ANY);
        }
    }
    exit(0);
}
Ejemplo n.º 9
0
void uninit_wc(void)
{
	free_kv(global_wordcloud1);
	free_kv(global_wordcloud2);
}