// Returns 0 on success, -1 on failure
// If a failure occurs the password will contain a description of the error
int Keygen(char const *_sysInfoData, int _sysInfoLen, char const *_userInfoFilename, char const **_password)
{
	int userInfoLen;
	char *userInfoData = ReadFileToBuf(_userInfoFilename, &userInfoLen);
	if (!userInfoData)
	{
		*_password = "******";
		return -1;
	}

	char const *validationResult = ValidateSysInfo(_sysInfoData, _sysInfoLen);
	if (validationResult)
	{
		*_password = validationResult;
		return -1;
	}
	validationResult = ValidateUserInfo(userInfoData, userInfoLen);
	if (validationResult)
	{
		*_password = validationResult;
		return -1;
	}

	unsigned int sysKey = GenerateKey(_sysInfoData, _sysInfoLen);
	unsigned int userKey = GenerateKey(userInfoData, userInfoLen);

	MakePasswordFromKey(userKey, sysKey, _password);

	delete [] userInfoData;

	return 0;
}
Ejemplo n.º 2
0
/*
 * Sv_UserInfoChanged
 *
 * Enforces safe user_info data before passing onto game module.
 */
void Sv_UserInfoChanged(sv_client_t *cl) {
	char *val;
	size_t i;

	if (*cl->user_info == '\0') { // catch empty user_info
		Com_Print("Empty user_info from %s\n", Sv_NetaddrToString(cl));
		Sv_KickClient(cl, "Bad user info");
		return;
	}

	if (strchr(cl->user_info, '\xFF')) { // catch end of message exploit
		Com_Print("Illegal user_info contained xFF from %s\n",
				Sv_NetaddrToString(cl));
		Sv_KickClient(cl, "Bad user info");
		return;
	}

	if (!ValidateUserInfo(cl->user_info)) { // catch otherwise invalid user_info
		Com_Print("Invalid user_info from %s\n", Sv_NetaddrToString(cl));
		Sv_KickClient(cl, "Bad user info");
		return;
	}

	val = GetUserInfo(cl->user_info, "skin");
	if (strstr(val, "..")) // catch malformed skins
		SetUserInfo(cl->user_info, "skin", "enforcer/qforcer");

	// call game code to allow overrides
	svs.game->ClientUserInfoChanged(cl->edict, cl->user_info);

	// name for C code, mask off high bit
	strncpy(cl->name, GetUserInfo(cl->user_info, "name"), sizeof(cl->name) - 1);
	for (i = 0; i < sizeof(cl->name); i++) {
		cl->name[i] &= 127;
	}

	// rate command
	val = GetUserInfo(cl->user_info, "rate");
	if (*val != '\0') {
		cl->rate = atoi(val);

		if (cl->rate > CLIENT_RATE_MAX)
			cl->rate = CLIENT_RATE_MAX;
		else if (cl->rate < CLIENT_RATE_MIN)
			cl->rate = CLIENT_RATE_MIN;
	}

	// limit the print messages the client receives
	val = GetUserInfo(cl->user_info, "message_level");
	if (*val != '\0') {
		cl->message_level = atoi(val);
	}

	// start/stop sending view angles for demo recording
	val = GetUserInfo(cl->user_info, "recording");
	cl->recording = atoi(val) == 1;
}
Ejemplo n.º 3
0
/*
 * @brief Enforces safe user_info data before passing onto game module.
 */
