Esempio n. 1
0
static int cifs_server(CLI *c) {
    u8 buffer[128];
    u8 response_access_denied[5] = {0x83, 0, 0, 1, 0x81};
    u8 response_use_ssl[5] = {0x83, 0, 0, 1, 0x8e};
    u16 len;

    if(read_blocking(c, c->local_rfd.fd, buffer, 4)<0) /* NetBIOS header */
        return -1;
    len=buffer[3];
    len|=(u16)(buffer[2]) << 8;
    if(len>sizeof(buffer)-4) {
        s_log(LOG_ERR, "Received block too long");
        return -1;
    }
    if(read_blocking(c, c->local_rfd.fd, buffer+4, len)<0)
        return -1;
    if(buffer[0]!=0x81){ /* NB_SSN_REQUEST */
        s_log(LOG_ERR, "Client did not send session setup");
        write_blocking(c, c->local_wfd.fd, response_access_denied, 5);
        return -1;
    }
    if(write_blocking(c, c->local_wfd.fd, response_use_ssl, 5)<0)
        return -1;
    return 0; /* OK */
}
Esempio n. 2
0
static int auth_libwrap(CLI *c) {
#ifdef USE_LIBWRAP
    struct request_info request;
    int fd[2];
    int result=0; /* deny by default */

    if(pipe(fd)<0) {
        ioerror("pipe");
        return -1;
    }
    if(alloc_fd(fd[0]) || alloc_fd(fd[1]))
        return -1;
    switch(fork()) {
    case -1:    /* error */
        close(fd[0]);
        close(fd[1]);
        ioerror("fork");
        return -1;
    case  0:    /* child */
        close(fd[0]); /* read side */
        request_init(&request,
            RQ_DAEMON, c->opt->servname, RQ_FILE, c->local_rfd.fd, 0);
        fromhost(&request);
        result=hosts_access(&request);
        write_blocking(c, fd[1], (u8 *)&result, sizeof(result));
            /* ignore the returned error */
        close(fd[1]); /* write side */
        _exit(0);
    default:    /* parent */
        close(fd[1]); /* write side */
        read_blocking(c, fd[0], (u8 *)&result, sizeof(result));
            /* ignore the returned error */
        close(fd[0]); /* read side */
        /* no need to wait() for zombies here:
         *  - in UCONTEXT/PTHREAD mode they're removed using the signal pipe
         *  - in FORK mode they're removed with the client process */
    }

    if(!result) {
        s_log(LOG_WARNING, "Connection from %s REFUSED by libwrap",
            c->accepting_address);
        s_log(LOG_DEBUG, "See hosts_access(5) manual for details");
        return -1; /* FAILED */
    }
    s_log(LOG_DEBUG, "Connection from %s permitted by libwrap",
        c->accepting_address);
#endif
    return 0; /* OK */
}
Esempio n. 3
0
static int cifs_client(CLI *c) {
    u8 buffer[5];
    u8 request_dummy[4] = {0x81, 0, 0, 0}; /* a zero-length request */

    if(write_blocking(c, c->remote_fd.fd, request_dummy, 4)<0)
        return -1;
    if(read_blocking(c, c->remote_fd.fd, buffer, 5)<0) {
        s_log(LOG_ERR, "Failed to read NetBIOS response");
        return -1;
    }
    if(buffer[0]!=0x83) { /* NB_SSN_NEGRESP */
        s_log(LOG_ERR, "Negative response expected");
        return -1;
    }
    if(buffer[2]!=0 || buffer[3]!=1) { /* length != 1 */
        s_log(LOG_ERR, "Unexpected NetBIOS response size");
        return -1;
    }
    if(buffer[4]!=0x8e) { /* use SSL */
        s_log(LOG_ERR, "Remote server does not require SSL");
        return -1;
    }
    return 0; /* OK */
}
Esempio n. 4
0
void libwrap_auth(CLI *c, char *accepted_address) {
    int result=0; /* deny by default */
#ifdef USE_PTHREAD
    static volatile int num_busy=0, roundrobin=0;
    int retval, my_process;
    static pthread_mutex_t mutex=PTHREAD_MUTEX_INITIALIZER;
    static pthread_cond_t cond=PTHREAD_COND_INITIALIZER;
#endif /* USE_PTHREAD */

    if(!c->opt->option.libwrap) /* libwrap is disabled for this service */
        return; /* allow connection */
#ifdef HAVE_STRUCT_SOCKADDR_UN
    if(c->peer_addr.sa.sa_family==AF_UNIX) {
        s_log(LOG_INFO, "Libwrap is not supported on Unix sockets");
        return;
    }
#endif
#ifdef USE_PTHREAD
    if(num_processes) {
        s_log(LOG_DEBUG, "Waiting for a libwrap process");

        retval=pthread_mutex_lock(&mutex);
        if(retval) {
            errno=retval;
            ioerror("pthread_mutex_lock");
            longjmp(c->err, 1);
        }
        while(num_busy==num_processes) { /* all child processes are busy */
            retval=pthread_cond_wait(&cond, &mutex);
            if(retval) {
                errno=retval;
                ioerror("pthread_cond_wait");
                longjmp(c->err, 1);
            }
        }
        while(busy[roundrobin]) /* find a free child process */
            roundrobin=(roundrobin+1)%num_processes;
        my_process=roundrobin; /* the process allocated by this thread */
        ++num_busy; /* the child process has been allocated */
        busy[my_process]=1; /* mark the child process as busy */
        retval=pthread_mutex_unlock(&mutex);
        if(retval) {
            errno=retval;
            ioerror("pthread_mutex_unlock");
            longjmp(c->err, 1);
        }

        s_log(LOG_DEBUG, "Acquired libwrap process #%d", my_process);
        write_fd(ipc_socket[2*my_process], c->opt->servname,
            strlen(c->opt->servname)+1, c->local_rfd.fd);
        read_blocking(c, ipc_socket[2*my_process],
            (u8 *)&result, sizeof result);
        s_log(LOG_DEBUG, "Releasing libwrap process #%d", my_process);

        retval=pthread_mutex_lock(&mutex);
        if(retval) {
            errno=retval;
            ioerror("pthread_mutex_lock");
            longjmp(c->err, 1);
        }
        busy[my_process]=0; /* mark the child process as free */
        --num_busy; /* the child process has been released */
        if(num_busy==num_processes-1) { /* need to wake up a thread */
            retval=pthread_cond_signal(&cond); /* signal waiting threads */
            if(retval) {
                errno=retval;
                ioerror("pthread_cond_signal");
                longjmp(c->err, 1);
            }
        }
        retval=pthread_mutex_unlock(&mutex);
        if(retval) {
            errno=retval;
            ioerror("pthread_mutex_unlock");
            longjmp(c->err, 1);
        }

        s_log(LOG_DEBUG, "Released libwrap process #%d", my_process);
    } else
#endif /* USE_PTHREAD */
    { /* use original, synchronous libwrap calls */
        enter_critical_section(CRIT_LIBWRAP);
        result=check(c->opt->servname, c->local_rfd.fd);
        leave_critical_section(CRIT_LIBWRAP);
    }
    if(!result) {
        s_log(LOG_WARNING, "Service [%s] REFUSED by libwrap from %s",
            c->opt->servname, accepted_address);
        s_log(LOG_DEBUG, "See hosts_access(5) manual for details");
        longjmp(c->err, 1);
    }
    s_log(LOG_DEBUG, "Service [%s] permitted by libwrap from %s",
        c->opt->servname, accepted_address);
}