예제 #1
0
파일: butch.c 프로젝트: yasar11732/butch
//return 0 on success.
//checks if filesize and/or sha512 matches, if used.
int verify_tarball(pkgconfig* cfg, pkgdata* package) {
	char buf[4096];
	char* error;
	SHA512_CTX ctx;
	int fd;
	uint64_t pos, len = 0, nread;
	stringptr hash;
	get_tarball_filename_with_path(cfg, package, buf, sizeof(buf));
	if(package->filesize) {
		len = getfilesize(buf);
		if(len < package->filesize) {
			log_put(2, VARISL("WARNING: "), VARIC(buf), VARISL(" filesize too small!"), NULL);
			return 1;
		} else if (len > package->filesize) {
			log_put(2, VARISL("WARNING: "), VARIC(buf), VARISL(" filesize too big!"), NULL);
			return 2;
		}
	}
	if(package->sha512) {
		if(!len) len = getfilesize(buf);
			
		fd = open(buf, O_RDONLY);
		if(fd == -1) {
			error = strerror(errno);
			log_put(2, VARISL("WARNING: "), VARIC(buf), VARISL(" failed to open: "), VARIC(error), NULL);
			return 3;
		}
		SHA512_Init(&ctx);
		pos = 0;
		while(pos < len) {
			nread = read(fd, buf, sizeof(buf));
			SHA512_Update(&ctx, (const uint8_t*) buf, nread);
			pos += nread;
		}
		close(fd);
		SHA512_End(&ctx, (char*) buf);
		hash.ptr = buf; hash.size = strlen(buf);
		if(!EQ(&hash, package->sha512)) {
			log_put(2, VARISL("WARNING: "), VARIS(package->name), VARISL(" sha512 mismatch, got "), 
				VARIS(&hash), VARISL(", expected "), VARIS(package->sha512), NULL);
			return 4;
		}
	}
	return 0;
}
예제 #2
0
파일: butch.c 프로젝트: yasar11732/butch
void print_queue(pkgstate* state, jobtype jt) {
	sblist* queue = (jt == JT_DOWNLOAD) ? state->dl_queue : state->build_queue;
	char *queuename = (jt == JT_DOWNLOAD) ? "download" : "build";
	pkg_exec* listitem;
	
	log_put(1, VARISL("*** "), VARIC(queuename), VARISL("queue ***"), NULL);
	sblist_iter(queue, listitem) {
		log_puts(1, listitem->name);
		log_putln(1);
	}
예제 #3
0
static int socksserver_on_clientconnect (void* userdata, struct sockaddr_storage* clientaddr, int fd) {
    socksserver* srv = (socksserver*) userdata;
    char buffer[256];
    (void) buffer;
    if(CONFIG_LOG && srv->log && clientaddr) {
        logstart();
        printfd(fd);
        LOGPUT(1, VARISL(" connect from: "), VARIC(get_client_ip(clientaddr, buffer, sizeof(buffer))), NULL);
    }

    if(fd < 3 || fd >= MAX_FD) {
        rocksockserver_disconnect_client(&srv->serva, fd);
        return -2;
    }

    fdinfo* client = &srv->clients[fdindex(fd)];

    // put into nonblocking mode, so that writes will not block the server
    int flags = fcntl(fd, F_GETFL);
    if(flags == -1) return -1;
    if(fcntl(fd, F_SETFL, flags | O_NONBLOCK) == -1) return -2;

    client->data = find_free_buffer(srv);
    if (!client->data) {
        if(CONFIG_LOG && srv->log) {
            logstart();
            LOGPUTS(1, SPL("warning: couldnt find free buffer\n"));
        }
        rocksockserver_disconnect_client(&srv->serva, fd);
        return -2;
    }

    client->state = SS_CONNECTED;
    client->data->state = BS_IDLE;
    client->data->start = 0;
    client->target_fd = -1;

    return 0;
}
예제 #4
0
static int socksserver_connect_request(socksserver* srv, int fd) {
    fdinfo* client = &srv->clients[fdindex(fd)];
    size_t i = 0;
    unsigned char dlen = 0;
    unsigned char* buf = client->data->buf;
    int flags, ret;
    host_info addr;

    struct addrinfo addrbuf;
    struct sockaddr sockbuf;

    memset(&addr, 0, sizeof(addr));
    memset(&addrbuf, 0, sizeof(addrbuf));
    memset(&sockbuf, 0, sizeof(sockbuf));

    addrbuf.ai_addr = &sockbuf;
    addr.hostaddr = &addrbuf;


    if(!client->data->start) return -1;
    if(buf[i++] != 5) return EC_NOT_ALLOWED; // check first byte whenever the message length is > 0 to not waste resources on maldoers
    if(client->data->start < 1+1+1+1+4+2) return -1;

    if(buf[i++] != 1) return EC_COMMAND_NOT_SUPPORTED; // we support only the connect method.
    if(buf[i++] != 0) return EC_GENERAL_FAILURE;
    switch(buf[i++]) {
    case 1:
        //ipv4
        memcpy(&((struct sockaddr_in*) addr.hostaddr->ai_addr)->sin_addr, buf + 4, 4);
        memcpy(&((struct sockaddr_in*) addr.hostaddr->ai_addr)->sin_port, buf + 8, 2);
        ((struct sockaddr_in*) addr.hostaddr->ai_addr)->sin_family = PF_INET;
        addr.hostaddr->ai_addr->sa_family = PF_INET;
        addr.hostaddr->ai_addrlen = sizeof(struct sockaddr_in);
        break;
    case 3:
        //dns
        if(CONFIG_DNS) {
            dlen = buf[i++];
            if(client->data->start < 1U+1U+1U+1U+1U+dlen+2U) return -1;
            addr.port = my_ntohs(buf + i + dlen);
            buf[i + dlen] = 0;
            addr.host = (char*) (buf + i);
            if(CONFIG_IPV6) addr.hostaddr = NULL;
            if(!resolve_host(&addr)) {
                if(CONFIG_IPV6) {
                    memcpy(&addrbuf, addr.hostaddr, sizeof(struct addrinfo));
                    freeaddrinfo(addr.hostaddr);
                    addr.hostaddr = &addrbuf;
                }
            } else goto notsupported;
            break;
        } else goto notsupported;
    case 4: //ipv6
        if(CONFIG_IPV6) {
            if(client->data->start < 1+1+1+1+16+2) return -1;
            memcpy(&((struct sockaddr_in6*) addr.hostaddr->ai_addr)->sin6_addr, buf + 4, 16);
            memcpy(&((struct sockaddr_in6*) addr.hostaddr->ai_addr)->sin6_port, buf + 20, 2);
            ((struct sockaddr_in6*) addr.hostaddr->ai_addr)->sin6_family = PF_INET6;
            addr.hostaddr->ai_addr->sa_family = PF_INET6;
            addr.hostaddr->ai_addrlen = sizeof(struct sockaddr_in6);
            break;
        }
    default:
notsupported:
        return EC_ADDRESSTYPE_NOT_SUPPORTED;
    }
    client->target_fd = socket(addr.hostaddr->ai_addr->sa_family, SOCK_STREAM, 0);
    if(client->target_fd == -1) {
neterror:
        switch(errno) {
        case ENETDOWN:
        case ENETUNREACH:
        case ENETRESET:
            return EC_NET_UNREACHABLE;
        case EHOSTUNREACH:
        case EHOSTDOWN:
            return EC_HOST_UNREACHABLE;
        case ECONNREFUSED:
            return EC_CONN_REFUSED;
        default:
            return EC_GENERAL_FAILURE;
        }
    }

    if(client->target_fd >= MAX_FD) {
        close(client->target_fd);
        return EC_GENERAL_FAILURE;
    }

    flags = fcntl(client->target_fd, F_GETFL);
    if(flags == -1) return EC_GENERAL_FAILURE;

    if(fcntl(client->target_fd, F_SETFL, flags | O_NONBLOCK) == -1) return EC_GENERAL_FAILURE;

    ret = connect(client->target_fd, addr.hostaddr->ai_addr, addr.hostaddr->ai_addrlen);
    if(ret == -1) {
        ret = errno;
        if (!(ret == EINPROGRESS || ret == EWOULDBLOCK))
            goto neterror;
    }

    srv->clients[fdindex(client->target_fd)].state = SS_SOCKSTARGET;
    srv->clients[fdindex(client->target_fd)].data = client->data;
    srv->clients[fdindex(client->target_fd)].target_fd = fd;
    rocksockserver_watch_fd(&srv->serva, client->target_fd);

    if(CONFIG_LOG && srv->log) {
        if(get_client_ip((struct sockaddr_storage*) addr.hostaddr->ai_addr, (char*) buf, CLIENT_BUFSIZE)) {
            logstart();
            printfd(fd);
            LOGPUTS(1, SPLITERAL(" -> "));
            printfd(client->target_fd);
            LOGPUT(1, VARISL(" <"), VARIC((char*)buf), VARISL(">"), NULL);
        }
    }

    return EC_SUCCESS;
}