void Sv_UserInfoChanged(sv_client_t *cl) {
	char *val;
	size_t i;

	if (*cl->user_info == '\0') { // catch empty user_info
		Com_Print("Empty user_info from %s\n", Sv_NetaddrToString(cl));
		Sv_KickClient(cl, "Bad user info");
		return;
	}

	if (strchr(cl->user_info, '\xFF')) { // catch end of message exploit
		Com_Print("Illegal user_info contained xFF from %s\n", Sv_NetaddrToString(cl));
		Sv_KickClient(cl, "Bad user info");
		return;
	}

	if (!ValidateUserInfo(cl->user_info)) { // catch otherwise invalid user_info
		Com_Print("Invalid user_info from %s\n", Sv_NetaddrToString(cl));
		Sv_KickClient(cl, "Bad user info");
		return;
	}

	// call game code to allow overrides
	svs.game->ClientUserInfoChanged(cl->entity, cl->user_info);

	// name for C code, mask off high bit
	g_strlcpy(cl->name, GetUserInfo(cl->user_info, "name"), sizeof(cl->name));
	for (i = 0; i < sizeof(cl->name); i++) {
		cl->name[i] &= 127;
	}

	// rate command
	val = GetUserInfo(cl->user_info, "rate");
	if (*val != '\0') {
		cl->rate = strtoul(val, NULL, 10);
		if (cl->rate > 0 && cl->rate < CLIENT_RATE_MIN) {
			cl->rate = CLIENT_RATE_MIN;
		}
	}

	// limit the print messages the client receives
	val = GetUserInfo(cl->user_info, "message_level");
	if (*val != '\0') {
		cl->message_level = strtoul(val, NULL, 10);
	}
}
Ejemplo n.º 4
0
ECode CURI::ParseAuthority(
    /* [in] */ Boolean forceServer)
{
    if (mAuthority.IsNull()) {
        return NOERROR;
    }

    String tempUserInfo;
    String temp = mAuthority;
    Int32 index = temp.IndexOf('@');
    Int32 hostIndex = 0;
    if (index != -1) {
        // remove user info
        tempUserInfo = temp.Substring(0, index);
        FAIL_RETURN(ValidateUserInfo(mAuthority, tempUserInfo, 0));
        temp = temp.Substring(index + 1); // host[:port] is left
        hostIndex = index + 1;
    }

    index = temp.LastIndexOf(':');
    Int32 endIndex = temp.IndexOf(']');

    String tempHost;
    Int32 tempPort = -1;
    if (index != -1 && endIndex < index) {
        // determine port and host
        tempHost = temp.Substring(0, index);

        Char32 firstPortChar = temp.GetChar(index + 1);
        if (firstPortChar >= '0' && firstPortChar <= '9') {
            // allow only digits, no signs
            ECode ec = StringUtils::Parse(temp.Substring(index + 1), &tempPort);
            if (ec == (ECode)E_NUMBER_FORMAT_EXCEPTION) {
                if (forceServer) {
                    ALOGE("%s Invalid port number %d", mAuthority.string(), hostIndex + index + 1);
                    return E_URI_SYNTAX_EXCEPTION;
                }
                return NOERROR;
            }
        } else {
            if (forceServer) {
                ALOGE("%s Invalid port number %d", mAuthority.string(), hostIndex + index + 1);
                return E_URI_SYNTAX_EXCEPTION;
            }
            return NOERROR;
        }
    }
    else {
        tempHost = temp;
    }

    if (tempHost.IsEmpty()) {
        if (forceServer) {
            return E_URI_SYNTAX_EXCEPTION;
        }
        return NOERROR;
    }

    Boolean isValid = FALSE;
    FAIL_RETURN(IsValidHost(forceServer, tempHost, &isValid));
    if (!isValid) {
        return NOERROR;
    }

    // this is a server based uri,
    // fill in the userInfo, host and port fields
    mUserInfo = tempUserInfo;
    mHost = tempHost;
    mPort = tempPort;
    mServerAuthority = TRUE;

    return NOERROR;
}
Ejemplo n.º 5
0
/*
 * G_ClientUserInfoChanged
 */
