Esempio n. 1
0
struct client_ctx *socket_listen(struct socket *s)
{
	socklen_t len = sizeof(struct sockaddr_in);
	int fd = accept(s->fd, (struct sockaddr *) &cli.addr, &len);
	if (fd == -1)
		return 0;

	struct client_ctx *cc = calloc(sizeof(*cc), 1);

	cc->fd = fd;
	socket_clientaddr(cc);
	
	if (isbanned(cc)){
		socket_puts(cc, "Banned lol\n");
		socket_close(cc);
		free(cc);
		return 0;
	}

	return cc;
}
Esempio n. 2
0
void ident_check(struct descriptor_data *d, int pulse)
{
  fd_set fd, efd;
  int rc, rmt_port, our_port, len;
  char user[256], *p;

  extern struct timeval null_time;
  extern int port;

  /*
   * Each pulse, this checks if the ident is ready to proceed to the
   * next state, by calling select to see if the socket is writeable
   * (connected) or readable (response waiting).  
   */

  switch (STATE(d)) {
    case CON_IDCONING:
      /* waiting for connect() to finish */

      if (d->ident_sock != INVALID_SOCKET) {
        FD_ZERO(&fd);
        FD_ZERO(&efd);
        FD_SET(d->ident_sock, &fd);
        FD_SET(d->ident_sock, &efd);
      }

      if ((rc = select(d->ident_sock + 1, (fd_set *) 0, &fd, &efd, &null_time)) == 0)
        break;

      else if (rc < 0) {
        logerror("ident check select (conning)");
        STATE(d) = CON_ASKNAME;
        break;
      }

      if (FD_ISSET(d->ident_sock, &efd)) {
        /* exception, such as failure to connect */
        STATE(d) = CON_ASKNAME;
        break;
      }

      STATE(d) = CON_IDCONED;
      break;

    case CON_IDCONED:
      /* connected, write request */

      sprintf(buf, "%d, %d\n\r", ntohs(d->peer_port), port);

      len = strlen(buf);
#ifdef CIRCLE_WINDOWS
      if (send(d->ident_sock, buf, len, 0) < 0) {
#else
      if (write(d->ident_sock, buf, len) != len) {
        if (errno != EPIPE) /* read end closed (no remote identd) */
#endif
          logerror("ident check write (conned)");

        STATE(d) = CON_ASKNAME;
        break;
      }

      STATE(d) = CON_IDREADING;
      break;

    case CON_IDREADING:
      /* waiting to read */

      if (d->ident_sock != INVALID_SOCKET) {
        FD_ZERO(&fd);
        FD_ZERO(&efd);
        FD_SET(d->ident_sock, &fd);
        FD_SET(d->ident_sock, &efd);
      }

      if ((rc = select(d->ident_sock + 1, &fd, (fd_set *) 0, &efd, &null_time)) == 0)
        break;

      else if (rc < 0) {
        logerror("ident check select (reading)");
        STATE(d) = CON_ASKNAME;
        break;
      }

      if (FD_ISSET(d->ident_sock, &efd)) {
        STATE(d) = CON_ASKNAME;
        break;
      }

      STATE(d) = CON_IDREAD;
      break;

    case CON_IDREAD:
      /* read ready, get the info */

#ifdef CIRCLE_WINDOWS
      if ((len = recv(d->ident_sock, buf, sizeof(buf) - 1, 0)) < 0)
#else
      if ((len = read(d->ident_sock, buf, sizeof(buf) - 1)) < 0)
#endif
        logerror("ident check read (read)");

      else {
        buf[len] = '\0';
        if (sscanf(buf, "%u , %u : USERID :%*[^:]:%255s", &rmt_port, &our_port, user) != 3) {

          /* check if error or malformed */
          if (sscanf(buf, "%u , %u : ERROR : %255s", &rmt_port, &our_port, user) == 3) {
            sprintf(buf2, "Ident error from %s: \"%s\"", d->hostIP, user);
            stderr_log(buf2);
          } else {
            /* strip off trailing newline */
            for (p = buf + len - 1; p > buf && ISNEWL(*p); p--)
              ;
            p[1] = '\0';

            sprintf(buf2, "Malformed ident response from %s: \"%s\"", d->hostIP, buf);
            stderr_log(buf2);
          }
        } else {

          len = HOST_LENGTH - strlen(d->hostIP);

          if (len > 0) {
            strncpy(buf2, user, len - 1);
            buf2[len - 1] = '\0';
            strcpy(d->username, buf2);
          }

          /* if len <= 0, no space for username */
        }
      }

      STATE(d) = CON_ASKNAME;
      break;

    case CON_ASKNAME:
      /* ident complete, ask for name */

      /* close up the ident socket, if one is opened. */
      if (d->ident_sock != INVALID_SOCKET) {
        close(d->ident_sock);
        d->ident_sock = INVALID_SOCKET;
      }
      d->idle_tics = 0;

      /* extra ban check */
      if ((d->host[0] != '\0' && isbanned(d->host) == BAN_ALL) || isbanned(d->hostIP)) {
        if (d->host[0] != '\0') {
          sprintf(buf, "Connection attempt denied from [%s]", d->host);
        } else {
          sprintf(buf, "Connection attempt denied from [%s]", d->hostIP);
        }
        mudlog(buf, 'S', COM_IMMORT, TRUE);
        close_socket(d);
        return;
      }

      /* SEND_TO_Q("\x1B[2K\n\rBy what name do you wish to be known? ", d); */
      STATE(d) = CON_GET_TERMTYPE;
      return;

    default:
      return;
  }

  /*
   * Print a dot every second so the user knows he hasn't been forgotten.
   * Allow the user to go on anyways after waiting IDENT_TIMEOUT seconds.
   */
  if ((pulse % PASSES_PER_SEC) == 0) {
    SEND_TO_Q(".", d);

    if (d->idle_tics++ >= IDENT_TIMEOUT)
      STATE(d) = CON_ASKNAME;
  }
}

/* returns 1 if waiting for ident to complete, else 0 */
int waiting_for_ident(struct descriptor_data *d)
{
  switch (STATE(d)) {
    case CON_IDCONING:
    case CON_IDCONED:
    case CON_IDREADING:
    case CON_IDREAD:
    case CON_ASKNAME:
      return 1;
  }
  return 0;
}