예제 #1
0
static bool decide_startup_pool(PgSocket *client, PktHdr *pkt)
{
	const char *username = NULL, *dbname = NULL;
	const char *key, *val;
	bool ok;

	while (1) {
		ok = mbuf_get_string(&pkt->data, &key);
		if (!ok || *key == 0)
			break;
		ok = mbuf_get_string(&pkt->data, &val);
		if (!ok)
			break;

		if (strcmp(key, "database") == 0) {
			slog_debug(client, "got var: %s=%s", key, val);
			dbname = val;
		} else if (strcmp(key, "user") == 0) {
			slog_debug(client, "got var: %s=%s", key, val);
			username = val;
		} else if (varcache_set(&client->vars, key, val)) {
			slog_debug(client, "got var: %s=%s", key, val);
		} else if (strlist_contains(cf_ignore_startup_params, key)) {
			slog_debug(client, "ignoring startup parameter: %s=%s", key, val);
		} else {
			slog_warning(client, "unsupported startup parameter: %s=%s", key, val);
			disconnect_client(client, true, "Unsupported startup parameter: %s", key);
			return false;
		}
	}
	if (!username || !username[0]) {
		disconnect_client(client, true, "No username supplied");
		return false;
	}

	/* if missing dbname, default to username */
	if (!dbname || !dbname[0])
		dbname = username;

	/* check if limit allows, dont limit admin db
	   nb: new incoming conn will be attached to PgSocket, thus
	   get_active_client_count() counts it */
	if (get_active_client_count() > cf_max_client_conn) {
		if (strcmp(dbname, "pgbouncer") != 0) {
			disconnect_client(client, true, "no more connections allowed (max_client_conn)");
			return false;
		}
	}

	/* find pool and log about it */
	if (set_pool(client, dbname, username)) {
		if (cf_log_connections)
			slog_info(client, "login attempt: db=%s user=%s", dbname, username);
		return true;
	} else {
		if (cf_log_connections)
			slog_info(client, "login failed: db=%s user=%s", dbname, username);
		return false;
	}
}
예제 #2
0
bool set_pool(PgSocket *client, const char *dbname, const char *username, const char *password, bool takeover)
{
	/* find database */
	client->db = find_database(dbname);
	if (!client->db) {
		client->db = register_auto_database(dbname);
		if (!client->db) {
			disconnect_client(client, true, "No such database: %s", dbname);
			if (cf_log_connections)
				slog_info(client, "login failed: db=%s user=%s", dbname, username);
			return false;
		}
		else {
			slog_info(client, "registered new auto-database: db = %s", dbname );
		}
	}

	/* are new connections allowed? */
	if (client->db->db_disabled) {
		disconnect_client(client, true, "database does not allow connections: %s", dbname);
		return false;
	}

	if (client->db->admin) {
		if (admin_pre_login(client, username))
			return finish_set_pool(client, takeover);
	}

	/* find user */
	if (cf_auth_type == AUTH_ANY) {
		/* ignore requested user */
		if (client->db->forced_user == NULL) {
			slog_error(client, "auth_type=any requires forced user");
			disconnect_client(client, true, "bouncer config error");
			return false;
		}
		client->auth_user = client->db->forced_user;
	} else {
		/* the user clients wants to log in as */
		client->auth_user = find_user(username);
		if (!client->auth_user && client->db->auth_user) {
			if (takeover) {
				client->auth_user = add_db_user(client->db, username, password);
				return finish_set_pool(client, takeover);
			}
			start_auth_request(client, username);
			return false;
		}
		if (!client->auth_user) {
			disconnect_client(client, true, "No such user: %s", username);
			if (cf_log_connections)
				slog_info(client, "login failed: db=%s user=%s", dbname, username);
			return false;
		}
	}
	return finish_set_pool(client, takeover);
}
예제 #3
0
bool set_pool(PgSocket *client, const char *dbname, const char *username)
{
	PgDatabase *db;
	PgUser *user;

	/* find database */
	db = find_database(dbname);
	if (!db) {
		db = register_auto_database(dbname);
		if (!db) {
			disconnect_client(client, true, "No such database: %s", dbname);
			return false;
		}
		else {
			slog_info(client, "registered new auto-database: db = %s", dbname );
		}
	}

	/* are new connections allowed? */
	if (db->db_disabled) {
		disconnect_client(client, true, "database does not allow connections: %s", dbname);
		return false;
	}

	/* find user */
	if (cf_auth_type == AUTH_ANY) {
		/* ignore requested user */
		user = NULL;

		if (db->forced_user == NULL) {
			slog_error(client, "auth_type=any requires forced user");
			disconnect_client(client, true, "bouncer config error");
			return false;
		}
		client->auth_user = db->forced_user;
	} else {
		/* the user clients wants to log in as */
		user = find_user(username);
		if (!user) {
			disconnect_client(client, true, "No such user: %s", username);
			return false;
		}
		client->auth_user = user;
	}

	/* pool user may be forced */
	if (db->forced_user)
		user = db->forced_user;
	client->pool = get_pool(db, user);
	if (!client->pool) {
		disconnect_client(client, true, "no memory for pool");
		return false;
	}

	return check_fast_fail(client);
}
예제 #4
0
void RedirectorSrv::server_sockevent( nlink_server *cptr, uint16 revents, void *myNet ) {
	NetworkInterface * client;
	struct nlink_client *ncptr;
	if(revents & PF_READ)
	{
		client = ( ( NetworkInterface * ) myNet )->getConnection( );
		if (!client) 
			return;
		uint32 nonblockingstate = true;
		IOCTL_SOCKET( client->getSocketID(), IOCTL_NOBLOCK, &nonblockingstate );

		ncptr = new nlink_client;
		if(ncptr == NULL)
			return;
		memset(ncptr, 0, sizeof(*ncptr));
		ncptr->hdr.type = RCLIENT;
		ncptr->hdr.fd = client->getSocketID();
		
		nlink_insert((struct nlink *)ncptr);

		Client *pClient = new Client();
		pClient->BindNI(client);
		ncptr->pClient = pClient;
		pClient->getNetwork()->sendData( mDestination.length( ), mDestination.c_str( ) );
		Log::getSingleton( ).outString( "REDIRECTOR: Sent world server" );
		disconnect_client( ncptr );
	}
}
예제 #5
0
static bool send_client_authreq(PgSocket *client)
{
	uint8_t saltlen = 0;
	int res;
	int auth_type = client->client_auth_type;

	/* Always use plain text to communicate with clients during PAM authorization */
	if (auth_type == AUTH_PAM) {
		auth_type = AUTH_PLAIN;
	}

	if (auth_type == AUTH_MD5) {
		saltlen = 4;
		get_random_bytes((void*)client->tmp_login_salt, saltlen);
	} else if (auth_type == AUTH_PLAIN) {
		/* nothing to do */
	} else {
		return false;
	}

	SEND_generic(res, client, 'R', "ib", auth_type, client->tmp_login_salt, saltlen);
	if (!res)
		disconnect_client(client, false, "failed to send auth req");
	return res;
}
예제 #6
0
static void start_auth_request(PgSocket *client, const char *username)
{
	int res;
	char quoted_username[64], query[128];

	client->auth_user = client->db->auth_user;
	/* have to fetch user info from db */
	client->pool = get_pool(client->db, client->db->auth_user);
	if (!find_server(client)) {
		client->wait_for_user_conn = true;
		return;
	}
	slog_noise(client, "Doing auth_conn query");
	client->wait_for_user_conn = false;
	client->wait_for_user = true;
	if (!sbuf_pause(&client->sbuf)) {
		release_server(client->link);
		disconnect_client(client, true, "pause failed");
		return;
	}
	client->link->ready = 0;

	pg_quote_literal(quoted_username, username, sizeof(quoted_username));
	snprintf(query, sizeof(query), "SELECT usename, passwd FROM pg_shadow WHERE usename=%s", quoted_username);
	SEND_generic(res, client->link, 'Q', "s", query);
	if (!res)
		disconnect_server(client->link, false, "unable to send login query");
}
예제 #7
0
static void
client_deref (struct ropa_client *c)
{
    c->ref--;

    if (c->ref == 0)
	disconnect_client (c);
}
예제 #8
0
void sigalrm_handler(int signum) {
    struct timeval t;
    gettimeofday(&t, NULL);
    for (int i = 0; i < MAX_CLIENTS; i++) {
        if (clients[i].sock != -1 && clients[i].sent == 0 && clients[i].last_msg_time.tv_sec + CONNECTION_TIMEOUT < t.tv_sec) {
            disconnect_client(i);
            printf("client deleted\n");
        }
    }
}
예제 #9
0
static bool login_as_unix_peer(PgSocket *client)
{
	if (!pga_is_unix(&client->remote_addr))
		goto fail;
	if (!check_unix_peer_name(sbuf_socket(&client->sbuf), client->auth_user->name))
		goto fail;
	return finish_client_login(client);
fail:
	disconnect_client(client, true, "unix socket login rejected");
	return false;
}
예제 #10
0
파일: pam.c 프로젝트: davidfetter/pgbouncer
/*
 * Finishes the handshake after successful or unsuccessful authorization.
 * The function is only called from the main thread.
 */