void G_ClientUserInfoChanged(g_edict_t *ent, const char *user_info) {
	const char *s;
	char *c;
	char name[MAX_NET_NAME];
	int player_num, i;
	boolean_t color;
	g_client_t *cl;

	// check for malformed or illegal info strings
	if (!ValidateUserInfo(user_info)) {
		user_info = "\\name\\newbie\\skin\\qforcer/enforcer";
	}

	cl = ent->client;

	// set name, use a temp buffer to compute length and crutch up bad names
	s = GetUserInfo(user_info, "name");

	strncpy(name, s, sizeof(name) - 1);
	name[sizeof(name) - 1] = 0;

	color = false;
	c = name;
	i = 0;

	// trim to 15 printable chars
	while (i < 15) {

		if (!*c)
			break;

		if (IS_COLOR(c)) {
			color = true;
			c += 2;
			continue;
		}

		c++;
		i++;
	}
	name[c - name] = 0;

	if (!i) // name had nothing printable
		strcpy(name, "newbie");

	if (color) // reset to white
		strcat(name, "^7");

	if (strncmp(cl->persistent.net_name, name, sizeof(cl->persistent.net_name))) {

		if (*cl->persistent.net_name != '\0')
			gi.BroadcastPrint(PRINT_MEDIUM, "%s changed name to %s\n",
					cl->persistent.net_name, name);

		strncpy(cl->persistent.net_name, name, sizeof(cl->persistent.net_name) - 1);
		cl->persistent.net_name[sizeof(cl->persistent.net_name) - 1] = 0;
	}

#ifdef HAVE_MYSQL
	if(mysql != NULL) { // escape name for safe db insertions

		StripColor(cl->persistent.net_name, name);

		mysql_real_escape_string(mysql, name, cl->persistent.sql_name,
				sizeof(cl->persistent.sql_name));
	}
#endif

	// set skin
	if ((g_level.teams || g_level.ctf) && cl->persistent.team) // players must use team_skin to change
		s = cl->persistent.team->skin;
	else
		s = GetUserInfo(user_info, "skin");

	if (*s != '\0') // something valid-ish was provided
		strncpy(cl->persistent.skin, s, sizeof(cl->persistent.skin) - 1);
	else {
		strcpy(cl->persistent.skin, "qforcer/enforcer");
		cl->persistent.skin[sizeof(cl->persistent.skin) - 1] = 0;
	}

	// set color
	s = GetUserInfo(user_info, "color");
	cl->persistent.color = ColorByName(s, 243);

	player_num = ent - g_game.edicts - 1;

	// combine name and skin into a config_string
	gi.ConfigString(CS_CLIENT_INFO + player_num,
			va("%s\\%s", cl->persistent.net_name, cl->persistent.skin));

	// save off the user_info in case we want to check something later
	strncpy(ent->client->persistent.user_info, user_info, sizeof(ent->client->persistent.user_info) - 1);
}
Ejemplo n.º 6
0
/*
 * @brief A connection request that did not come from the master.
 */
