Esempio n. 1
0
int privsep_privpart_bindresport(const int psfd, 
                                 const PrivSepQuery * const query)
{
    static const in_port_t portlist[] = FTP_ACTIVE_SOURCE_PORTS;
    const in_port_t *portlistpnt = portlist;    
    int fd;
    int on = 1;
    int ret;
    
    if ((fd = socket(query->bindresport.protocol,
                     SOCK_STREAM, IPPROTO_TCP)) == -1) {
        goto bye;
    }
# ifdef SO_REUSEPORT
    (void) setsockopt(fd, SOL_SOCKET, SO_REUSEPORT, (char *) &on, sizeof on);
# else
    (void) setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (char *) &on, sizeof on);
# endif
    privsep_priv_user();
    for (;;) {
        if (query->bindresport.protocol == PF_INET6) {
            STORAGE_PORT6(query->bindresport.ss) = htons(*portlistpnt);
        } else {
            STORAGE_PORT(query->bindresport.ss) = htons(*portlistpnt);
        }
        if (bind(fd, (struct sockaddr *) &query->bindresport.ss,
                 STORAGE_LEN(query->bindresport.ss)) == 0) {
            break;
        }
# ifdef USE_ONLY_FIXED_DATA_PORT
        (void) sleep(1U);
# else
        if (*portlistpnt == (in_port_t) 0U) {
            break;
        }
        portlistpnt++;
# endif        
    }
    privsep_unpriv_user();
    
    bye:    
    ret = privsep_sendfd(psfd, fd);
    ret |= close(fd);
    
    return ret;
}
Esempio n. 2
0
int filter_overwrite_sa_with_reply_map(const msgpack_object_map * const map,
                                       const char * const key_host,
                                       const char * const key_port,
                                       struct sockaddr_storage * const sa,
                                       socklen_t * const sa_len)
{
    if (sa == NULL) {
        return 0;
    }
    const msgpack_object * const obj_host =
        msgpack_get_map_value_for_key(map, key_host);
    if (obj_host != NULL &&
        obj_host->type == MSGPACK_OBJECT_RAW &&
        obj_host->via.raw.size > 0 &&
        obj_host->via.raw.size < NI_MAXHOST) {
        struct addrinfo *ai, hints;
        memset(&hints, 0, sizeof hints);
        hints.ai_family = AF_UNSPEC;
        hints.ai_socktype = SOCK_STREAM;
        hints.ai_protocol = IPPROTO_TCP;
        hints.ai_flags = NI_NUMERICHOST | AI_ADDRCONFIG;
        char new_host[NI_MAXHOST];
        memcpy(new_host, obj_host->via.raw.ptr,
               obj_host->via.raw.size);
        new_host[obj_host->via.raw.size] = 0;
        const int gai_err = getaddrinfo(new_host, NULL, &hints, &ai);
        if (gai_err == 0) {
            assert(ai->ai_addrlen <= sizeof *sa);
            if (ai->ai_family == AF_INET &&
                *sa_len >= (socklen_t) sizeof(STORAGE_SIN_ADDR(*sa))) {
                assert((size_t) ai->ai_addrlen >=
                       sizeof(STORAGE_SIN_ADDR(*sa)));
                memcpy(&STORAGE_SIN_ADDR(*sa),
                       &STORAGE_SIN_ADDR(* (struct sockaddr_storage *)
                                         (void *) ai->ai_addr),
                       sizeof(STORAGE_SIN_ADDR(*sa)));
                *sa_len = ai->ai_addrlen;
                STORAGE_FAMILY(*sa) = ai->ai_family;
                SET_STORAGE_LEN(*sa, ai->ai_addrlen);
            } else if (ai->ai_family == AF_INET6 &&
                      *sa_len >= (socklen_t) sizeof(STORAGE_SIN_ADDR6(*sa))) {
                assert((size_t) ai->ai_addrlen >=
                       sizeof(STORAGE_SIN_ADDR6(*sa)));
                memcpy(&STORAGE_SIN_ADDR6(*sa),
                       &STORAGE_SIN_ADDR6(* (struct sockaddr_storage *)
                                          (void *) ai->ai_addr),
                       sizeof(STORAGE_SIN_ADDR6(*sa)));
                *sa_len = ai->ai_addrlen;
                STORAGE_FAMILY(*sa) = ai->ai_family;
                SET_STORAGE_LEN(*sa, ai->ai_addrlen);
            }
            freeaddrinfo(ai);
        }
    }    

    const msgpack_object * const obj_port =
        msgpack_get_map_value_for_key(map, key_port);
    if (obj_port != NULL &&
        obj_port->type == MSGPACK_OBJECT_POSITIVE_INTEGER) {
        if (obj_port->via.i64 >= 0 &&
            obj_port->via.i64 <= 65535) {            
            if (STORAGE_FAMILY(*sa) == AF_INET) {
                STORAGE_PORT(*sa) = htons((in_port_t) obj_port->via.i64);
            } else if (STORAGE_FAMILY(*sa) == AF_INET6) {
                STORAGE_PORT6(*sa) = htons((in_port_t) obj_port->via.i64);
            }
        }
    }   
    return 0;
}