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 */ }
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 */ }
void fdputline(CLI *c, int fd, char *line) { char tmpline[STRLEN]; const char crlf[]="\r\n"; int len; if(strlen(line)+2>=STRLEN) { /* 2 for crlf */ s_log(LOG_ERR, "Line too long in fdputline"); longjmp(c->err, 1); } safecopy(tmpline, line); safeconcat(tmpline, crlf); len=strlen(tmpline); write_blocking(c, fd, tmpline, len); tmpline[len-2]='\0'; /* remove CRLF */ safestring(tmpline); s_log(LOG_DEBUG, " -> %s", tmpline); }
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 */ }