static void Svc_Connect(void) {
	char user_info[MAX_USER_INFO_STRING];
	sv_client_t *cl, *client;
	int32_t i;

	Com_Debug("Svc_Connect()\n");

	net_addr_t *addr = &net_from;

	const int32_t version = strtol(Cmd_Argv(1), NULL, 0);

	// resolve protocol
	if (version != PROTOCOL) {
		Netchan_OutOfBandPrint(NS_UDP_SERVER, addr, "print\nServer is version %d.\n", PROTOCOL);
		return;
	}

	const uint8_t qport = strtoul(Cmd_Argv(2), NULL, 0);

	const uint32_t challenge = strtoul(Cmd_Argv(3), NULL, 0);

	// copy user_info, leave room for ip stuffing
	g_strlcpy(user_info, Cmd_Argv(4), sizeof(user_info) - 25);

	if (*user_info == '\0') { // catch empty user_info
		Com_Print("Empty user_info from %s\n", Net_NetaddrToString(addr));
		Netchan_OutOfBandPrint(NS_UDP_SERVER, addr, "print\nConnection refused\n");
		return;
	}

	if (strchr(user_info, '\xFF')) { // catch end of message in string exploit
		Com_Print("Illegal user_info contained xFF from %s\n", Net_NetaddrToString(addr));
		Netchan_OutOfBandPrint(NS_UDP_SERVER, addr, "print\nConnection refused\n");
		return;
	}

	if (strlen(GetUserInfo(user_info, "ip"))) { // catch spoofed ips
		Com_Print("Illegal user_info contained ip from %s\n", Net_NetaddrToString(addr));
		Netchan_OutOfBandPrint(NS_UDP_SERVER, addr, "print\nConnection refused\n");
		return;
	}

	if (!ValidateUserInfo(user_info)) { // catch otherwise invalid user_info
		Com_Print("Invalid user_info from %s\n", Net_NetaddrToString(addr));
		Netchan_OutOfBandPrint(NS_UDP_SERVER, addr, "print\nConnection refused\n");
		return;
	}

	// force the ip so the game can filter on it
	SetUserInfo(user_info, "ip", Net_NetaddrToString(addr));

	// enforce a valid challenge to avoid denial of service attack
	for (i = 0; i < MAX_CHALLENGES; i++) {
		if (Net_CompareClientNetaddr(addr, &svs.challenges[i].addr)) {
			if (challenge == svs.challenges[i].challenge) {
				svs.challenges[i].challenge = 0;
				break; // good
			}
			Netchan_OutOfBandPrint(NS_UDP_SERVER, addr, "print\nBad challenge\n");
			return;
		}
	}
	if (i == MAX_CHALLENGES) {
		Netchan_OutOfBandPrint(NS_UDP_SERVER, addr, "print\nNo challenge for address\n");
		return;
	}

	// resolve the client slot
	client = NULL;

	// first check for an ungraceful reconnect (client crashed, perhaps)
	for (i = 0, cl = svs.clients; i < sv_max_clients->integer; i++, cl++) {

		const net_chan_t *ch = &cl->net_chan;

		if (cl->state == SV_CLIENT_FREE) // not in use, not interested
			continue;

		// the base address and either the qport or real port must match
		if (Net_CompareClientNetaddr(addr, &ch->remote_address)) {

			if (addr->port == ch->remote_address.port || qport == ch->qport) {
				client = cl;
				break;
			}
		}
	}

	// otherwise, treat as a fresh connect to a new slot
	if (!client) {
		for (i = 0, cl = svs.clients; i < sv_max_clients->integer; i++, cl++) {
			if (cl->state == SV_CLIENT_FREE && !cl->edict->ai) { // we have a free one
				client = cl;
				break;
			}
		}
	}

	// no soup for you, next!!
	if (!client) {
		Netchan_OutOfBandPrint(NS_UDP_SERVER, addr, "print\nServer is full\n");
		Com_Debug("Rejected a connection\n");
		return;
	}

	// give the game a chance to reject this connection or modify the user_info
	if (!(svs.game->ClientConnect(client->edict, user_info))) {
		const char *rejmsg = GetUserInfo(user_info, "rejmsg");

		if (strlen(rejmsg)) {
			Netchan_OutOfBandPrint(NS_UDP_SERVER, addr, "print\n%s\nConnection refused\n", rejmsg);
		} else {
			Netchan_OutOfBandPrint(NS_UDP_SERVER, addr, "print\nConnection refused\n");
		}

		Com_Debug("Game rejected a connection\n");
		return;
	}

	// parse some info from the info strings
	g_strlcpy(client->user_info, user_info, sizeof(client->user_info));
	Sv_UserInfoChanged(client);

	// send the connect packet to the client
	Netchan_OutOfBandPrint(NS_UDP_SERVER, addr, "client_connect %s", sv_download_url->string);

	Netchan_Setup(NS_UDP_SERVER, &client->net_chan, addr, qport);

	Mem_InitBuffer(&client->datagram.buffer, client->datagram.data, sizeof(client->datagram.data));
	client->datagram.buffer.allow_overflow = true;

	client->last_message = svs.real_time; // don't timeout

	client->state = SV_CLIENT_CONNECTED;
}