Ejemplo n.º 1
0
GeoIPRecord    *
GeoIP_record_by_addr(GeoIP * gi, const char *addr)
{
  unsigned long   ipnum;
  if (addr == NULL) {
    return 0;
  }
  ipnum = GeoIP_addr_to_num(addr);
  return _get_record(gi, ipnum);
}
Ejemplo n.º 2
0
int
GeoIP_record_id_by_addr(GeoIP * gi, const char *addr)
{
  unsigned long   ipnum;
  if (gi->databaseType != GEOIP_CITY_EDITION_REV0 &&
      gi->databaseType != GEOIP_CITY_EDITION_REV1) {
    printf("Invalid database type %s, expected %s\n", GeoIPDBDescription[(int) gi->databaseType], GeoIPDBDescription[GEOIP_CITY_EDITION_REV1]);
    return 0;
  }
  if (addr == NULL) {
    return 0;
  }
  ipnum = GeoIP_addr_to_num(addr);
  return _GeoIP_seek_record(gi, ipnum);
}
Ejemplo n.º 3
0
/* Returns the numeric form of an IP address.
 *
 * For example:
 * 24.24.24.24 => 404232216
 *
 * This is used in order to be able to perform searches in CSV versions of the
 * data files or in SQL records if the data has been put there.
 */
