Esempio n. 1
0
int main(int argc, char *argv[])
{
	int numthreads;
	if (!new_listener(argv[1], echo_start, NULL))
		fatal("failed to create new listener!\n");

	numthreads = argc > 3 ? atoi(argv[2]) : 0;
	if (numthreads > 0) {
		int i;
		pthread_t thrds[numthreads];
		for (i = 0; i < numthreads; ++i)
			if (pthread_create(&thrds[i], NULL, start_thread, conn_loop) != 0)
				return 1;
		struct pollfd pfd;
		pfd.fd = STDIN_FILENO;
		pfd.events = POLLIN;

		if (poll(&pfd, 1, -1) && pfd.revents & POLLIN) {
			printf("Key pressed, terminating...\n");
			pthread_exit(NULL);
		}
	} else
		conn_loop();
	return 0;
}
Esempio n. 2
0
/* Add a new forwarding from port -> desthost:destport
 sets up a listener on the local machine on port
 */
char *pfd_addforward(char *desthost, int destport, int port)
{
    static struct plug_function_table fn_table = {
	pfd_closing,
	pfd_receive,		       /* should not happen... */
	pfd_sent,		       /* also should not happen */
	pfd_accepting
    };

    char *err;
    struct PFwdPrivate *pr;
    Socket s;

    /*
     * Open socket.
     */
    pr = (struct PFwdPrivate *) smalloc(sizeof(struct PFwdPrivate));
    pr->fn = &fn_table;
    pr->c = NULL;
    strcpy(pr->hostname, desthost);
    pr->port = destport;
    pr->throttled = pr->throttle_override = 0;
    pr->ready = 0;
    pr->waiting = NULL;

    pr->s = s = new_listener(port, (Plug) pr, !cfg.lport_acceptall);
    if ((err = sk_socket_error(s))) {
	sfree(pr);
	return err;
    }

    sk_set_private_ptr(s, pr);

    return NULL;
}
Esempio n. 3
0
/* returns DROPBEAR_SUCCESS or DROPBEAR_FAILURE */
int x11req(struct ChanSess * chansess) {

	int fd;

	if (!svr_pubkey_allows_x11fwd()) {
		return DROPBEAR_FAILURE;
	}

	/* we already have an x11 connection */
	if (chansess->x11listener != NULL) {
		return DROPBEAR_FAILURE;
	}

	chansess->x11singleconn = buf_getbool(ses.payload);
	chansess->x11authprot = buf_getstring(ses.payload, NULL);
	chansess->x11authcookie = buf_getstring(ses.payload, NULL);
	chansess->x11screennum = buf_getint(ses.payload);

	/* create listening socket */
	fd = socket(PF_INET, SOCK_STREAM, 0);
	if (fd < 0) {
		goto fail;
	}

	/* allocate port and bind */
	chansess->x11port = bindport(fd);
	if (chansess->x11port < 0) {
		goto fail;
	}

	/* listen */
	if (listen(fd, 20) < 0) {
		goto fail;
	}

	/* set non-blocking */
	setnonblocking(fd);

	/* listener code will handle the socket now.
	 * No cleanup handler needed, since listener_remove only happens
	 * from our cleanup anyway */
	chansess->x11listener = new_listener( &fd, 1, 0, chansess, x11accept, NULL);
	if (chansess->x11listener == NULL) {
		goto fail;
	}

	return DROPBEAR_SUCCESS;

fail:
	/* cleanup */
	m_free(chansess->x11authprot);
	m_free(chansess->x11authcookie);
	close(fd);

	return DROPBEAR_FAILURE;
}
Esempio n. 4
0
int parse_config(char* filename) {
  FILE* f = fopen(filename, "r");
  if (!f) {
    fprintf(stderr, "Error '%s' while opening '%s'.\n", strerror(errno), filename);
    return 0;
  }
  bzero(config, sizeof(struct config));
  char linebuffer[BUFSIZ];
  unsigned int line_count = 0;
  struct listener* listener = NULL;
  struct vhost* vhost = NULL;
  while (fgets(linebuffer, sizeof(linebuffer), f)) {
    line_count++;
    if (linebuffer[0] == '#' || linebuffer[1] == 1)
      continue;
    char key[BUFSIZ];
    char value[BUFSIZ];
    if (sscanf(linebuffer, "%[a-z_] = %[^\t\n]", key, value) == 2) {
      if (strcmp(key, "daemon") == 0 && strcmp(value, "true") == 0)
        config->daemon = 1;
      else if (strcmp(key, "listener") == 0) {
        if (config->listeners == NULL) {
          listener = new_listener(value);
          if (listener) {
            config->listeners = malloc(sizeof(struct listener) * 2);
            bzero(config->listeners, sizeof(struct listener) * 2);
            config->listeners[0] = listener;
          } else {
            fprintf(stderr, "%s is not valid.\n", value);
            return 0;
          }
        } else {
          listener = new_listener(value);
          if (listener) {
            size_t i = 0;
            while (config->listeners[++i]);
            config->listeners = realloc(config->listeners, sizeof(struct listener) * (i + 2));
            config->listeners[i] = listener;
            config->listeners[++i] = NULL;
          } else {
            fprintf(stderr, "%s is not valid.\n", value);
            return 0;
          }
        }
      } else if (listener && strcmp(key, "pingmode") == 0) {
        if (strcmp(value, "forward") == 0)
          listener->ping_mode = FORWARD_PING;
        else if (strcmp(value, "static") == 0) {
          listener->ping_mode = malloc(sizeof(struct ping_mode));
          bzero(listener->ping_mode, sizeof(struct ping_mode));
          listener->ping_mode->motd = "A Minecraft Server";
        } else {
          fprintf(stderr, "'%s' is invalid for pingmode, only 'forward' and 'static' are valid.\n", value);
          return 0;
        }
      } else if (listener && !listener->logfile && strcmp(key, "logfile") == 0) {
        if (strcmp(value, "stderr") == 0)
          listener->logfile = STDERR;
        else if (strcmp(value, "stdout") == 0)
          listener->logfile = STDOUT;
        else if (strcmp(value, SYSLOG) == 0)
          listener->logfile = SYSLOG;
        else {
          FILE* f = fopen(value, "a");
          if (f) {
            listener->logfile = strdup(value);
            fclose(f);
          } else {
            fprintf(stderr, "Error '%s'.\n", strerror(errno));
            return 0;
          }
        }
      } else if (listener && strcmp(key, "vhost") == 0) {
        vhost = new_vhost(value);
        if (listener->vhosts == NULL) {
          listener->vhosts = malloc(sizeof(struct vhost) * 2);
          bzero(listener->vhosts, sizeof(struct vhost) * 2);
          listener->vhosts[0] = vhost;
        } else {
          size_t i = 0;
          while (listener->vhosts[++i]);
          listener->vhosts = realloc(listener->vhosts, sizeof(struct vhost) * (i + 2));
          listener->vhosts[i] = vhost;
          listener->vhosts[++i] = NULL;
        }
      } else if (vhost && strcmp(key, "internaladdress") == 0) {
        if (fill_in_vhost_address(vhost, value) == 0) {
          fprintf(stderr, "%s is not valid.\n", value);
          return 0;
        }
      } else if (listener && listener->ping_mode && listener->ping_mode != FORWARD_PING) {
        if (strcmp(key, "version") == 0) {
          free(listener->ping_mode->version);
          listener->ping_mode->version = strdup(value);
        } else if (strcmp(key, "numplayers") == 0)
          listener->ping_mode->numplayers = atoi(value);
        else if (strcmp(key, "maxplayers") == 0)
          listener->ping_mode->maxplayers = atoi(value);
        DEBUG(255, "motd: %s", listener->ping_mode->motd);
        DEBUG(255, "version: %s", listener->ping_mode->version);
        DEBUG(255, "%d/%d", listener->ping_mode->numplayers, listener->ping_mode->maxplayers);
      }
    }
  }
  return line_count;
};
Esempio n. 5
0
int parse_config(char* config_file) {
  FILE* f = fopen(config_file, "r");
  if (!f) {
    fprintf(stderr, "Error '%s' while opening '%s'\n", strerror(errno), config_file);
    return 1;
  }
  char line_buffer[BUFSIZ];
  config = malloc(sizeof(struct config));
  bzero(config, sizeof(struct config));
  struct listener* listener = NULL;
  struct module* module = NULL;
  unsigned int line_count = 0;
  while (fgets(line_buffer, sizeof(line_buffer), f)) {
    line_count++;
    if (strlen(line_buffer) <= 1 || line_buffer[0] == '#')
      continue;
    char key[BUFSIZ];
    char value[BUFSIZ];
    if (sscanf(line_buffer, "%[a-z_] = %[^\t\n]", key, value) == 2) {
      if (config->disconnect_after_bytes == 0 && strcmp(key, "disconnect_after_bytes") == 0) {
        errno = 0;
        unsigned short tmp = strtol(value, NULL, 10);
        if (errno == 0)
          config->disconnect_after_bytes = tmp;
      } else if (!config->dateformat && strcmp(key, "dateformat") == 0)
        config->dateformat = strdup(value);
      else if (strcmp(key, "listener") == 0) {
        listener = new_listener(value);
        module = NULL;
        if (listener) {
          if (!config->listeners)
            config->listeners = listener;
          else {
            struct listener* l = config->listeners;
            while (l->next)
              l = l->next;
            l->next = listener;
          }
        }
      } else if (listener && strcmp(key, "module") == 0) {
        module = new_module(value);
        if (module) {
          if (!listener->modules)
            listener->modules = module;
          else {
            struct module* m = listener->modules;
            while (m->next)
              m = m->next;
            m->next = module;
          }
        }
      } else if (listener && module && !module->address && strcmp(key, "address") == 0) {
        char address[129];
        uint16_t port;
        if (sscanf(value, "%128[^:]:%hd", address, &port) == 2) {
          module->address = strdup(address);
          module->port = port;
        }
      } else if (listener && module && !module->logfile && strcmp(key, "logfile") == 0) {
        if (strcmp(value, "stderr") == 0)
          module->logfile = STDERR;
        else if (strcmp(value, "stdout") == 0)
          module->logfile = STDOUT;
        else if (strcmp(value, "syslog") == 0)
          module->logfile = SYSLOG;
        else {
          FILE* f = fopen(value, "a");
          if (f) {
            module->logfile = strdup(value);
            fclose(f);
          } else
            fprintf(stderr, "ERROR: %s\n", strerror(errno));
        }
      } else if (listener && module && !module->logformat && strcmp(key, "logformat") == 0)
        module->logformat = strdup(value);
    } else {
      fprintf(stderr, "Error on line %ud\tCould not be parsed correctly.\n", line_count);
      return 1;
    }
  };
  return 0;
};
Esempio n. 6
0
	TRACE(("enter listen_tcpfwd"))

	/* first we try to bind, so don't need to do so much cleanup on failure */
	snprintf(portstring, sizeof(portstring), "%u", tcpinfo->listenport);

	nsocks = dropbear_listen(AF_UNSPEC, tcpinfo->listenaddr, portstring, socks, 
			DROPBEAR_MAX_SOCKS, &errstring, &ses.maxfd);
	if (nsocks < 0) {
		dropbear_log(LOG_INFO, "TCP forward failed: %s", errstring);
		m_free(errstring);
		TRACE(("leave listen_tcpfwd: dropbear_listen failed"))
		return DROPBEAR_FAILURE;
	}
	m_free(errstring);
	
	/* new_listener will close the socks if it fails */
	listener = new_listener(socks, nsocks, CHANNEL_ID_TCPFORWARDED, tcpinfo, 
			tcp_acceptor, cleanup_tcp);

	if (listener == NULL) {
		TRACE(("leave listen_tcpfwd: listener failed"))
		return DROPBEAR_FAILURE;
	}

	TRACE(("leave listen_tcpfwd: success"))
	return DROPBEAR_SUCCESS;
}