static void pam_auth_finish(struct pam_auth_request *request)
{
	PgSocket *client = request->client;
	bool authenticated = (request->status == PAM_STATUS_SUCCESS);

	if (authenticated) {
		safe_strcpy(client->auth_user->passwd, request->password, sizeof(client->auth_user->passwd));
		sbuf_continue(&client->sbuf);
	} else {
		disconnect_client(client, true, "auth failed");
	}
}
예제 #11
0
파일: sbcs.cpp 프로젝트: Pat61/hyperserv
	void playerkick(int *cn)
	{
		server::clientinfo *ci = server::getinfo(*cn);

		if(!ci)
		{
			// todo: some error mechanism
			intret(RINT_ERROR);
			return;
		}

		disconnect_client(*cn, DISC_KICK);
	}
예제 #12
0
static bool login_via_cert(PgSocket *client)
{
	struct tls *tls = client->sbuf.tls;

	if (!tls) {
		disconnect_client(client, true, "TLS connection required");
		return false;
	}
	if (!tls_peer_cert_provided(client->sbuf.tls)) {
		disconnect_client(client, true, "TLS client certificate required");
		return false;
	}

	log_debug("TLS cert login: %s", tls_peer_cert_subject(client->sbuf.tls));
	if (!tls_peer_cert_contains_name(client->sbuf.tls, client->auth_user->name)) {
		disconnect_client(client, true, "TLS certificate name mismatch");
		return false;
	}

	/* login successful */
	return finish_client_login(client);
}
예제 #13
0
int read_producer_stream(bionet_stream_t *stream) {
    stream_info_t *sinfo = bionet_stream_get_user_data(stream);
    alsa_t *alsa = sinfo->info.producer.alsa;
    int r;
    int frames, bytes;

    if (!check_alsa_poll(alsa)) {
        return 0;
    }

    r = pcm_read(alsa);
    if (r < 0) {
        // FIXME
        printf("read error on stream %s\n", bionet_stream_get_local_name(stream));
        return 1;
    }

    frames = r;
    bytes = (frames * alsa->bytes_per_frame);

    hab_publish_stream(stream, alsa->audio_buffer, bytes);

#if 0
    FIXME
    r = write(client->socket, client->alsa->audio_buffer, bytes);
    if (r < 0) {
        printf("error writing stream %s to consumer: %s\n", bionet_stream_get_local_name(stream), strerror(errno));
        disconnect_client(stream, client);
        return 1;
    } else if (r < bytes) {
        printf("short write to stream %s consumer", bionet_stream_get_local_name(stream));
        disconnect_client(stream, client);
        return 1;
    }
#endif

    return 0;
}
예제 #14
0
static bool finish_set_pool(PgSocket *client, bool takeover)
{
	PgUser *user = client->auth_user;
	/* pool user may be forced */
	if (client->db->forced_user) {
		user = client->db->forced_user;
	}
	client->pool = get_pool(client->db, user);
	if (!client->pool) {
		disconnect_client(client, true, "no memory for pool");
		return false;
	}

	if (cf_log_connections)
		slog_info(client, "login attempt: db=%s user=%s", client->db->name, client->auth_user->name);

	if (!check_fast_fail(client))
		return false;

	if (takeover)
		return true;

	if (client->pool->db->admin) {
		if (!admin_post_login(client))
			return false;
	}

	if (cf_auth_type <= AUTH_TRUST || client->own_user) {
		if (!finish_client_login(client))
			return false;
	} else {
		if (!send_client_authreq(client)) {
			disconnect_client(client, false, "failed to send auth req");
			return false;
		}
	}
	return true;
}
예제 #15
0
파일: ibsim.c 프로젝트: jgunthorpe/ibsim
static int sim_read_pkt(int fd, int client)
{
	char buf[512];
	Client *cl = clients + client, *dcl;
	int size, ret;

	if (client >= IBSIM_MAX_CLIENTS || !cl->pid) {
		IBWARN("pkt from unconnected client %d?!", client);
		return -1;
	}
	for (;;) {
		if ((size = read(fd, buf, sizeof(buf))) <= 0)
			return size;

		if ((size = process_packet(cl, buf, size, &dcl)) < 0) {
			IBWARN("process packet error - discarded");
			continue;	// not a network error
		}

		if (!dcl)
			continue;

		VERB("%s %d bytes (%zu) to client %d fd %d",
		     dcl == cl ? "replying" : "forwarding",
		     size, sizeof(struct sim_request), dcl->id, dcl->fd);

		// reply
		do {
			ret = write(dcl->fd, buf, size);
		} while ((errno == EAGAIN) && (ret == -1));
			 
		if (ret == size)
			return 0;

		if (ret < 0 && (errno == ECONNREFUSED || errno == ENOTCONN)) {
			IBWARN("client %u seems to be dead - disconnecting.",
			       dcl->id);
			disconnect_client(dcl->id);
		}
		IBWARN("write failed: %m - pkt dropped");
		if (dcl != cl) { /* reply timeout */
			struct sim_request *r = (struct sim_request *)buf;
			r->status = htonl(110);
			ret = write(cl->fd, buf, size);
		}
	}

	return -1;		// never reached
}
예제 #16
0
파일: server.c 프로젝트: mpatraw/MOAG
int main(int argc, char *argv[])
{
    init_enet_server(PORT);

    LOG("Started server.\n");

    struct moag moag;
    init_game(&moag);

    LOG("Initialized game.\n");

    ENetEvent event;

    for (;;)
    {
        while (enet_host_service(get_server_host(), &event, 0))
        {
            switch (event.type)
            {
                case ENET_EVENT_TYPE_CONNECT:
                    LOG("Client connected.\n");
                    event.peer->data = (void *)client_connect(&moag);
                    break;

                case ENET_EVENT_TYPE_DISCONNECT:
                    LOG("Client disconnected.\n");
                    disconnect_client(&moag, (intptr_t)event.peer->data);
                    break;

                case ENET_EVENT_TYPE_RECEIVE:
                    on_receive(&moag, &event);
                    enet_packet_destroy(event.packet);
                    break;

                default:
                    break;
            }
        }
	SDL_Delay(10);

        step_game(&moag);
    }

    uninit_enet();

    LOG("Stopped server.\n");

    return EXIT_SUCCESS;
}
예제 #17
0
파일: micserver.c 프로젝트: rofl0r/rocksock
static int on_cread (void* userdata, int fd, size_t dummy) {
	(void) dummy;
	server* s = userdata;
	struct client *c = &p.client;
	unsigned x = c->samples_recvd % ARRAY_SIZE(c->wave);
	DPRINTF(2, "receiving samplebuf %u\n", x);
	if(sizeof(c->wave[0]) != recv(fd, c->wave[x], sizeof(c->wave[0]), 0)) {
		disconnect_client(s, fd);
		return 0;
	}
	pthread_mutex_lock(&c->mtx);
	c->samples_recvd++;
	pthread_mutex_unlock(&c->mtx);
	return 0;
}
예제 #18
0
파일: micserver.c 프로젝트: rofl0r/rocksock
static int on_cconnect (void* userdata, struct sockaddr_storage* clientaddr, int fd) {
	(void) clientaddr;
	server* s = userdata;
	if(p.client.fd != -1) {
		disconnect_client(s, fd);
		return -1;
	}
	struct client* c = &p.client;
	c->fd = fd;
	c->terminate = 0;
	c->playback_handle = init_playback_device(s->audiodevice);
	pthread_mutex_init(&c->mtx, 0);
	pthread_create(&c->thr, 0, c_thread, c);
	return 0;
}
예제 #19
0
static PyObject *playerKick(PyObject *self, PyObject *args)
{
	int cn;
	server::clientinfo *ci;
	if(!PyArg_ParseTuple(args, "i", &cn))
		return 0;
	ci = server::getinfo(cn);
	if(!ci)
	{
		PyErr_SetString(PyExc_ValueError, "Invalid cn specified");
		return 0;
	}
	disconnect_client(cn, DISC_KICK);
	Py_INCREF(Py_None);
	return Py_None;
}
예제 #20
0
static PyObject *playerDisconnect(PyObject *self, PyObject *args)
{
	int cn;
	int reason;
	server::clientinfo *ci;
	if(!PyArg_ParseTuple(args, "ii", &cn, &reason))
		return 0;
	ci = server::getinfo(cn);
	if(!ci)
	{
		PyErr_SetString(PyExc_ValueError, "Invalid cn specified");
		return 0;
	}
	//enum { DISC_NONE = 0, DISC_EOP, DISC_CN, DISC_KICK, DISC_TAGT, DISC_IPBAN, DISC_PRIVATE, DISC_MAXCLIENTS, DISC_TIMEOUT, DISC_OVERFLOW, DISC_NUM };
	if (reason < DISC_NONE || reason > DISC_NUM)
	{
		PyErr_SetString(PyExc_ValueError, "That is not a valid disconnect reason.");
		return 0;
	}
	disconnect_client(cn, reason);
	Py_INCREF(Py_None);
	return Py_None;
}
예제 #21
0
static void start_auth_request(PgSocket *client, const char *username)
{
	int res;
	PktBuf *buf;

	client->auth_user = client->db->auth_user;
	/* have to fetch user info from db */
	client->pool = get_pool(client->db, client->db->auth_user);
	if (!find_server(client)) {
		client->wait_for_user_conn = true;
		return;
	}
	slog_noise(client, "Doing auth_conn query");
	client->wait_for_user_conn = false;
	client->wait_for_user = true;
	if (!sbuf_pause(&client->sbuf)) {
		release_server(client->link);
		disconnect_client(client, true, "pause failed");
		return;
	}
	client->link->ready = 0;

	res = 0;
	buf = pktbuf_dynamic(512);
	if (buf) {
		pktbuf_write_ExtQuery(buf, cf_auth_query, 1, username);
		res = pktbuf_send_immediate(buf, client->link);
		pktbuf_free(buf);
		/*
		 * Should do instead:
		 *   res = pktbuf_send_queued(buf, client->link);
		 * but that needs better integration with SBuf.
		 */
	}
	if (!res)
		disconnect_server(client->link, false, "unable to send login query");
}
예제 #22
0
static struct ropa_client *
client_query (uint32_t host, uint16_t port)
{
    struct ropa_client *c, *c_new;
    int ret;

    c = client_query_notalkback(host, port);
    if (c == NULL) {
	interfaceAddr remote;
	struct rx_connection *conn = NULL;

	c = obtain_client();
	assert (c->state == ROPAC_FREE && c->li == NULL);
	c->state = ROPAC_LOOKUP_U;
	c->flags |= ROPAF_LOOKUP;
	client_init (c, host, port, NULL, NULL);
	
	conn = rx_NewConnection (host, port, CM_SERVICE_ID,
				 rxnull_NewClientSecurityObject(),
				 0);
	if (conn == NULL) {
	    free(c);
	    return NULL;
	}
    retry:
	switch (c->state) {
	case ROPAC_DEAD:
	    c->li = listaddtail (lru_clients, c);
	    ret = ENETDOWN;
	    break;
	case ROPAC_LOOKUP_U:
	    ret = RXAFSCB_WhoAreYou (conn, &remote);
	    if (ret == RXGEN_OPCODE) {
		c->state = ROPAC_LOOKUP;
		goto retry;
	    } else if (ret == RX_CALL_DEAD) {
		c->state = ROPAC_DEAD;
		goto retry;
	    } else {
		struct ropa_client ckey;
		
		ckey.uuid = remote.uuid;
		c_new = hashtabsearch (ht_clients_uuid, &ckey);
		if (c_new == NULL) {
		    client_init (c, host, port, &remote.uuid, NULL);
		    ret = RXAFSCB_InitCallBackState3(conn, &server_uuid);
		} else {
		    client_update_interfaces (c_new, host, port, &remote);
		    disconnect_client (c);
		    c = c_new;
		    listdel(lru_clients, c->li);
		    c->li = NULL;
		}
	    }
	    break;
	case ROPAC_LOOKUP: {
	    afsUUID uuid;
	    ret = RXAFSCB_InitCallBackState(conn);
	    if (ret == RX_CALL_DEAD) {
		c->state = ROPAC_DEAD;
		goto retry;
	    }
	    uuid_init_simple (&uuid, host);
	    client_init (c, host, port, &uuid, NULL);
	    break;
	}
	default:
	     exit(-1);
	}
	
	rx_DestroyConnection (conn);
	
	if ((c->flags & ROPAF_WAITING) != 0)
	    LWP_NoYieldSignal (c);
	c->flags &= ~(ROPAF_LOOKUP|ROPAF_WAITING);

	if (ret) {
	    assert (c->li != NULL);
	    return NULL;
	}

	assert (c->li == NULL);
	c->li = listaddhead (lru_clients, c);

    } else { /* c != NULL */
	if ((c->flags & ROPAF_LOOKUP) != 0) {
	    c->flags |= ROPAF_WAITING;
	    LWP_WaitProcess (c);
	}
	assert (c->li != NULL);
    }

    return c;
}
예제 #23
0
파일: server.cpp 프로젝트: bsegovia/mini.q
// server side processing of updates: does very little and most state is tracked
// client only could be extended to move more gameplay to server (at expense of
// lag)
void process(ENetPacket * packet, int sender) { // sender may be -1
  const u16 len = *(u16*) packet->data;
  if (ENET_NET_TO_HOST_16(len)!=packet->dataLength) {
    disconnect_client(sender, "packet length");
    return;
  }

  u8 *end = packet->data+packet->dataLength;
  u8 *p = packet->data+2;
  char text[MAXTRANS];
  int cn = -1, type;

  while (p<end) switch (type = getint(p)) {
    case SV_TEXT:
      sgetstr();
    break;
    case SV_INITC2S:
      sgetstr();
      strcpy_s(clients[cn].name, text);
      sgetstr();
      getint(p);
    break;
    case SV_MAPCHANGE: {
      sgetstr();
      int reqmode = getint(p);
      if (reqmode<0) reqmode = 0;
      if (smapname[0] && !mapreload && !vote(text, reqmode, sender)) return;
      mapreload = false;
      mode = reqmode;
      minremain = mode&1 ? 15 : 10;
      mapend = lastsec+minremain*60;
      interm = 0;
      strcpy_s(smapname, text);
      resetitems();
      sender = -1;
    }
    break;
    case SV_ITEMLIST: {
      int n;
      while ((n = getint(p))!=-1) if (notgotitems) {
        server_entity se = { false, 0 };
        while (sents.size()<=n) sents.push_back(se);
        sents[n].spawned = true;
      }
      notgotitems = false;
    }
    break;
    case SV_ITEMPICKUP: {
      const int n = getint(p);
      pickup(n, getint(p), sender);
    }
    break;
    case SV_PING:
      send2(false, cn, SV_PONG, getint(p));
    break;
    case SV_POS: {
      cn = getint(p);
      if (cn<0 || cn>=clients.size() || clients[cn].type==ST_EMPTY) {
        disconnect_client(sender, "client num");
        return;
      }
      int size = msgsizelookup(type);
      assert(size!=-1);
      loopi(size-2) getint(p);
    }
    break;
    case SV_SENDMAP: {
      sgetstr();
      const auto mapsize = getint(p);
      sendmaps(sender, text, mapsize, p);
    }
    return;
    case SV_RECVMAP:
      send(sender, recvmap(sender));
    return;
    case SV_EXT:   // allows for new features that require no server updates 
      for (int n = getint(p); n; n--) getint(p);
    break;
    default: {
      const int size = msgsizelookup(type);
      if (size==-1) { disconnect_client(sender, "tag type"); return; };
      loopi(size-1) getint(p);
    }
  }

  if (p>end) { disconnect_client(sender, "end of packet"); return; };
  multicast(packet, sender);
}
예제 #24
0
int main (int argc, char *argv[])
{
    char cmd[10];
    int num, end = 0;
    int cobex = FALSE, tcpobex = FALSE, btobex = FALSE, r320 = FALSE, usbobex = FALSE;
    obex_t *handle;
#ifdef HAVE_BLUETOOTH
    bdaddr_t bdaddr;
    uint8_t channel = 0;
#endif

#ifdef HAVE_USB
    obex_interface_t *obex_intf;
#endif

    struct context global_context = {0,};

#ifndef _WIN32

    char *port;
    obex_ctrans_t custfunc;

    if( (argc == 2 || argc ==3) && (strcmp(argv[1], "-s") == 0 ) )
        cobex = TRUE;
    if( (argc == 2 || argc ==3) && (strcmp(argv[1], "-r") == 0 ) ) {
        cobex = TRUE;
        r320 = TRUE;
    }
#endif

    if( (argc == 2) && (strcmp(argv[1], "-i") == 0 ) )
        tcpobex = TRUE;
    if( (argc >= 2) && (strcmp(argv[1], "-b") == 0 ) )
        btobex = TRUE;
    if( (argc >= 2) && (strcmp(argv[1], "-u") == 0 ) )
        usbobex = TRUE;

    if(cobex)	{
#ifndef _WIN32
        if(argc == 3)
            port = argv[2];
        else
            port = "/dev/ttyS0";

        if(r320)
            printf("OBEX to R320 on %s!\n", port);
        else
            printf("OBEX on %s!\n", port);

        custfunc.customdata = cobex_open(port, r320);

        if(custfunc.customdata == NULL) {
            printf("cobex_open() failed\n");
            return -1;
        }

        if(! (handle = OBEX_Init(OBEX_TRANS_CUSTOM, obex_event, 0)))	{
            perror( "OBEX_Init failed");
            return -1;
        }

        custfunc.connect = cobex_connect;
        custfunc.disconnect = cobex_disconnect;
        custfunc.write = cobex_write;
        custfunc.handleinput = cobex_handle_input;
        custfunc.listen = cobex_connect;	// Listen and connect is 100% same on cable

        if(OBEX_RegisterCTransport(handle, &custfunc) < 0)	{
            printf("Custom transport callback-registration failed\n");
        }
#else
        printf("Not implemented in Win32 yet.\n");
#endif	// _WIN32
    }

    else if(tcpobex) {
        printf("Using TCP transport\n");
        if(! (handle = OBEX_Init(OBEX_TRANS_INET, obex_event, 0)))	{
            perror( "OBEX_Init failed");
            exit(0);
        }
    }
    else if(btobex) {
#ifndef _WIN32
        switch (argc) {
#ifdef HAVE_BLUETOOTH
        case 4:
            str2ba(argv[2], &bdaddr);
            channel = atoi(argv[3]);
            break;
        case 3:
            str2ba(argv[2], &bdaddr);
            if (bacmp(&bdaddr, BDADDR_ANY) == 0)
                channel = atoi(argv[2]);
            else
                channel = BT_CHANNEL;
            break;
        case 2:
            bacpy(&bdaddr, BDADDR_ANY);
            channel = BT_CHANNEL;
            break;
#endif
        default:
            printf("Wrong number of arguments\n");
            exit(0);
        }

        printf("Using Bluetooth RFCOMM transport\n");
        if(! (handle = OBEX_Init(OBEX_TRANS_BLUETOOTH, obex_event, 0)))      {
            perror( "OBEX_Init failed");
            exit(0);
        }
#else
        printf("Not implemented in Win32 yet.\n");
#endif	// _WIN32
    }
    else if(usbobex) {
#ifdef HAVE_USB
        int i, interfaces_number, intf_num;
        switch (argc) {
        case 2:
            printf("Using USB transport, querying available interfaces\n");
            if(! (handle = OBEX_Init(OBEX_TRANS_USB, obex_event, 0)))      {
                perror( "OBEX_Init failed");
                exit(0);
            }
            interfaces_number = OBEX_FindInterfaces(handle, &obex_intf);
            for (i=0; i < interfaces_number; i++)
                printf("Interface %d: %s %s %s\n", i,
                       obex_intf[i].usb.manufacturer,
                       obex_intf[i].usb.product,
                       obex_intf[i].usb.control_interface);
            printf("Use '%s -u interface_number' to run interactive OBEX test client\n", argv[0]);
            OBEX_Cleanup(handle);
            exit(0);
            break;
        case 3:
            intf_num = atoi(argv[2]);
            printf("Using USB transport \n");
            if(! (handle = OBEX_Init(OBEX_TRANS_USB, obex_event, 0)))      {
                perror( "OBEX_Init failed");
                exit(0);
            }

            interfaces_number = OBEX_FindInterfaces(handle, &obex_intf);
            if (intf_num >= interfaces_number) {
                printf( "Invalid interface number\n");
                exit(0);
            }
            obex_intf += intf_num;

            break;
        default:
            printf("Wrong number of arguments\n");
            exit(0);
        }
#else
        printf("Not compiled with USB support\n");
        exit(0);
#endif
    }
    else	{
        printf("Using IrDA transport\n");
        if(! (handle = OBEX_Init(OBEX_TRANS_IRDA, obex_event, 0)))	{
            perror( "OBEX_Init failed");
            exit(0);
        }
    }

    OBEX_SetUserData(handle, &global_context);

    printf( "OBEX Interactive test client/server.\n");

    while (!end) {
        printf("> ");
        num = scanf("%s", cmd);
        switch (cmd[0] | 0x20)	{
        case 'q':
            end=1;
            break;
        case 'g':
            get_client(handle, &global_context);
            break;
        case 't':
            setpath_client(handle);
            break;
        case 'p':
            put_client(handle);
            break;
        case 'x':
            push_client(handle);
            break;
        case 'c':
            /* First connect transport */
            if(tcpobex) {
                if(TcpOBEX_TransportConnect(handle, NULL, 0) < 0) {
                    printf("Transport connect error! (TCP)\n");
                    break;
                }
            }
            if(cobex) {
                if(OBEX_TransportConnect(handle, (void*) 1, 0) < 0) {
                    printf("Transport connect error! (Serial)\n");
                    break;
                }
            }
            if(btobex) {
#ifdef HAVE_BLUETOOTH
                if (bacmp(&bdaddr, BDADDR_ANY) == 0) {
                    printf("Device address error! (Bluetooth)\n");
                    break;
                }
                if(BtOBEX_TransportConnect(handle, BDADDR_ANY, &bdaddr, channel) <0) {
                    printf("Transport connect error! (Bluetooth)\n");
                    break;
                }
#else
                printf("Transport not found! (Bluetooth)\n");
#endif
            }
            if (usbobex) {
#ifdef HAVE_USB
                if (OBEX_InterfaceConnect(handle, obex_intf) < 0) {
                    printf("Transport connect error! (USB)\n");
                    break;
                }
#else
                printf("Transport not found! (USB)\n");
#endif
            }
            if (!tcpobex && !cobex && !btobex && !usbobex) {
                if(IrOBEX_TransportConnect(handle, IR_SERVICE) < 0) {
                    printf("Transport connect error! (IrDA)\n");
                    break;
                }
            }
            // Now send OBEX-connect.
            connect_client(handle);
            break;
        case 'd':
            disconnect_client(handle);
            break;
        case 's':
            /* First register server */
            if(tcpobex) {
                if(TcpOBEX_ServerRegister(handle, NULL, 0) < 0) {
                    printf("Server register error! (TCP)\n");
                    break;
                }
            }
            if(cobex) {
                if(OBEX_ServerRegister(handle, (void*) 1, 0) < 0) {
                    printf("Server register error! (Serial)\n");
                    break;
                }
            }
            if(btobex) {
#ifdef HAVE_BLUETOOTH
                if(BtOBEX_ServerRegister(handle, BDADDR_ANY, channel) < 0) {
                    printf("Server register error! (Bluetooth)\n");
                    break;
                }
#else
                printf("Transport not found! (Bluetooth)\n");
#endif
            }
            if (usbobex) {
                printf("Transport not found! (USB)\n");
            }
            if (!tcpobex && !cobex && !btobex && !usbobex) {
                if(IrOBEX_ServerRegister(handle, IR_SERVICE) < 0)	{
                    printf("Server register error! (IrDA)\n");
                    break;
                }
            }
            /* No process server events */
            server_do(handle);
            break;
        default:
            printf("Unknown command %s\n", cmd);
        }
    }
#ifndef _WIN32
    if(cobex)
        cobex_close(custfunc.customdata);
#endif

    return 0;
}
예제 #25
0
int main(int argc, char *argv[]) {
    int port;
    char *args_help = "Enter port and path to unix socket.\n";
    if (read_args(argc, argv, &port, &socket_unix_path) != 0) {
        printf(args_help);
        return 1;
    }

    atexit(cleanup);
    struct sigaction act;
    memset(&act, 0, sizeof act);
    act.sa_handler = sigint_handler;
    sigaction(SIGINT, &act, NULL);
    sigaction(SIGTSTP, &act, NULL);
    act.sa_handler = sigalrm_handler;
    sigaction(SIGALRM, &act, NULL);

    for (int i = 0; i < MAX_CLIENTS; i++) {
        clients[i].sock = -1;
        clients[i].username[0] = '\0';
        clients[i].sent = 0;
    }

    unlink(socket_unix_path);

    unix_socket = prepare_unix_socket(socket_unix_path);
    internet_socket = prepare_internet_socket(port);
    if (unix_socket == -1 || internet_socket == -1) {
        printf("Error while creating sockets occurred.\n");
        return 1;
    }

    struct itimerval timer_val;
    struct timeval timer_time;
    timer_time.tv_sec = 3;
    timer_time.tv_usec = 0;
    timer_val.it_interval = timer_time;
    timer_val.it_value = timer_time;

    setitimer(ITIMER_REAL, &timer_val, NULL);

    fd_set read_sock_set;
    FD_ZERO(&sock_set);
    int fd_max = unix_socket > internet_socket ? unix_socket : internet_socket;
    FD_SET(unix_socket, &sock_set);
    FD_SET(internet_socket, &sock_set);
    struct timeval msg_time;
    while(1) {
        gettimeofday(&msg_time, NULL);
        read_sock_set = sock_set;
        if (select(fd_max + 1, &read_sock_set, NULL , NULL , NULL) < 0) {
            if (errno == EINTR)
                continue;
            else {
                printf("Error while executing select occurred.\n");
                sleep(1);
                continue;
            }
        }
        int client_unix_sock = -1;
        int client_internet_sock = -1;

        if (clients_connected < MAX_CLIENTS) {
            if (FD_ISSET(unix_socket, &read_sock_set)) {
                if ((client_unix_sock = accept(unix_socket, NULL, NULL)) == -1)
                    printf("Cannot accept new client connection!\n");
            }
            if (FD_ISSET(internet_socket, &read_sock_set) && !(clients_connected + 1 == MAX_CLIENTS && client_unix_sock != -1))
                if ((client_internet_sock = accept(internet_socket, NULL, NULL)) == -1)
                    printf("Cannot accept new client connection!\n");
            for (int i = 0; i < MAX_CLIENTS && (client_unix_sock != -1 || client_internet_sock != -1); i++) {
                if (clients[i].sock == -1) {
                    int client_sock;
                    if (client_unix_sock != -1) {
                        client_sock = client_unix_sock;
                        client_unix_sock = -1;
                    } else {
                        client_sock = client_internet_sock;
                        client_internet_sock = -1;
                    }
                    FD_SET(client_sock, &sock_set);
                    if (client_sock > fd_max) {
                        fd_max = client_sock;
                    }
                    clients[i].sock = client_sock;
                    clients[i].last_msg_time = msg_time;
                    clients_connected++;
                    printf("client accepted\n");
                }
            }
        }
        else {
            if (FD_ISSET(unix_socket, &read_sock_set)) {
                client_unix_sock = accept(unix_socket, NULL, NULL);
                close(client_unix_sock);
            }
            if (FD_ISSET(internet_socket, &read_sock_set)) {
                client_internet_sock = accept(internet_socket, NULL, NULL);
                close(client_internet_sock);
            }
        }
        for (int i = 0; i < MAX_CLIENTS; i++) {
            if (clients[i].sock == -1 || !FD_ISSET(clients[i].sock, &read_sock_set)) {
                continue;
            }
            struct Message msg;
            clients[i].sent = 1;
            if(recv(clients[i].sock, &msg, sizeof(msg), 0) <= 0) {
                printf("%s disconnected\n", clients[i].username);
                strcpy(msg.username, clients[i].username);
                strcpy(msg.message, "Disconnected\n");
                broadcast(msg, clients[i].sock);
                disconnect_client(i);
                continue;
            }
            clients[i].last_msg_time = msg_time;
            printf("%s", msg.message);
            strcpy(clients[i].username, msg.username);
            broadcast(msg, clients[i].sock);
        }
    }
}
예제 #26
0
bool handle_auth_response(PgSocket *client, PktHdr *pkt) {
	uint16_t columns;
	uint32_t length;
	const char *username, *password;
	PgUser user;
	PgSocket *server = client->link;

	switch(pkt->type) {
	case 'T':	/* RowDescription */
		if (!mbuf_get_uint16be(&pkt->data, &columns)) {
			disconnect_server(server, false, "bad packet");
			return false;
		}
		if (columns != 2u) {
			disconnect_server(server, false, "expected 1 column from login query, not %hu", columns);
			return false;
		}
		break;
	case 'D':	/* DataRow */
		memset(&user, 0, sizeof(user));
		if (!mbuf_get_uint16be(&pkt->data, &columns)) {
			disconnect_server(server, false, "bad packet");
			return false;
		}
		if (columns != 2u) {
			disconnect_server(server, false, "expected 1 column from login query, not %hu", columns);
			return false;
		}
		if (!mbuf_get_uint32be(&pkt->data, &length)) {
			disconnect_server(server, false, "bad packet");
			return false;
		}
		if (!mbuf_get_chars(&pkt->data, length, &username)) {
			disconnect_server(server, false, "bad packet");
			return false;
		}
		if (sizeof(user.name) - 1 < length)
			length = sizeof(user.name) - 1;
		memcpy(user.name, username, length);
		if (!mbuf_get_uint32be(&pkt->data, &length)) {
			disconnect_server(server, false, "bad packet");
			return false;
		}
		if (length == (uint32_t)-1) {
			// NULL - set an md5 password with an impossible value,
			// so that nothing will ever match
			password = "******";
			length = 3;
		} else {
			if (!mbuf_get_chars(&pkt->data, length, &password)) {
				disconnect_server(server, false, "bad packet");
				return false;
			}
		}
		if (sizeof(user.passwd)  - 1 < length)
			length = sizeof(user.passwd) - 1;
		memcpy(user.passwd, password, length);

		client->auth_user = add_db_user(client->db, user.name, user.passwd);
		if (!client->auth_user) {
			disconnect_server(server, false, "unable to allocate new user for auth");
			return false;
		}
		break;
	case 'C':	/* CommandComplete */
		break;
	case 'Z':	/* ReadyForQuery */
		sbuf_prepare_skip(&client->link->sbuf, pkt->len);
		if (!client->auth_user) {
			if (cf_log_connections)
				slog_info(client, "login failed: db=%s", client->db->name);
			disconnect_client(client, true, "No such user");
		} else {
			slog_noise(client, "auth query complete");
			client->link->resetting = true;
			sbuf_continue(&client->sbuf);
		}
		// either sbuf_continue or disconnect_client could disconnect the server
		// way down in their bowels of other callbacks. so check that, and
		// return appropriately (similar to reuse_on_release)
		if (server->state == SV_FREE || server->state == SV_JUSTFREE)
			return false;
		return true;
	default:
		disconnect_server(server, false, "unexpected response from login query");
		return false;
	}
	sbuf_prepare_skip(&server->sbuf, pkt->len);
	return true;
}
예제 #27
0
파일: kiro-server.c 프로젝트: IMCG/kiro
void
kiro_server_realloc (KiroServer *self, void *mem, size_t size) {

    if (!self)
        return;

    g_debug ("Starting realloc");

    struct kiro_rdma_mem rdma_mem;
    rdma_mem.mem = mem;
    rdma_mem.size = size;

    KiroServerPrivate *priv = KIRO_SERVER_GET_PRIVATE (self);


    G_LOCK (connection_handling);
    G_LOCK (rdma_handling);

    priv->mem = mem;
    priv->mem_size = size;
    if (!priv->clients) {
        g_debug ("No clients to reconnect. Done.");
        G_UNLOCK (rdma_handling);
        G_UNLOCK (connection_handling);
        return;
    }
    g_list_foreach (priv->clients, request_client_realloc, &rdma_mem);

    // Swap the two lists. See Note above.
    GList *tmp = priv->clients;
    priv->clients = realloc_list;
    realloc_list = tmp;
    G_UNLOCK (rdma_handling);

    guint timeout = g_timeout_add_seconds (2, client_realloc_timeout, NULL);

    timeout_done = FALSE;
    while (!timeout_done) {
        if (!realloc_list) {
            g_debug ("All clients have ACKed");
            break; // all clients ACKed
        }
    }

    GSource *timeout_source = g_main_context_find_source_by_id (NULL, timeout);
    if (timeout_source) {
        g_source_destroy (timeout_source);
    }

    G_LOCK (realloc_timeout);
    GList *current = g_list_first (realloc_list);
    while (current) {
        struct kiro_client_connection *cc = (struct kiro_client_connection *)current->data;
        g_debug ("Client %i did not ACK the REALLOC request in time.", cc->id);
        GList *client = g_list_find (priv->clients, current->data);
        if (client) {
            priv->clients = g_list_delete_link (priv->clients, client);
        }
        disconnect_client (current->data, NULL);
        current = g_list_next (current);
    }

    if (realloc_list) {
        g_list_free (realloc_list);
        realloc_list = NULL;
    }
    G_UNLOCK (realloc_timeout);


    g_debug ("Realloc procedure done!");
    G_UNLOCK (connection_handling);
}
예제 #28
0
/* decide on packets of client in login phase */
static bool handle_client_startup(PgSocket *client, PktHdr *pkt)
{
	const char *passwd;
	const uint8_t *key;
	bool ok;

	SBuf *sbuf = &client->sbuf;

	/* don't tolerate partial packets */
	if (incomplete_pkt(pkt)) {
		disconnect_client(client, true, "client sent partial pkt in startup phase");
		return false;
	}

	if (client->wait_for_welcome) {
		if  (finish_client_login(client)) {
			/* the packet was already parsed */
			sbuf_prepare_skip(sbuf, pkt->len);
			return true;
		} else
			return false;
	}

	switch (pkt->type) {
	case PKT_SSLREQ:
		slog_noise(client, "C: req SSL");
		slog_noise(client, "P: nak");

		/* reject SSL attempt */
		if (!sbuf_answer(&client->sbuf, "N", 1)) {
			disconnect_client(client, false, "failed to nak SSL");
			return false;
		}
		break;
	case PKT_STARTUP_V2:
		disconnect_client(client, true, "Old V2 protocol not supported");
		return false;
	case PKT_STARTUP:
		if (client->pool) {
			disconnect_client(client, true, "client re-sent startup pkt");
			return false;
		}

		if (!decide_startup_pool(client, pkt))
			return false;

		if (client->pool->db->admin) {
			if (!admin_pre_login(client))
				return false;
		}

		if (cf_auth_type <= AUTH_TRUST || client->own_user) {
			if (!finish_client_login(client))
				return false;
		} else {
			if (!send_client_authreq(client)) {
				disconnect_client(client, false, "failed to send auth req");
				return false;
			}
		}
		break;
	case 'p':		/* PasswordMessage */
		/* haven't requested it */
		if (cf_auth_type <= AUTH_TRUST) {
			disconnect_client(client, true, "unrequested passwd pkt");
			return false;
		}

		ok = mbuf_get_string(&pkt->data, &passwd);
		if (ok && check_client_passwd(client, passwd)) {
			if (!finish_client_login(client))
				return false;
		} else {
			disconnect_client(client, true, "Auth failed");
			return false;
		}
		break;
	case PKT_CANCEL:
		if (mbuf_avail_for_read(&pkt->data) == BACKENDKEY_LEN
		    && mbuf_get_bytes(&pkt->data, BACKENDKEY_LEN, &key))
		{
			memcpy(client->cancel_key, key, BACKENDKEY_LEN);
			accept_cancel_request(client);
		} else
			disconnect_client(client, false, "bad cancel request");
		return false;
	default:
		disconnect_client(client, false, "bad packet");
		return false;
	}
	sbuf_prepare_skip(sbuf, pkt->len);
	client->request_time = get_cached_time();
	return true;
}
예제 #29
0
/* callback from SBuf */
bool client_proto(SBuf *sbuf, SBufEvent evtype, struct MBuf *data)
{
	bool res = false;
	PgSocket *client = container_of(sbuf, PgSocket, sbuf);
	PktHdr pkt;


	Assert(!is_server_socket(client));
	Assert(client->sbuf.sock);
	Assert(client->state != CL_FREE);

	/* may happen if close failed */
	if (client->state == CL_JUSTFREE)
		return false;

	switch (evtype) {
	case SBUF_EV_CONNECT_OK:
	case SBUF_EV_CONNECT_FAILED:
		/* ^ those should not happen */
	case SBUF_EV_RECV_FAILED:
		disconnect_client(client, false, "client unexpected eof");
		break;
	case SBUF_EV_SEND_FAILED:
		disconnect_server(client->link, false, "Server connection closed");
		break;
	case SBUF_EV_READ:
		if (mbuf_avail_for_read(data) < NEW_HEADER_LEN && client->state != CL_LOGIN) {
			slog_noise(client, "C: got partial header, trying to wait a bit");
			return false;
		}

		if (!get_header(data, &pkt)) {
			char hex[8*2 + 1];
			disconnect_client(client, true, "bad packet header: '%s'",
					  hdr2hex(data, hex, sizeof(hex)));
			return false;
		}
		slog_noise(client, "pkt='%c' len=%d", pkt_desc(&pkt), pkt.len);

		client->request_time = get_cached_time();
		switch (client->state) {
		case CL_LOGIN:
			res = handle_client_startup(client, &pkt);
			break;
		case CL_ACTIVE:
			if (client->wait_for_welcome)
				res = handle_client_startup(client, &pkt);
			else
				res = handle_client_work(client, &pkt);
			break;
		case CL_WAITING:
			fatal("why waiting client in client_proto()");
		default:
			fatal("bad client state: %d", client->state);
		}
		break;
	case SBUF_EV_FLUSH:
		/* client is not interested in it */
		break;
	case SBUF_EV_PKT_CALLBACK:
		/* unused ATM */
		break;
	}
	return res;
}
예제 #30
0
/* decide on packets of logged-in client */
static bool handle_client_work(PgSocket *client, PktHdr *pkt)
{
	SBuf *sbuf = &client->sbuf;

	switch (pkt->type) {

	/* one-packet queries */
	case 'Q':		/* Query */
		if (cf_disable_pqexec) {
			slog_error(client, "Client used 'Q' packet type.");
			disconnect_client(client, true, "PQexec disallowed");
			return false;
		}
	case 'F':		/* FunctionCall */

	/* request immediate response from server */
	case 'H':		/* Flush */
	case 'S':		/* Sync */

	/* copy end markers */
	case 'c':		/* CopyDone(F/B) */
	case 'f':		/* CopyFail(F/B) */

	/*
	 * extended protocol allows server (and thus pooler)
	 * to buffer packets until sync or flush is sent by client
	 */
	case 'P':		/* Parse */
	case 'E':		/* Execute */
	case 'C':		/* Close */
	case 'B':		/* Bind */
	case 'D':		/* Describe */
	case 'd':		/* CopyData(F/B) */

		/* update stats */
		if (!client->query_start) {
			client->pool->stats.request_count++;
			client->query_start = get_cached_time();
		}

		if (client->pool->db->admin)
			return admin_handle_client(client, pkt);

		/* aquire server */
		if (!find_server(client))
			return false;

		client->pool->stats.client_bytes += pkt->len;

		/* tag the server as dirty */
		client->link->ready = false;
		client->link->idle_tx = false;

		/* forward the packet */
		sbuf_prepare_send(sbuf, &client->link->sbuf, pkt->len);
		break;

	/* client wants to go away */
	default:
		slog_error(client, "unknown pkt from client: %d/0x%x", pkt->type, pkt->type);
		disconnect_client(client, true, "unknown pkt");
		return false;
	case 'X': /* Terminate */
		disconnect_client(client, false, "client close request");
		return false;
	}
	return true;
}