VALUE rb_geoip_addr_to_num(VALUE self, VALUE addr) {
  Check_Type(addr, T_STRING);
  return UINT2NUM((unsigned int)GeoIP_addr_to_num(StringValuePtr(addr)));
}
Ejemplo n.º 4
0
/*
===========
ClientConnect

Called when a player begins connecting to the server.
Called again for every map change or tournement restart.

The session information will be valid after exit.

Return NULL if the client should be allowed, otherwise return
a string with the reason for denial.

Otherwise, the client will be sent the current gamestate
and will eventually get to ClientBegin.

firstTime will be qtrue the very first time a client connects
to the server machine, but qfalse on map changes and tournement
restarts.
============
*/
char *ClientConnect(int clientNum, qboolean firstTime) {
	char      *value;
	gclient_t *client;
	char      userinfo[MAX_INFO_STRING];
	gentity_t *ent;
	char      userinfo2[MAX_INFO_STRING]; // Nico, used in connections limit check
	int       i = 0;
	int       clientNum2; // Nico, used in connections limit check
	int       conn_per_ip = 1; // Nico, connections per IP counter
	char      ip[20], ip2[20]; // Nico, used in connections limit check
	char      parsedIp[20], parsedIp2[20]; // Nico, used in connections limit check
	char      cs_name[MAX_NETNAME];

	ent = &g_entities[clientNum];

	trap_GetUserinfo(clientNum, userinfo, sizeof (userinfo));

	// IP filtering
	// show_bug.cgi?id=500
	// recommanding PB based IP / GUID banning, the builtin system is pretty limited
	// check to see if they are on the banned IP list
	value = Info_ValueForKey(userinfo, "ip");
	if (G_FilterIPBanPacket(value)) {
		return "You are banned from this server.";
	}

	// Nico, check maximum connections per IP (from ETpub)
	// (prevents fakeplayers DOS http://aluigi.altervista.org/fakep.htm )
	// note: value is the client ip
	if (!getParsedIp(value, parsedIp)) {
		return "Invalid IP address";
	}
	Q_strncpyz(ip, parsedIp, sizeof (ip));
	for (i = 0; i < level.numConnectedClients; ++i) {
		clientNum2 = level.sortedClients[i];
		if (clientNum == clientNum2) {
			continue;
		}
		trap_GetUserinfo(clientNum2, userinfo2, sizeof (userinfo2));
		value = Info_ValueForKey(userinfo2, "ip");
		if (!getParsedIp(value, parsedIp2)) {
			continue;
		}
		Q_strncpyz(ip2, parsedIp2, sizeof (ip2));
		if (strcmp(ip, ip2) == 0) {
			conn_per_ip++;
		}
	}
	if (conn_per_ip > g_maxConnsPerIP.integer) {
		G_LogPrintf("%s: possible DoS attack, rejecting client from %s (%d connections already)\n", GAME_VERSION, ip, g_maxConnsPerIP.integer);
		return "Too many connections from your IP.";
	}
	// Nico, end of check maximum connections per IP

	// Nico, check name
	value = Info_ValueForKey(userinfo, "name");
	Q_strncpyz(cs_name, value, sizeof (cs_name));
	if (CheckName(cs_name) != qtrue) {
		return "Bad name: extended ASCII characters or too long name. Please change your name.";
	}

	// we don't check password for bots and local client
	// NOTE: local client <-> "ip" "localhost"
	//   this means this client is not running in our current process
	if (strcmp(Info_ValueForKey(userinfo, "ip"), "localhost") != 0) {
		// check for a password
		value = Info_ValueForKey(userinfo, "password");
		if (g_password.string[0] &&
			Q_stricmp(g_password.string, "none") &&
			strcmp(g_password.string, value) != 0 &&
			(!sv_privatepassword.string[0] || strcmp(sv_privatepassword.string, value) != 0)) {
			return "Invalid password";
		}
	}

	// Gordon: porting q3f flag bug fix
	// If a player reconnects quickly after a disconnect, the client disconnect may never be called, thus flag can get lost in the ether
	if (ent->inuse) {
		G_LogPrintf("Forcing disconnect on active client: %d\n", (int)(ent - g_entities));
		// so lets just fix up anything that should happen on a disconnect
		ClientDisconnect(ent - g_entities);
	}

	// they can connect
	ent->client = level.clients + clientNum;
	client      = ent->client;

	memset(client, 0, sizeof (*client));

	client->pers.connected   = CON_CONNECTING;

	// read or initialize the session data
	if (firstTime) {
		G_InitSessionData(client);
		client->pers.enterTime            = level.time;
		client->ps.persistant[PERS_SCORE] = 0;
	} else {
		G_ReadSessionData(client);
	}
	client->pers.enterTime = level.time;

	if (firstTime) {
		// force into spectator
		client->sess.sessionTeam     = TEAM_SPECTATOR;
		client->sess.spectatorState  = SPECTATOR_FREE;
		client->sess.spectatorClient = 0;

		// unlink the entity - just in case they were already connected
		trap_UnlinkEntity(ent);
	}

	// Nico, GeoIP
	if (gidb != NULL) {
		value = Info_ValueForKey (userinfo, "ip");
		if (!strcmp(value, "localhost")) {
			client->sess.countryCode = 0;
		} else {
			char realIP[IP_MAX_LENGTH] = {0};// Nico, used to store IP without :port
			unsigned long ip;

			// Nico, remove :port from IP
			sscanf(value, "%15[0-9.]:%*d", realIP);

			ip = GeoIP_addr_to_num(realIP);

			if (((ip & 0xFF000000) == 0x0A000000) ||
				((ip & 0xFFF00000) == 0xAC100000) ||
				((ip & 0xFFFF0000) == 0xC0A80000) ||
				( ip == 0x7F000001) ) {
				client->sess.countryCode = 246;
			} else {
				unsigned int ret = GeoIP_seek_record(gidb, ip);
				if (ret > 0) {
					client->sess.countryCode = ret;
				} else {
					client->sess.countryCode = 246;
					G_LogPrintf("GeoIP: This IP:%s cannot be located\n", realIP);
				}
			}
		}
	} else {
		client->sess.countryCode = 255;
	}
	// Nico, end of GeoIP

	// get and distribute relevent paramters
	G_LogPrintf("ClientConnect: %i\n", clientNum);
	G_UpdateCharacter(client);
	ClientUserinfoChanged(clientNum);

	// don't do the "xxx connected" messages if they were caried over from previous level
	//		TAT 12/10/2002 - Don't display connected messages in single player

	if (firstTime) {
		trap_SendServerCommand(-1, va("cpm \"%s" S_COLOR_WHITE " connected\n\"", client->pers.netname));
	}

	// count current clients and rank for scoreboard
	CalculateRanks();

	return NULL;
}