#endif /* DROPBEAR_TCP_ACCEPT */
Esempio n. 7
0
int platform_make_x11_server(Plug *plug, const char *progname, int mindisp,
                             const char *screen_number_suffix,
                             ptrlen authproto, ptrlen authdata,
                             Socket **sockets, Conf *conf)
{
    char *tmpdir;
    char *authfilename = NULL;
    strbuf *authfiledata = NULL;
    char *unix_path = NULL;

    SockAddr *a_tcp = NULL, *a_unix = NULL;

    int authfd;
    FILE *authfp;

    int displayno;

    authfiledata = strbuf_new_nm();

    int nsockets = 0;

    /*
     * Look for a free TCP port to run our server on.
     */
    for (displayno = mindisp;; displayno++) {
        const char *err;
        int tcp_port = displayno + 6000;
        int addrtype = ADDRTYPE_IPV4;

        sockets[nsockets] = new_listener(
            NULL, tcp_port, plug, false, conf, addrtype);

        err = sk_socket_error(sockets[nsockets]);
        if (!err) {
            char *hostname = get_hostname();
            if (hostname) {
                char *canonicalname = NULL;
                a_tcp = name_lookup(hostname, tcp_port, &canonicalname,
                                    conf, addrtype, NULL, "");
                sfree(canonicalname);
            }
            sfree(hostname);
            nsockets++;
            break;                     /* success! */
        } else {
            sk_close(sockets[nsockets]);
        }

        if (!strcmp(err, strerror(EADDRINUSE))) /* yuck! */
            goto out;
    }

    if (a_tcp) {
        x11_format_auth_for_authfile(
            BinarySink_UPCAST(authfiledata),
            a_tcp, displayno, authproto, authdata);
    }

    /*
     * Try to establish the Unix-domain analogue. That may or may not
     * work - file permissions in /tmp may prevent it, for example -
     * but it's worth a try, and we don't consider it a fatal error if
     * it doesn't work.
     */
    unix_path = dupprintf("/tmp/.X11-unix/X%d", displayno);
    a_unix = unix_sock_addr(unix_path);

    sockets[nsockets] = new_unix_listener(a_unix, plug);
    if (!sk_socket_error(sockets[nsockets])) {
        x11_format_auth_for_authfile(
            BinarySink_UPCAST(authfiledata),
            a_unix, displayno, authproto, authdata);
        nsockets++;
    } else {
        sk_close(sockets[nsockets]);
        sfree(unix_path);
        unix_path = NULL;
    }

    /*
     * Decide where the authority data will be written.
     */

    tmpdir = getenv("TMPDIR");
    if (!tmpdir || !*tmpdir)
        tmpdir = "/tmp";

    authfilename = dupcat(tmpdir, "/", progname, "-Xauthority-XXXXXX", NULL);

    {
        int oldumask = umask(077);
        authfd = mkstemp(authfilename);
        umask(oldumask);
    }
    if (authfd < 0) {
        while (nsockets-- > 0)
            sk_close(sockets[nsockets]);
        goto out;
    }

    /*
     * Spawn a subprocess which will try to reliably delete our
     * auth file when we terminate, in case we die unexpectedly.
     */
    {
        int cleanup_pipe[2];
        pid_t pid;

        /* Don't worry if pipe or fork fails; it's not _that_ critical. */
        if (!pipe(cleanup_pipe)) {
            if ((pid = fork()) == 0) {
                int buf[1024];
                /*
                 * Our parent process holds the writing end of
                 * this pipe, and writes nothing to it. Hence,
                 * we expect read() to return EOF as soon as
                 * that process terminates.
                 */

                close(0);
                close(1);
                close(2);

                setpgid(0, 0);
                close(cleanup_pipe[1]);
                close(authfd);
                while (read(cleanup_pipe[0], buf, sizeof(buf)) > 0);
                unlink(authfilename);
                if (unix_path)
                    unlink(unix_path);
                _exit(0);
            } else if (pid < 0) {
                close(cleanup_pipe[0]);
                close(cleanup_pipe[1]);
            } else {
                close(cleanup_pipe[0]);
                cloexec(cleanup_pipe[1]);
            }
        }
    }

    authfp = fdopen(authfd, "wb");
    fwrite(authfiledata->u, 1, authfiledata->len, authfp);
    fclose(authfp);

    {
        char *display = dupprintf(":%d%s", displayno, screen_number_suffix);
        conf_set_str_str(conf, CONF_environmt, "DISPLAY", display);
        sfree(display);
    }
    conf_set_str_str(conf, CONF_environmt, "XAUTHORITY", authfilename);

    /*
     * FIXME: return at least the DISPLAY and XAUTHORITY env settings,
     * and perhaps also the display number
     */

  out:
    if (a_tcp)
        sk_addr_free(a_tcp);
    /* a_unix doesn't need freeing, because new_unix_listener took it over */
    sfree(authfilename);
    strbuf_free(authfiledata);
    sfree(unix_path);
    return nsockets;
}