Exemple #1
0
/* "do_parse" - the user interface input/output to files.

 The internal R_Parse.. functions are defined in ./gram.y (-> gram.c)

 .Internal( parse(file, n, text, prompt, srcfile, encoding) )
 If there is text then that is read and the other arguments are ignored.
*/
SEXP attribute_hidden do_parse(/*const*/ CXXR::Expression* call, const CXXR::BuiltInFunction* op, CXXR::Environment* env, CXXR::RObject* const* args, int num_args, const CXXR::PairList* tags)
{
    SEXP text, prompt, s, source;
    Rconnection con;
    Rboolean wasopen, old_latin1 = known_to_be_latin1,
	old_utf8 = known_to_be_utf8, allKnown = TRUE;
    int ifile, num, i;
    const char *encoding;
    ParseStatus status;

    op->checkNumArgs(num_args, call);
    R_ParseError = 0;
    R_ParseErrorMsg[0] = '\0';

    ifile = asInteger(args[0]);                       args = (args + 1);

    con = getConnection(ifile);
    wasopen = con->isopen;
    num = asInteger(args[0]);				args = (args + 1);
    if (num == 0)
	return(allocVector(EXPRSXP, 0));

    PROTECT(text = coerceVector(args[0], STRSXP));
    if(length(args[0]) && !length(text))
	errorcall(call, _("coercion of 'text' to character was unsuccessful"));
    args = (args + 1);
    prompt = args[0];					args = (args + 1);
    source = args[0];					args = (args + 1);
    if(!isString(args[0]) || LENGTH(args[0]) != 1)
	error(_("invalid '%s' value"), "encoding");
    encoding = CHAR(STRING_ELT(args[0], 0)); /* ASCII */
    known_to_be_latin1 = known_to_be_utf8 = FALSE;
    /* allow 'encoding' to override declaration on 'text'. */
    if(streql(encoding, "latin1")) {
	known_to_be_latin1 = TRUE;
	allKnown = FALSE;
    } else if(streql(encoding, "UTF-8"))  {
	known_to_be_utf8 = TRUE;
	allKnown = FALSE;
    } else if(!streql(encoding, "unknown") && !streql(encoding, "native.enc")) 
    	warning(_("argument '%s = \"%s\"' will be ignored"), "encoding", encoding);

    if (prompt == R_NilValue)
	PROTECT(prompt);
    else
	PROTECT(prompt = coerceVector(prompt, STRSXP));

    if (length(text) > 0) {
	/* If 'text' has known encoding then we can be sure it will be
	   correctly re-encoded to the current encoding by
	   translateChar in the parser and so could mark the result in
	   a Latin-1 or UTF-8 locale.

	   A small complication is that different elements could have
	   different encodings, but all that matters is that all
	   non-ASCII elements have known encoding.
	*/
	for(i = 0; i < length(text); i++)
	    if(!ENC_KNOWN(STRING_ELT(text, i)) &&
	       !IS_ASCII(STRING_ELT(text, i))) {
		allKnown = FALSE;
		break;
	    }
	if(allKnown) {
	    known_to_be_latin1 = old_latin1;
	    known_to_be_utf8 = old_utf8;
	}
	if (num == NA_INTEGER) num = -1;
	s = R_ParseVector(text, num, &status, source);
	if (status != PARSE_OK) parseError(call, R_ParseError);
    }
    else if (ifile >= 3) {/* file != "" */
	if (num == NA_INTEGER) num = -1;
	try {
	    if(!wasopen && !con->open(con))
		error(_("cannot open the connection"));
	    if(!con->canread) error(_("cannot read from this connection"));
	    s = R_ParseConn(con, num, &status, source);
	    if(!wasopen) con->close(con);
	} catch (...) {
	    if (!wasopen && con->isopen)
		con->close(con);
	    throw;
	}
	if (status != PARSE_OK) parseError(call, R_ParseError);
    }
    else {
	if (num == NA_INTEGER) num = 1;
	s = R_ParseBuffer(&R_ConsoleIob, num, &status, prompt, source);
	if (status != PARSE_OK) parseError(call, R_ParseError);
    }
    UNPROTECT(2);
    known_to_be_latin1 = old_latin1;
    known_to_be_utf8 = old_utf8;
    return s;
}
Exemple #2
0
SEXP countfields(SEXP args)
{
    SEXP ans, file, sep,  bns, quotes, comstr;
    int nfields, nskip, i, c, inquote, quote = 0;
    int blocksize, nlines, blskip;
    const char *p;
    Rboolean dbcslocale = (MB_CUR_MAX == 2);
    LocalData data = {NULL, 0, 0, '.', NULL, NO_COMCHAR, 0, NULL, FALSE,
		      FALSE, 0, FALSE, FALSE};
    data.NAstrings = R_NilValue;

    args = CDR(args);

    file = CAR(args);	args = CDR(args);
    sep = CAR(args);	args = CDR(args);
    quotes = CAR(args);	 args = CDR(args);
    nskip = asInteger(CAR(args));  args = CDR(args);
    blskip = asLogical(CAR(args)); args = CDR(args);
    comstr = CAR(args);
    if (TYPEOF(comstr) != STRSXP || length(comstr) != 1)
	error(_("invalid '%s' argument"), "comment.char");
    p = translateChar(STRING_ELT(comstr, 0));
    data.comchar = NO_COMCHAR; /*  here for -Wall */
    if (strlen(p) > 1)
	error(_("invalid '%s' argument"), "comment.char");
    else if (strlen(p) == 1) data.comchar = (unsigned char)*p;

    if (nskip < 0 || nskip == NA_INTEGER) nskip = 0;
    if (blskip == NA_LOGICAL) blskip = 1;

    if (isString(sep) || isNull(sep)) {
	if (length(sep) == 0) data.sepchar = 0;
	else data.sepchar = (unsigned char) translateChar(STRING_ELT(sep, 0))[0];
	/* gets compared to chars: bug prior to 1.7.0 */
    } else error(_("invalid '%s' argument"), "sep");

    if (isString(quotes)) {
	const char *sc = translateChar(STRING_ELT(quotes, 0));
	if (strlen(sc)) data.quoteset = strdup(sc);
	else data.quoteset = "";
    } else if (isNull(quotes))
	data.quoteset = "";
    else
	error(_("invalid quote symbol set"));

    i = asInteger(file);
    data.con = getConnection(i);
    if(i == 0) {
	data.ttyflag = 1;
    } else {
	data.ttyflag = 0;
	data.wasopen = data.con->isopen;
	if(!data.wasopen) {
	    strcpy(data.con->mode, "r");
	    if(!data.con->open(data.con))
		error(_("cannot open the connection"));
	    if(!data.con->canread) {
		data.con->close(data.con);
		error(_("cannot read from this connection"));
	    } 
	} else {
	    if(!data.con->canread) 
		error(_("cannot read from this connection"));
	}
	for (i = 0; i < nskip; i++) /* MBCS-safe */
	    while ((c = scanchar(FALSE, &data)) != '\n' && c != R_EOF);
    }

    blocksize = SCAN_BLOCKSIZE;
    PROTECT(ans = allocVector(INTSXP, blocksize));
    nlines = 0;
    nfields = 0;
    inquote = 0;

    data.save = 0;

    for (;;) {
	c = scanchar(inquote, &data);
	if (c == R_EOF)	 {
	    if (nfields != 0)
		INTEGER(ans)[nlines] = nfields;
	    else nlines--;
	    goto donecf;
	}
	else if (c == '\n') {
	    if (nfields || !blskip) {
		INTEGER(ans)[nlines] = nfields;
		nlines++;
		nfields = 0;
		inquote = 0;
	    }
	    if (nlines == blocksize) {
		bns = ans;
		blocksize = 2 * blocksize;
		ans = allocVector(INTSXP, blocksize);
		UNPROTECT(1);
		PROTECT(ans);
		copyVector(ans, bns);
	    }
	    continue;
	}
	else if (data.sepchar) {
	    if (nfields == 0)
		nfields++;
	    if (inquote && (c == R_EOF || c == '\n')) {
		if(!data.wasopen) data.con->close(data.con);
		error(_("string terminated by newline or EOF"));
	    }
	    if (inquote && c == quote)
		inquote = 0;
	    else if (strchr(data.quoteset, c)) {
		inquote = 1;
		quote = c;
	    }
	    if (c == data.sepchar && !inquote)
		nfields++;
	}
	else if (!Rspace(c)) {
	    if (strchr(data.quoteset, c)) {
		quote = c;
		inquote = 1;
		while ((c = scanchar(inquote, &data)) != quote) {
		    if (c == R_EOF || c == '\n') {
			if(!data.wasopen) data.con->close(data.con);
			error(_("string terminated by newline or EOF"));
		    }
		}
		inquote = 0;
	    } else {
		do {
		    if(dbcslocale && btowc(c) == WEOF) scanchar2(&data);
		    c = scanchar(FALSE, &data);
		} while (!Rspace(c) && c != R_EOF);
		if (c == R_EOF) c = '\n';
		unscanchar(c, &data);
	    }
	    nfields++;
	}

    }
 donecf:
    /* we might have a character that was unscanchar-ed.
       So pushback if possible */
    if (data.save && !data.ttyflag && data.wasopen) {
	char line[2] = " ";
	line[0] = (char) data.save;
	con_pushback(data.con, FALSE, line);
    }
    if(!data.wasopen) data.con->close(data.con);

    if (nlines < 0) {
	UNPROTECT(1);
	return R_NilValue;
    }
    if (nlines == blocksize) {
	UNPROTECT(1);
	return ans;
    }

    bns = allocVector(INTSXP, nlines+1);
    for (i = 0; i <= nlines; i++)
	INTEGER(bns)[i] = INTEGER(ans)[i];
    UNPROTECT(1);
    if (data.quoteset[0]) free(data.quoteset);
    return bns;
}
Exemple #3
0
SEXP writetable(SEXP call, SEXP op, SEXP args, SEXP env)
{
    SEXP x, sep, rnames, eol, na, dec, quote, xj;
    int nr, nc, i, j, qmethod;
    Rboolean wasopen, quote_rn = FALSE, *quote_col;
    Rconnection con;
    const char *csep, *ceol, *cna, *sdec, *tmp=NULL /* -Wall */;
    char cdec;
    SEXP *levels;
    R_StringBuffer strBuf = {NULL, 0, MAXELTSIZE};
    wt_info wi;
    RCNTXT cntxt;

    args = CDR(args);

    x = CAR(args);		   args = CDR(args);
    /* this is going to be a connection open or openable for writing */
    if(!inherits(CAR(args), "connection"))
	error(_("'file' is not a connection"));
    con = getConnection(asInteger(CAR(args))); args = CDR(args);
    if(!con->canwrite)
	error(_("cannot write to this connection"));
    wasopen = con->isopen;
    if(!wasopen) {
	strcpy(con->mode, "wt");
	if(!con->open(con)) error(_("cannot open the connection"));
    }
    nr = asInteger(CAR(args));	   args = CDR(args);
    nc = asInteger(CAR(args));	   args = CDR(args);
    rnames = CAR(args);		   args = CDR(args);
    sep = CAR(args);		   args = CDR(args);
    eol = CAR(args);		   args = CDR(args);
    na = CAR(args);		   args = CDR(args);
    dec = CAR(args);		   args = CDR(args);
    quote = CAR(args);		   args = CDR(args);
    qmethod = asLogical(CAR(args));

    if(nr == NA_INTEGER) error(_("invalid '%s' argument"), "nr");
    if(nc == NA_INTEGER) error(_("invalid '%s' argument"), "nc");
    if(!isNull(rnames) && !isString(rnames))
	error(_("invalid '%s' argument"), "rnames");
    if(!isString(sep)) error(_("invalid '%s' argument"), "sep");
    if(!isString(eol)) error(_("invalid '%s' argument"), "eol");
    if(!isString(na)) error(_("invalid '%s' argument"), "na");
    if(!isString(dec)) error(_("invalid '%s' argument"), "dec");
    if(qmethod == NA_LOGICAL) error(_("invalid '%s' argument"), "qmethod");
    csep = translateChar(STRING_ELT(sep, 0));
    ceol = translateChar(STRING_ELT(eol, 0));
    cna = translateChar(STRING_ELT(na, 0));
    sdec = translateChar(STRING_ELT(dec, 0));
    if(strlen(sdec) != 1)
	error(_("'dec' must be a single character"));
    cdec = sdec[0];
    quote_col = (Rboolean *) R_alloc(nc, sizeof(Rboolean));
    for(j = 0; j < nc; j++) quote_col[j] = FALSE;
    for(i = 0; i < length(quote); i++) { /* NB, quote might be NULL */
	int this = INTEGER(quote)[i];
	if(this == 0) quote_rn = TRUE;
	if(this >  0) quote_col[this - 1] = TRUE;
    }
    R_AllocStringBuffer(0, &strBuf);
    PrintDefaults();
    wi.savedigits = R_print.digits; R_print.digits = DBL_DIG;/* MAX precision */
    wi.con = con;
    wi.wasopen = wasopen;
    wi.buf = &strBuf;
    begincontext(&cntxt, CTXT_CCODE, call, R_BaseEnv, R_BaseEnv,
		 R_NilValue, R_NilValue);
    cntxt.cend = &wt_cleanup;
    cntxt.cenddata = &wi;

    if(isVectorList(x)) { /* A data frame */

	/* handle factors internally, check integrity */
	levels = (SEXP *) R_alloc(nc, sizeof(SEXP));
	for(j = 0; j < nc; j++) {
	    xj = VECTOR_ELT(x, j);
	    if(LENGTH(xj) != nr)
		error(_("corrupt data frame -- length of column %d does not not match nrows"), j+1);
	    if(inherits(xj, "factor")) {
		levels[j] = getAttrib(xj, R_LevelsSymbol);
	    } else levels[j] = R_NilValue;
	}

	for(i = 0; i < nr; i++) {
	    if(i % 1000 == 999) R_CheckUserInterrupt();
	    if(!isNull(rnames))
		Rconn_printf(con, "%s%s",
			     EncodeElement2(rnames, i, quote_rn, qmethod,
					    &strBuf, cdec), csep);
	    for(j = 0; j < nc; j++) {
		xj = VECTOR_ELT(x, j);
		if(j > 0) Rconn_printf(con, "%s", csep);
		if(isna(xj, i)) tmp = cna;
		else {
		    if(!isNull(levels[j])) {
			/* We do not assume factors have integer levels,
			   although they should. */
			if(TYPEOF(xj) == INTSXP)
			    tmp = EncodeElement2(levels[j], INTEGER(xj)[i] - 1,
						 quote_col[j], qmethod,
						 &strBuf, cdec);
			else if(TYPEOF(xj) == REALSXP)
			    tmp = EncodeElement2(levels[j], 
						 (int) (REAL(xj)[i] - 1),
						 quote_col[j], qmethod,
						 &strBuf, cdec);
			else
			    error("column %s claims to be a factor but does not have numeric codes", j+1);
		    } else {
			tmp = EncodeElement2(xj, i, quote_col[j], qmethod,
					     &strBuf, cdec);
		    }
		    /* if(cdec) change_dec(tmp, cdec, TYPEOF(xj)); */
		}
		Rconn_printf(con, "%s", tmp);
	    }
	    Rconn_printf(con, "%s", ceol);
	}

    } else { /* A matrix */

	if(!isVectorAtomic(x))
	    UNIMPLEMENTED_TYPE("write.table, matrix method", x);
	/* quick integrity check */
	if(LENGTH(x) != nr * nc)
	    error(_("corrupt matrix -- dims not not match length"));

	for(i = 0; i < nr; i++) {
	    if(i % 1000 == 999) R_CheckUserInterrupt();
	    if(!isNull(rnames))
		Rconn_printf(con, "%s%s",
			     EncodeElement2(rnames, i, quote_rn, qmethod,
					    &strBuf, cdec), csep);
	    for(j = 0; j < nc; j++) {
		if(j > 0) Rconn_printf(con, "%s", csep);
		if(isna(x, i + j*nr)) tmp = cna;
		else {
		    tmp = EncodeElement2(x, i + j*nr, quote_col[j], qmethod,
					&strBuf, cdec);
		    /* if(cdec) change_dec(tmp, cdec, TYPEOF(x)); */
		}
		Rconn_printf(con, "%s", tmp);
	    }
	    Rconn_printf(con, "%s", ceol);
	}

    }
    endcontext(&cntxt);
    wt_cleanup(&wi);
    return R_NilValue;
}
Exemple #4
0
int fetch_mesg_data(char *username, int mesgId, struct emaildata **mail) {
	char *query;
	struct emaildata *result;
	int col_mesgId = 0;
	int col_mesgSize = 1;
	int col_mesgSubject = 2;
	int col_mesgBody = 3;
	int col_mesgFrom = 4;
	int col_mesgTo = 5;
	char sMesgId[10];
	sqlite3_stmt *stmt;
	int retval;
	sqlite3 *handle;
	int rowCount = 0;

	getConnection(DBNAME, &handle);

	sprintf(sMesgId, "%d", mesgId);

	generateMesgQuery(username, sMesgId, &query);
	rowCount = getQueryCount(handle, query);
	if (rowCount > 0) {
		int rCounter = 0;
		retval = sqlite3_prepare_v2(handle, query, -1, &stmt, 0);
		if (retval) {
			printf("Selecting data from DB Failed\n");
			freeConnection(handle);
			return -1;
		}

		result = (struct emaildata *) malloc (sizeof (struct emaildata *) * rowCount);
		if (result == NULL) {
			perror("ERROR: Cannot allocate memory");
			freeConnection(handle);
			return(-1);
		}

		// Read the number of rows fetched
		// int cols = sqlite3_column_count(stmt);
		while(1)
		{
			// fetch a row's status
			retval = sqlite3_step(stmt);

			if(retval == SQLITE_ROW)
			{
				// SQLITE_ROW means fetched a row
				result[rCounter].mesgid = sqlite3_column_int(stmt,col_mesgId);
				result[rCounter].mesgsize = sqlite3_column_int(stmt,col_mesgSize);
				strcpy(result[rCounter].subject,(const char*)sqlite3_column_text(stmt,col_mesgSubject));
				result[rCounter].body = (char *)malloc(sizeof(char *)*result[rCounter].mesgsize);
				if (result[rCounter].body == NULL) {
					perror("ERROR: Cannot allocate memory");
					sqlite3_finalize(stmt);
					free(query);
					freeConnection(handle);
					return(-1);
				}
				strcpy(result[rCounter].body,(const char*)sqlite3_column_text(stmt,col_mesgBody));
				//From
				result[rCounter].from = (char *)malloc(sizeof(char *)*50);
				if (result[rCounter].from == NULL) {
					perror("ERROR: Cannot allocate memory");
					sqlite3_finalize(stmt);
					free(query);
					freeConnection(handle);
					return(-1);
				}
				strcpy(result[rCounter].from,(const char*)sqlite3_column_text(stmt,col_mesgFrom));
				//TO
				result[rCounter].to = (char *)malloc(sizeof(char *)*50);
				if (result[rCounter].to == NULL) {
					perror("ERROR: Cannot allocate memory");
					sqlite3_finalize(stmt);
					free(query);
					freeConnection(handle);
					return(-1);
				}
				strcpy(result[rCounter].to,(const char*)sqlite3_column_text(stmt,col_mesgTo));
				rCounter++;
			}
			else if(retval == SQLITE_DONE)
			{
				break;
			}
			else
			{
				// Some error encountered
				printf("Some error encountered\n");
				freeConnection(handle);
				return -1;
			}
		}
		sqlite3_finalize(stmt);
		*mail = result;
	}

	free(query);
	freeConnection(handle);

	return(rowCount);
}
Exemple #5
0
void ProtocolLogin::onRecvFirstMessage(NetworkMessage& msg)
{
	if (g_game.getGameState() == GAME_STATE_SHUTDOWN) {
		disconnect();
		return;
	}

	msg.skipBytes(2); // client OS

	uint16_t version = msg.get<uint16_t>();
	if (version >= 971) {
		msg.skipBytes(17);
	} else {
		msg.skipBytes(12);
	}
	/*
	 * Skipped bytes:
	 * 4 bytes: protocolVersion
	 * 12 bytes: dat, spr, pic signatures (4 bytes each)
	 * 1 byte: 0
	 */

	if (version <= 760) {
		disconnectClient("Only clients with protocol " CLIENT_VERSION_STR " allowed!", version);
		return;
	}

	if (!Protocol::RSA_decrypt(msg)) {
		disconnect();
		return;
	}

	uint32_t key[4];
	key[0] = msg.get<uint32_t>();
	key[1] = msg.get<uint32_t>();
	key[2] = msg.get<uint32_t>();
	key[3] = msg.get<uint32_t>();
	enableXTEAEncryption();
	setXTEAKey(key);

	if (version < CLIENT_VERSION_MIN || version > CLIENT_VERSION_MAX) {
		disconnectClient("Only clients with protocol " CLIENT_VERSION_STR " allowed!", version);
		return;
	}

	if (g_game.getGameState() == GAME_STATE_STARTUP) {
		disconnectClient("Gameworld is starting up. Please wait.", version);
		return;
	}

	if (g_game.getGameState() == GAME_STATE_MAINTAIN) {
		disconnectClient("Gameworld is under maintenance.\nPlease re-connect in a while.", version);
		return;
	}

	BanInfo banInfo;
	auto connection = getConnection();
	if (!connection) {
		return;
	}

	if (IOBan::isIpBanned(connection->getIP(), banInfo)) {
		if (banInfo.reason.empty()) {
			banInfo.reason = "(none)";
		}

		std::ostringstream ss;
		ss << "Your IP has been banned until " << formatDateShort(banInfo.expiresAt) << " by " << banInfo.bannedBy << ".\n\nReason specified:\n" << banInfo.reason;
		disconnectClient(ss.str(), version);
		return;
	}

	std::string accountName = msg.getString();
	if (accountName.empty()) {
		disconnectClient("Invalid account name.", version);
		return;
	}

	std::string password = msg.getString();
	auto thisPtr = std::dynamic_pointer_cast<ProtocolLogin>(shared_from_this());
	g_dispatcher.addTask(createTask(std::bind(&ProtocolLogin::getCharacterList, thisPtr, accountName, password, version)));
}
Exemple #6
0
bool ProtocolLogin::parseFirstPacket(NetworkMessage& msg)
{	
	if(g_game.getGameState() == GAME_STATE_SHUTDOWN){
		getConnection()->closeConnection();
		return false;
	}

	uint32_t clientip = getConnection()->getIP();

	/*uint16_t clientos =*/ msg.GetU16();
	uint16_t version  = msg.GetU16();
	msg.SkipBytes(12);
	
	if(version <= 760){
		disconnectClient(0x0A, STRING_CLIENT_VERSION);
	}

	if(!RSA_decrypt(g_otservRSA, msg)){
		getConnection()->closeConnection();
		return false;
	}

	uint32_t key[4];
	key[0] = msg.GetU32();
	key[1] = msg.GetU32();
	key[2] = msg.GetU32();
	key[3] = msg.GetU32();
	enableXTEAEncryption();
	setXTEAKey(key);

	uint32_t accnumber = msg.GetU32();
	std::string password = msg.GetString();

	if(!accnumber){
		disconnectClient(0x0A, "You must enter your account number.");
		return false;
	}

	if(version < CLIENT_VERSION_MIN || version > CLIENT_VERSION_MAX){
		disconnectClient(0x0A, STRING_CLIENT_VERSION);
		return false;
	}

	if(g_game.getGameState() == GAME_STATE_STARTUP){
		disconnectClient(0x0A, "Gameworld is starting up. Please wait.");
		return false;
	}

	if(g_bans.isIpDisabled(clientip)){
		disconnectClient(0x0A, "Too many connections attempts from this IP. Try again later.");
		return false;
	}
	
	if(g_bans.isIpBanished(clientip)){
		disconnectClient(0x0A, "Your IP is banished!");
		return false;
	}

	uint32_t serverip = serverIPs[0].first;
	for(uint32_t i = 0; i < serverIPs.size(); i++){
		if((serverIPs[i].first & serverIPs[i].second) == (clientip & serverIPs[i].second)){
			serverip = serverIPs[i].first;
			break;
		}
	}
	
	Account account = IOAccount::instance()->loadAccount(accnumber);
	if(!(accnumber != 0 && account.accnumber == accnumber &&
			passwordTest(password, account.password))){

		g_bans.addLoginAttempt(clientip, false);
		disconnectClient(0x0A, "Please enter a valid account number and password.");
		return false;
	}

	g_bans.addLoginAttempt(clientip, true);
		
	
	OutputMessage* output = OutputMessagePool::getInstance()->getOutputMessage(this, false);
	//Add MOTD
	std::stringstream motd;
	output->AddByte(0x14);
	motd << g_config.getNumber(ConfigManager::MOTD_NUM) << "\n";
	motd << g_config.getString(ConfigManager::MOTD);
	output->AddString(motd.str());
	//Add char list
	output->AddByte(0x64);
	output->AddByte((uint8_t)account.charList.size());
	std::list<std::string>::iterator it;
	for(it = account.charList.begin(); it != account.charList.end(); it++){
		output->AddString((*it));
		output->AddString(g_config.getString(ConfigManager::WORLD_NAME));
		output->AddU32(serverip);
		output->AddU16(g_config.getNumber(ConfigManager::PORT));
	}
	//Add premium days
	output->AddU16(account.premiumDays);//output->AddU16(0);
	
	OutputMessagePool::getInstance()->send(output);
	getConnection()->closeConnection();

	return true;
}
Exemple #7
0
int storeMail(char *from, char to[50][100], char *subject, char *msg, int noRcpt) {
	char query[4000];
	char msgId[1000];
	char msgSize[1000];
	sqlite3 *handle;
	int iCount;
	int retval;

	sprintf( msgId, "%d", getNextMailId());
	sprintf( msgSize, "%d", (int)strlen(msg));

	memset(query,'0',4000);
	//INSERT MAIL
	strcpy(query,dml_insert_mails);
	strcat(query,msgId);
	strcat(query,", ");
	strcat(query,msgSize);
	strcat(query,", '");
	strcat(query,subject);
	strcat(query,"', '");
	strcat(query,msg);
	strcat(query,"')");

	getConnection(DBNAME, &handle);
	retval = sqlite3_exec(handle, query, 0, 0, 0);
	if (retval == -1) {
		perror("ERROR: Cannot insert data in the table");
		freeConnection(handle);
		return(-1);
	}

	//INSERT MAILBOX

	memset(query,'0',4000);
	for (iCount = 0; iCount < noRcpt; iCount++) {
		strcpy(query,dml_insert_mailboxes);
		strcat(query,msgId);
		strcat(query,", '");
		strcat(query,from);
		strcat(query,"', '");
		strcat(query,to[iCount]);
		strcat(query,"', 0)");

		retval = sqlite3_exec(handle, query, 0, 0, 0);
		if (retval == -1) {
			perror("ERROR: Cannot insert data in the table");
			freeConnection(handle);
			return(-1);
		}
	}

	memset(query,'0',4000);
	strcpy(query,"commit");

	retval = sqlite3_exec(handle, query, 0, 0, 0);
	if (retval == -1) {
		perror("ERROR: Cannot insert data in the table");
		freeConnection(handle);
		return(-1);
	}

	freeConnection(handle);
	return(0);
}
Exemple #8
0
//----------------------------------------------------------------------------
void ctkPluginStorageSQL::updateDB()
{
  QSqlDatabase database = getConnection();
  QSqlQuery query(database);

  beginTransaction(&query, Write);

  // 1. Get the state information of all plug-ins (it is assumed that
  //    plug-ins marked as UNINSTALLED (startlevel == -2) are already removed

  QString statement = "SELECT ID,MAX(Generation),Location,LocalPath,Timestamp,StartLevel,AutoStart,K "
                      "FROM " PLUGINS_TABLE " GROUP BY ID";

  QList<int> outdatedIds;
  QList<QSharedPointer<ctkPluginArchiveSQL> > updatedPluginArchives;
  try
  {
    executeQuery(&query, statement);

    // 2. Check the timestamp for each plug-in

    while (query.next())
    {
      QFileInfo pluginInfo(query.value(EBindIndex3).toString());
      QDateTime pluginLastModified = pluginInfo.lastModified();
      // Make sure the QDateTime has the same accuracy as the one in the database
      pluginLastModified = getQDateTimeFromString(getStringFromQDateTime(pluginLastModified));

      if (pluginLastModified > getQDateTimeFromString(query.value(EBindIndex4).toString()))
      {
        QSharedPointer<ctkPluginArchiveSQL> updatedPA(
              new ctkPluginArchiveSQL(this,
                                      query.value(EBindIndex2).toUrl(),    // plug-in location url
                                      query.value(EBindIndex3).toString(), // plugin local path
                                      query.value(EBindIndex).toInt(),     // plugin id
                                      query.value(EBindIndex5).toInt(),    // start level
                                      QDateTime(),                         // last modififed
                                      query.value(EBindIndex6).toInt())    // auto start setting
              );
        updatedPA->key = query.value(EBindIndex7).toInt();
        updatedPluginArchives << updatedPA;

        // remember the plug-in ids for deletion
        outdatedIds << query.value(EBindIndex).toInt();
      }
    }
  }
  catch (...)
  {
    rollbackTransaction(&query);
    throw;
  }

  query.finish();
  query.clear();

  if (!outdatedIds.isEmpty())
  {
    // 3. Remove all traces from outdated plug-in data. Due to cascaded delete,
    //    it is sufficient to remove the records from the main table

    statement = "DELETE FROM " PLUGINS_TABLE " WHERE ID IN (%1)";
    QString idStr;
    foreach(int id, outdatedIds)
    {
      idStr += QString::number(id) + ",";
    }
bool ProtocolLogin::parseFirstPacket(NetworkMessage& msg)
{
	if (g_game.getGameState() == GAME_STATE_SHUTDOWN) {
		getConnection()->closeConnection();
		return false;
	}

	uint32_t clientip = getConnection()->getIP();

	/*uint16_t clientos = */
	msg.GetU16();
	uint16_t version = msg.GetU16();
	msg.SkipBytes(12);

	/*
	 * Skipped bytes:
	 * 12 bytes: dat, spr, pic signatures (4 bytes each)
	*/

	#ifdef __PROTOCOL_77__
	if (!RSA_decrypt(msg)) {
		getConnection()->closeConnection();
		return false;
	}

	uint32_t key[4];
	key[0] = msg.GetU32();
	key[1] = msg.GetU32();
	key[2] = msg.GetU32();
	key[3] = msg.GetU32();
	enableXTEAEncryption();
	setXTEAKey(key);
	#endif

	uint32_t accountName = msg.GetU32();
	std::string password = msg.GetString();

	if (version < CLIENT_VERSION_MIN || version > CLIENT_VERSION_MAX) {
		disconnectClient(0x0A, "Only clients with protocol " CLIENT_VERSION_STR " allowed!");
		return false;
	}

	if (g_game.getGameState() == GAME_STATE_STARTUP) {
		disconnectClient(0x0A, "Gameworld is starting up. Please wait.");
		return false;
	}

	if (g_game.getGameState() == GAME_STATE_MAINTAIN) {
		disconnectClient(0x0A, "Gameworld is under maintenance. Please re-connect in a while.");
		return false;
	}

	BanInfo banInfo;
	if (IOBan::getInstance()->isIpBanned(clientip, banInfo)) {
		if (banInfo.reason.empty()) {
			banInfo.reason = "(none)";
		}

		std::ostringstream ss;
		ss << "Your IP has been banned until " << formatDateShort(banInfo.expiresAt) << " by " << banInfo.bannedBy << ".\n\nReason specified:\n" << banInfo.reason;
		disconnectClient(0x0A, ss.str().c_str());
		return false;
	}

	uint32_t serverip = serverIPs[0].first;
	for (uint32_t i = 0; i < serverIPs.size(); i++) {
		if ((serverIPs[i].first & serverIPs[i].second) == (clientip & serverIPs[i].second)) {
			serverip = serverIPs[i].first;
			break;
		}
	}

	if (!accountName) {
		disconnectClient(0x0A, "Invalid account id.");
		return false;
	}

	Account account;
	if (!IOLoginData::getInstance()->loginserverAuthentication(accountName, password, account)) {
		disconnectClient(0x0A, "Account id or password is not correct.");
		return false;
	}

	OutputMessage_ptr output = OutputMessagePool::getInstance()->getOutputMessage(this, false);
	if (output) {
		//Update premium days
		g_game.updatePremium(account);

		//Add MOTD
		output->AddByte(0x14);

		std::ostringstream ss;
		ss << g_game.getMotdNum() << "\n" << g_config.getString(ConfigManager::MOTD);
		output->AddString(ss.str());

		//Add char list
		output->AddByte(0x64);
		output->AddByte((uint8_t)account.charList.size());

		for (const std::string& characterName : account.charList) {
			output->AddString(characterName);

			if (g_config.getBoolean(ConfigManager::ON_OR_OFF_CHARLIST)) {
				if (g_game.getPlayerByName(characterName)) {
					output->AddString("Online");
				} else {
					output->AddString("Offline");
				}
			} else {
				output->AddString(g_config.getString(ConfigManager::SERVER_NAME));
			}

			output->AddU32(serverip);
			output->AddU16(g_config.getNumber(ConfigManager::GAME_PORT));
		}

		//Add premium days
		if (g_config.getBoolean(ConfigManager::FREE_PREMIUM)) {
			output->AddU16(0xFFFF);    //client displays free premium
		} else {
			output->AddU16(account.premiumDays);
		}

		OutputMessagePool::getInstance()->send(output);
	}

	getConnection()->closeConnection();
	return true;
}
Exemple #10
0
Element* getConnectedElt(Connector* c, int pos)
{
    Connector* ans = getConnection(c, pos);
    return ans ? ans->master : NULL;
}
Exemple #11
0
SoundConnection *DSPNode::getConnection(const char *snk)
{
	return getConnection( dynamic_cast<DSPNode*>( sceneManager->getNode(snk) ) );
}
void ProtocolLogin::onRecvFirstMessage(NetworkMessage& msg)
{
	if (g_game.getGameState() == GAME_STATE_SHUTDOWN) {
		getConnection()->closeConnection();
		return;
	}

	uint32_t clientip = getConnection()->getIP();

	/*uint16_t clientos = */
	msg.get<uint16_t>();
	uint16_t version = msg.get<uint16_t>();

	if (version >= 971) {
		msg.SkipBytes(17);
	} else {
		msg.SkipBytes(12);
	}

	/*
	 * Skipped bytes:
	 * 4 bytes: protocolVersion (only 971+)
	 * 12 bytes: dat, spr, pic signatures (4 bytes each)
	 * 1 byte: 0 (only 971+)
	 */

#define dispatchDisconnectClient(err) g_dispatcher.addTask(createTask(std::bind(&ProtocolLogin::disconnectClient, this, err)))

	if (version <= 760) {
		dispatchDisconnectClient("Only clients with protocol " CLIENT_VERSION_STR " allowed!");
		return;
	}

	if (!RSA_decrypt(msg)) {
		getConnection()->closeConnection();
		return;
	}

	uint32_t key[4];
	key[0] = msg.get<uint32_t>();
	key[1] = msg.get<uint32_t>();
	key[2] = msg.get<uint32_t>();
	key[3] = msg.get<uint32_t>();
	enableXTEAEncryption();
	setXTEAKey(key);

	std::string accountName = msg.GetString();
	std::string password = msg.GetString();

	if (version < CLIENT_VERSION_MIN || version > CLIENT_VERSION_MAX) {
		dispatchDisconnectClient("Only clients with protocol " CLIENT_VERSION_STR " allowed!");
		return;
	}

	if (g_game.getGameState() == GAME_STATE_STARTUP) {
		dispatchDisconnectClient("Gameworld is starting up. Please wait.");
		return;
	}

	if (g_game.getGameState() == GAME_STATE_MAINTAIN) {
		dispatchDisconnectClient("Gameworld is under maintenance. Please re-connect in a while.");
		return;
	}

	BanInfo banInfo;
	if (IOBan::isIpBanned(clientip, banInfo)) {
		if (banInfo.reason.empty()) {
			banInfo.reason = "(none)";
		}

		std::ostringstream ss;
		ss << "Your IP has been banned until " << formatDateShort(banInfo.expiresAt) << " by " << banInfo.bannedBy << ".\n\nReason specified:\n" << banInfo.reason;
		dispatchDisconnectClient(ss.str());
		return;
	}

	if (accountName.empty()) {
		dispatchDisconnectClient("Invalid account name.");
		return;
	}

#undef dispatchDisconnectClient

	g_dispatcher.addTask(createTask(std::bind(&ProtocolLogin::getCharacterList, this, accountName, password)));
}
/*
 * This function is called when the first EAP_IDENTITY_RESPONSE message
 * was received.
 *
 * Initiates the EPA_TNC session by sending the first EAP_TNC_RESPONSE
 * to the peer. The packet has the Start-Bit set and contains no data.
 *
 *  0		   1		   2		   3
 *  0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 * |      Code     |   Identifier  |	    Length	     |
 * |	       |	       |			       |
 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 * |      Type     |  Flags  | Ver |
 * |	       |0 0 1 0 0|0 0 1|
 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 *
 * For this package, only 'Identifier' has to be set dynamically. Any
 * other information is static.
 */
static int tnc_initiate(void *instance, eap_handler_t *handler)
{
	rlm_eap_tnc_t *inst = instance;
	REQUEST *request = NULL;

	char buff[71];
	ssize_t len = 0;

	TNC_Result result;
	TNC_ConnectionID conn_id;

	TNC_BufferReference eap_tnc_request;
	TNC_BufferReference eap_tnc_user;

	VALUE_PAIR *username;

	/*
	 *	Check if we run inside a secure EAP method.
	 *	FIXME check concrete outer EAP method.
	 */
	if (!handler->request || !handler->request->parent) {
		ERROR("rlm_eap_tnc: EAP_TNC must only be used as an "
		      "inner method within a protected tunneled EAP created "
		      "by an outer EAP method");

		return 0;
	}

	request = handler->request->parent;

	/*
	 *	Build the connection string
	 */
	len = radius_xlat(buff, sizeof(buff), request, inst->connection_string, NULL, NULL);
	if (len < 0){
		return 0;
	}

	RDEBUG("Getting connection from NAA-EAP");

	/*
	 *	Get connection (uses a function from the NAA-EAP-library)
	 */
	result = getConnection(buff, &conn_id);
	if (result != TNC_RESULT_SUCCESS) {
		ERROR("rlm_eap_tnc: NAA-EAP getConnection returned an "
		      "error code");

		return 0;
	}

	/*
	 *	Previous code manually parsed the EAP identity response
	 *	this was wrong. rlm_eap will *always* create the Username
	 *	from the EAP Identity response.
	 *
	 *	Something has gone very wrong if the User-Name doesn't exist.
	 */
	username = pairfind(request->packet->vps, PW_USER_NAME, 0, TAG_ANY);

	RDEBUG("Username for TNC connection: %s", username->vp_strvalue);

	/*
	 *	Stores the username associated with the connection
	 *
	 *	What becomes of username? Who knows... but we don't free it
	 *	so not safe to use talloc.
	 */
	MEM(eap_tnc_user = (TNC_BufferReference) strdup(username->vp_strvalue));

	result = storeUsername(conn_id, eap_tnc_user, username->length);
	if (result != TNC_RESULT_SUCCESS) {
		ERROR("rlm_eap_tnc: NAA-EAP storeUsername returned an "
		      "error code");

		return 0;
	}

	/*
	 *	Set connection ID
	 */
	handler->opaque = talloc(handler, TNC_ConnectionID);
	memcpy(handler->opaque, &conn_id, sizeof(TNC_ConnectionID));

	/*
	 *	Bild first EAP TNC request
	 */

	MEM(eap_tnc_request = talloc_array(handler->eap_ds->request, uint8_t, 1));
	*eap_tnc_request = SET_START(1);

	handler->eap_ds->request->code = PW_EAP_REQUEST;
	handler->eap_ds->request->type.num = PW_EAP_TNC;

	handler->eap_ds->request->type.length = 1;

	talloc_free(handler->eap_ds->request->type.data);
	handler->eap_ds->request->type.data = eap_tnc_request;

	/*
	 *	We don't need to authorize the user at this point.
	 *
	 *	We also don't need to keep the challenge, as it's
	 *	stored in 'handler->eap_ds', which will be given back
	 *	to us...
	 */
	handler->stage = AUTHENTICATE;

	return 1;
}
Exemple #14
0
bool
NIVissimDisturbance::addToNode(NBNode* node, NBDistrictCont& dc,
                               NBNodeCont& nc, NBEdgeCont& ec) {
    myNode = 0;
    NIVissimConnection* pc =
        NIVissimConnection::dictionary(myEdge.getEdgeID());
    NIVissimConnection* bc =
        NIVissimConnection::dictionary(myDisturbance.getEdgeID());
    if (pc == 0 && bc == 0) {
        // This has not been tested completely, yet
        // Both competing abstract edges are normal edges
        // We have to find a crossing point, build a node here,
        //  split both edges and add the connections
        NIVissimEdge* e1 = NIVissimEdge::dictionary(myEdge.getEdgeID());
        NIVissimEdge* e2 = NIVissimEdge::dictionary(myDisturbance.getEdgeID());
        WRITE_WARNING("Ugly split to prohibit '" + toString<int>(e1->getID()) + "' by '" + toString<int>(e2->getID()) + "'.");
        Position pos = e1->crossesEdgeAtPoint(e2);
        std::string id1 = toString<int>(e1->getID()) + "x" + toString<int>(e2->getID());
        std::string id2 = toString<int>(e2->getID()) + "x" + toString<int>(e1->getID());
        NBNode* node1 = nc.retrieve(id1);
        NBNode* node2 = nc.retrieve(id2);
        NBNode* node = 0;
        assert(node1 == 0 || node2 == 0);
        if (node1 == 0 && node2 == 0) {
            refusedProhibits++;
            return false;
            /*            node = new NBNode(id1, pos.x(), pos.y(), "priority");
                        if(!myNodeCont.insert(node)) {
                             "nope, NIVissimDisturbance" << endl;
                            throw 1;
                        }*/
        } else {
            node = node1 == 0 ? node2 : node1;
        }
        ec.splitAt(dc, ec.retrievePossiblySplit(toString<int>(e1->getID()), myEdge.getPosition()), node);
        ec.splitAt(dc, ec.retrievePossiblySplit(toString<int>(e2->getID()), myDisturbance.getPosition()), node);
        // !!! in some cases, one of the edges is not being build because it's too short
        // !!! what to do in these cases?
        NBEdge* mayDriveFrom = ec.retrieve(toString<int>(e1->getID()) + "[0]");
        NBEdge* mayDriveTo = ec.retrieve(toString<int>(e1->getID()) + "[1]");
        NBEdge* mustStopFrom = ec.retrieve(toString<int>(e2->getID()) + "[0]");
        NBEdge* mustStopTo = ec.retrieve(toString<int>(e2->getID()) + "[1]");
        if (mayDriveFrom != 0 && mayDriveTo != 0 && mustStopFrom != 0 && mustStopTo != 0) {
            node->addSortedLinkFoes(
                NBConnection(mayDriveFrom, mayDriveTo),
                NBConnection(mayDriveFrom, mayDriveTo));
        } else {
            refusedProhibits++;
            return false;
            // !!! warning
        }
//        }
    } else if (pc != 0 && bc == 0) {
        // The prohibited abstract edge is a connection, the other
        //  is not;
        // The connection will be prohibitesd by all connections
        //  outgoing from the "real" edge

        NBEdge* e = ec.retrievePossiblySplit(toString<int>(myDisturbance.getEdgeID()), myDisturbance.getPosition());
        if (e == 0) {
            WRITE_WARNING("Could not prohibit '" + toString<int>(myEdge.getEdgeID()) + "' by '" + toString<int>(myDisturbance.getEdgeID()) + "'. Have not found disturbance.");
            refusedProhibits++;
            return false;
        }
        if (e->getFromNode() == e->getToNode()) {
            WRITE_WARNING("Could not prohibit '" + toString<int>(myEdge.getEdgeID()) + "' by '" + toString<int>(myDisturbance.getEdgeID()) + "'. Disturbance connects same node.");
            refusedProhibits++;
            // What to do with self-looping edges?
            return false;
        }
        // get the begin of the prohibited connection
        std::string id_pcoe = toString<int>(pc->getFromEdgeID());
        std::string id_pcie = toString<int>(pc->getToEdgeID());
        NBEdge* pcoe = ec.retrievePossiblySplit(id_pcoe, id_pcie, true);
        NBEdge* pcie = ec.retrievePossiblySplit(id_pcie, id_pcoe, false);
        // check whether it's ending node is the node the prohibited
        //  edge end at
        if (pcoe != 0 && pcie != 0 && pcoe->getToNode() == e->getToNode()) {
            // if so, simply prohibit the connections
            NBNode* node = e->getToNode();
            const EdgeVector& connected = e->getConnectedEdges();
            for (EdgeVector::const_iterator i = connected.begin(); i != connected.end(); i++) {
                node->addSortedLinkFoes(
                    NBConnection(e, *i),
                    NBConnection(pcoe, pcie));
            }
        } else {
            WRITE_WARNING("Would have to split edge '" + e->getID() + "' to build a prohibition");
            refusedProhibits++;
            // quite ugly - why was it not build?
            return false;
            /*
            std::string nid1 = e->getID() + "[0]";
            std::string nid2 = e->getID() + "[1]";

            if(ec.splitAt(e, node)) {
                node->addSortedLinkFoes(
                        NBConnection(
                            ec.retrieve(nid1),
                            ec.retrieve(nid2)
                        ),
                        getConnection(node, myEdge.getEdgeID())
                    );
            }
            */
        }
    } else if (bc != 0 && pc == 0) {
        // The prohibiting abstract edge is a connection, the other
        //  is not;
        // We have to split the other one and add the prohibition
        //  description

        NBEdge* e = ec.retrievePossiblySplit(toString<int>(myEdge.getEdgeID()), myEdge.getPosition());
        if (e == 0) {
            WRITE_WARNING("Could not prohibit '" + toString<int>(myEdge.getEdgeID()) + "' - it was not built.");
            return false;
        }
        std::string nid1 = e->getID() + "[0]";
        std::string nid2 = e->getID() + "[1]";
        if (e->getFromNode() == e->getToNode()) {
            WRITE_WARNING("Could not prohibit '" + toString<int>(myEdge.getEdgeID()) + "' by '" + toString<int>(myDisturbance.getEdgeID()) + "'.");
            refusedProhibits++;
            // What to do with self-looping edges?
            return false;
        }
        // get the begin of the prohibiting connection
        std::string id_bcoe = toString<int>(bc->getFromEdgeID());
        std::string id_bcie = toString<int>(bc->getToEdgeID());
        NBEdge* bcoe = ec.retrievePossiblySplit(id_bcoe, id_bcie, true);
        NBEdge* bcie = ec.retrievePossiblySplit(id_bcie, id_bcoe, false);
        // check whether it's ending node is the node the prohibited
        //  edge end at
        if (bcoe != 0 && bcie != 0 && bcoe->getToNode() == e->getToNode()) {
            // if so, simply prohibit the connections
            NBNode* node = e->getToNode();
            const EdgeVector& connected = e->getConnectedEdges();
            for (EdgeVector::const_iterator i = connected.begin(); i != connected.end(); i++) {
                node->addSortedLinkFoes(
                    NBConnection(bcoe, bcie),
                    NBConnection(e, *i));
            }
        } else {
            WRITE_WARNING("Would have to split edge '" + e->getID() + "' to build a prohibition");
            refusedProhibits++;
            return false;
            /*
            // quite ugly - why was it not build?
            if(ec.splitAt(e, node)) {
                node->addSortedLinkFoes(
                        getConnection(node, myDisturbance.getEdgeID()),
                        NBConnection(
                            ec.retrieve(nid1),
                            ec.retrieve(nid2)
                        )
                    );
            }
            */
        }
    } else {
        // both the prohibiting and the prohibited abstract edges
        //  are connections
        // We can retrieve the conected edges and add the desription
        NBConnection conn1 = getConnection(node, myDisturbance.getEdgeID());
        NBConnection conn2 = getConnection(node, myEdge.getEdgeID());
        if (!conn1.check(ec) || !conn2.check(ec)) {
            refusedProhibits++;
            return false;
        }
        node->addSortedLinkFoes(conn1, conn2);
    }
    return true;
}
Exemple #15
0
void ProtocolGame::sendPing()
{
	uint8_t tmp = NET_PING;
	getConnection()->write(&tmp, 1);
}
void statement::unbufferedFetch()
{
  logMsg("statement::unbufferedFetch() - MySQL_Resultset::*");

  sql::ConnectOptionsMap connection_properties;
  int id=0;

  try
  {

    /*
     This is the first way to do an unbuffered fetch...
     */
    /* url comes from the unit testing framework */
    connection_properties["hostName"]=url;
    /* user comes from the unit testing framework */
    connection_properties["userName"]=user;
    connection_properties["password"]=passwd;

    bool bval= !TestsRunner::getStartOptions()->getBool("dont-use-is");
    connection_properties["metadataUseInfoSchema"]=bval;

    logMsg("... setting TYPE_FORWARD_ONLY through connection map");
    connection_properties.erase("defaultStatementResultType");
    {
      connection_properties["defaultStatementResultType"]=sql::ResultSet::TYPE_FORWARD_ONLY;

      try
      {
        created_objects.clear();
        con.reset(driver->connect(connection_properties));
      }
      catch (sql::SQLException &e)
      {
        fail(e.what(), __FILE__, __LINE__);
      }
      con->setSchema(db);
      stmt.reset(con->createStatement());
      ASSERT_EQUALS(stmt->getResultSetType(), sql::ResultSet::TYPE_FORWARD_ONLY);
      stmt->execute("DROP TABLE IF EXISTS test");

      stmt->execute("CREATE TABLE test(id INT)");
      stmt->execute("INSERT INTO test(id) VALUES (0), (2), (3), (4), (5)");
      ASSERT_EQUALS(5, (int) stmt->getUpdateCount());
      stmt->execute("UPDATE test SET id = 1 WHERE id = 0");
      ASSERT_EQUALS(1, (int) stmt->getUpdateCount());
      stmt->execute("DELETE FROM test WHERE id = 1");
      ASSERT_EQUALS(1, (int) stmt->getUpdateCount());
      stmt->execute("INSERT INTO test(id) VALUES (1)");
      ASSERT_EQUALS(1, (int) stmt->getUpdateCount());

      logMsg("... simple forward reading");
      res.reset(stmt->executeQuery("SELECT id FROM test ORDER BY id ASC"));
      id=0;
      while (res->next())
      {
        id++;
        ASSERT_EQUALS(res->getInt(1), res->getInt("id"));
        ASSERT_EQUALS(id, res->getInt("id"));
      }
      checkUnbufferedScrolling();

      logMsg("... simple forward reading again");
      res.reset(stmt->executeQuery("SELECT id FROM test ORDER BY id DESC"));
      try
      {
        res->beforeFirst();
        FAIL("Nonscrollable result set not detected");
      }
      catch (sql::SQLException &)
      {
      }
      id=5;
      while (res->next())
      {
        ASSERT_EQUALS(res->getInt(1), res->getInt("id"));
        ASSERT_EQUALS(id, res->getInt("id"));
        id--;
      }
    }
    connection_properties.erase("defaultStatementResultType");


    logMsg("... setting TYPE_FORWARD_ONLY through setClientOption()");
    try
    {
      created_objects.clear();
      con.reset(getConnection());
    }
    catch (sql::SQLException &e)
    {
      fail(e.what(), __FILE__, __LINE__);
    }
    int option=sql::ResultSet::TYPE_FORWARD_ONLY;
    con->setSchema(db);
    con->setClientOption("defaultStatementResultType", (static_cast<void *> (&option)));
    stmt.reset(con->createStatement());

    logMsg("... simple forward reading");
    res.reset(stmt->executeQuery("SELECT id FROM test ORDER BY id ASC"));
    id=0;
    while (res->next())
    {
      id++;
      ASSERT_EQUALS(res->getInt(1), res->getInt("id"));
      ASSERT_EQUALS(id, res->getInt("id"));
    }
    checkUnbufferedScrolling();
    logMsg("... simple forward reading again");
    res.reset(stmt->executeQuery("SELECT id FROM test ORDER BY id DESC"));
    try
    {
      res->beforeFirst();
      FAIL("Nonscrollable result set not detected");
    }
    catch (sql::SQLException &)
    {
    }
    id=5;
    while (res->next())
    {
      ASSERT_EQUALS(res->getInt(1), res->getInt("id"));
      ASSERT_EQUALS(id, res->getInt("id"));
      id--;
    }

    logMsg("... setting TYPE_FORWARD_ONLY pointer magic");
    try
    {
      created_objects.clear();
      con.reset(getConnection());
    }
    catch (sql::SQLException &e)
    {
      fail(e.what(), __FILE__, __LINE__);
    }
    con->setSchema(db);
    stmt.reset(con->createStatement());
    res.reset((stmt->setResultSetType(sql::ResultSet::TYPE_FORWARD_ONLY)->executeQuery("SELECT id FROM test ORDER BY id ASC")));
    logMsg("... simple forward reading");

    id=0;
    while (res->next())
    {
      id++;
      ASSERT_EQUALS(res->getInt(1), res->getInt("id"));
      ASSERT_EQUALS(id, res->getInt("id"));
    }
    checkUnbufferedScrolling();

    logMsg("... simple forward reading again");
    res.reset((stmt->setResultSetType(sql::ResultSet::TYPE_FORWARD_ONLY)->executeQuery("SELECT id FROM test ORDER BY id DESC")));
    ASSERT_EQUALS(stmt->getResultSetType(), sql::ResultSet::TYPE_FORWARD_ONLY);
    try
    {
      res->beforeFirst();
      FAIL("Nonscrollable result set not detected");
    }
    catch (sql::SQLException &)
    {
    }
    id=5;
    while (res->next())
    {
      ASSERT_EQUALS(res->getInt(1), res->getInt("id"));
      ASSERT_EQUALS(id, res->getInt("id"));
      id--;
    }

    stmt->execute("DROP TABLE IF EXISTS test");

  }
  catch (sql::SQLException &e)
  {
    logErr(e.what());
    logErr("SQLState: " + std::string(e.getSQLState()));
    fail(e.what(), __FILE__, __LINE__);
  }
}
Exemple #17
0
bool ProtocolLogin::parseFirstPacket(NetworkMessage& msg)
{
	if(g_game.getGameState() == GAME_STATE_SHUTDOWN){
		getConnection()->closeConnection();
		return false;
	}

	uint32_t clientip = getConnection()->getIP();

	/*uint16_t clientos =*/ msg.GetU16();
	uint16_t version  = msg.GetU16();
	msg.SkipBytes(12);

	if(version <= 760){
		disconnectClient(0x0A, "This server requires client version " CLIENT_VERSION_STRING ".");
	}

	if(!RSA_decrypt(msg)){
		getConnection()->closeConnection();
		return false;
	}

	uint32_t key[4];
	key[0] = msg.GetU32();
	key[1] = msg.GetU32();
	key[2] = msg.GetU32();
	key[3] = msg.GetU32();
	enableXTEAEncryption();
	setXTEAKey(key);

	std::string accname = msg.GetString();
	std::string password = msg.GetString();

	if(!accname.length()){
		//Tibia sends this message if the account name length is < 5
		//We will send it only if account name is BLANK
		disconnectClient(0x0A, "Invalid Account Name.");
		return false;
	}

	if(version < CLIENT_VERSION_MIN || version > CLIENT_VERSION_MAX){
		disconnectClient(0x0A, "This server requires client version " CLIENT_VERSION_STRING ".");
		return false;
	}

	if(g_game.getGameState() == GAME_STATE_STARTUP){
		disconnectClient(0x0A, "Gameworld is starting up. Please wait.");
		return false;
	}

	if(g_bans.isIpDisabled(clientip)){
		disconnectClient(0x0A, "Too many connections attempts from this IP. Try again later.");
		return false;
	}

	if(g_bans.isIpBanished(clientip)){
		disconnectClient(0x0A, "Your IP is banished!");
		return false;
	}
	/*
	uint32_t serverip = serverIPs[0].first;
	for(uint32_t i = 0; i < serverIPs.size(); i++){
		if((serverIPs[i].first & serverIPs[i].second) == (clientip & serverIPs[i].second)){
			serverip = serverIPs[i].first;
			break;
		}
	}
	*/

	Account account = IOAccount::instance()->loadAccount(accname);
	if(!(asLowerCaseString(account.name) == asLowerCaseString(accname) &&
			passwordTest(password, account.password))){

		g_bans.addLoginAttempt(clientip, false);
		disconnectClient(0x0A, "Account name or password is not correct.");
		return false;
	}

	g_bans.addLoginAttempt(clientip, true);


	OutputMessage_ptr output = OutputMessagePool::getInstance()->getOutputMessage(this, false);
	if(output){
		TRACK_MESSAGE(output);
		//Add MOTD
		std::stringstream motd;
		output->AddByte(0x14);
		motd << g_config.getNumber(ConfigManager::MOTD_NUM) << "\n";
		motd << g_config.getString(ConfigManager::MOTD);
		output->AddString(motd.str());
		//Add char list
		output->AddByte(0x64);
		output->AddByte((uint8_t)account.charList.size());
		std::list<AccountCharacter>::iterator it;
		for(it = account.charList.begin(); it != account.charList.end(); it++){
			const AccountCharacter& character = *it;
			output->AddString(character.name);
			output->AddString(character.world_name);
			output->AddU32(character.ip);
			output->AddU16(character.port);
		}
		
		output->AddU16(IOAccount::getPremiumDaysLeft(account.premiumEnd));

		OutputMessagePool::getInstance()->send(output);
	}
	getConnection()->closeConnection();

	return true;
}
void EspGuaControlConnection::actOnSystemMessage(
       short                  messageNum,
       IpcMessageBufferPtr    sysMsg,
       IpcMessageObjSize      sysMsgLen,
       short                  clientFileNumber,
       const GuaProcessHandle &clientPhandle,
       GuaConnectionToClient  *connection)
{
  switch (messageNum)
    {
    case ZSYS_VAL_SMSG_OPEN:
      if (initialized_)
	{
	  // This an OPEN message for a connection that isn't the
	  // initial control connection. Create a new message stream and
	  // attach it to the newly created connection.
	  EspNewIncomingConnectionStream *newStream = new(getEnv()->getHeap())
	    EspNewIncomingConnectionStream(getEnv(),espFragInstanceDir_);

	  ex_assert(connection != NULL,
                    "Must create connection for open sys msg");
	  newStream->addRecipient(connection);
          newStream->receive(FALSE);

	  // now abandon the new object, it will find its way to the right
	  // send bottom TCB on its own
	  // (a memory leak would result if the client would open our $RECEIVE
	  // w/o sending corresponding ESP level open requests)
	}
      break;

    case ZSYS_VAL_SMSG_CPUDOWN:
    case ZSYS_VAL_SMSG_REMOTECPUDOWN:
    case ZSYS_VAL_SMSG_CLOSE:
    case ZSYS_VAL_SMSG_NODEDOWN:
      // Somebody closed us or went down. Was it master executor?
      // Note that GuaReceiveControlConnection::getConnection returns
      // the master executor connection.
      if (getConnection() == connection)
      {
        // Master is gone, stop this process and let the OS cleanup.
        if (getEnv()->getLogEspGotCloseMsg())
        {
          // LCOV_EXCL_START
          /*
          Coverage notes: to test this code in a dev regression requires
          changing $MY_SQROOT/etc/ms.env, so I made a manual test on
          May 11, 2012 to verify this code.
          */
          char myName[20];
          memset(myName, '\0', sizeof(myName));
          getEnv()->getMyOwnProcessId(IPC_DOM_GUA_PHANDLE).toAscii(
                                                    myName, sizeof(myName));
          char buf[500];
          char *sysMsgName = NULL;
          switch (messageNum)
          {
          // LCOV_EXCL_STOP
          case ZSYS_VAL_SMSG_CPUDOWN:
            sysMsgName = (char *) "CPUDOWN";
            break;
          case ZSYS_VAL_SMSG_REMOTECPUDOWN:
            sysMsgName = (char *) "REMOTECPUDOWN";
            break;
          // LCOV_EXCL_START
          case ZSYS_VAL_SMSG_CLOSE:
            sysMsgName = (char *) "CLOSE";
            break;
          case ZSYS_VAL_SMSG_NODEDOWN:
            sysMsgName = (char *) "NODEDOWN";
            break;
          }
          str_sprintf(buf, 
                      "System %s message causes %s to exit.",
                            sysMsgName, myName);
          SQLMXLoggingArea::logExecRtInfo(__FILE__, 
                                          __LINE__, buf, 0);
          // LCOV_EXCL_STOP
        }
        getEnv()->stopIpcEnvironment();
      }
      // Otherwise, do a search thru all
      // downloaded fragment entries and check whether their
      // client is still using them. The IPC layer will wake
      // up the scheduler so the actual release can take place.
      espFragInstanceDir_->releaseOrphanEntries();
      break;

    default:
      // do nothing for all other kinds of system messages
      break;
    } // switch


  // The parent class already handles the job of closing all connections
  // who lost their client process by failed processes, failed CPUs and
  // failed systems or networks. Check here that we die if all our
  // requestors go away, but don't die if the first system message is
  // something other than an OPEN message.
  if (getNumRequestors() == 0 AND initialized_)
    {
      // ABORT("Lost connection to client");
      // losing the client is not a reason to panic, the client may
      // have voluntarily decided to exit without freeing its resources
      NAExit(0);
    }
  else if (NOT initialized_ AND getNumRequestors() > 0)
    {
      // the first requestor came in
      initialized_ = TRUE;
    }
}
bool ConnectionManager::mousePressEvent(QMouseEvent *event) {
	if (event->button() == Qt::RightButton) {
		if (m_fromPin != -1) {
			m_fromPin = -1;
			m_points.clear();
			return true;
		}

		int point;
		Connection *c = getPoint(NORM(event->x()), NORM(event->y()), point);
		if (point != -1) {
			// User can't remove first or last point like that
			if (point == 0 || point == c->points.size() - 1) {
				return false;
			}
			QList<QAction *> actions;
			actions.append(new QAction("Remove point", 0));
			QAction *action = QMenu::exec(actions, event->globalPos(), 0, 0);
			if (action) {
				removePoint(c, point);
			}
			return true;
		}

		c = getConnection(NORM(event->x()), NORM(event->y()), point);
		if (c) {
			QList<QAction *> actions;
			actions.append(new QAction("Remove connection", 0));
			QAction *action = QMenu::exec(actions, event->globalPos(), 0, 0);
			if (action) {
				removeConnection(c);
			}
			return true;
		}
	}
	else if (event->button() == Qt::LeftButton) {
		if (m_fromPin != -1) {
			QPoint from = QPoint(m_movingX, m_movingY);
			QPoint to(NORM(event->pos().x()), NORM(event->pos().y()));
			ScreenObject *object = m_screen->getObject(NORM(event->x()), NORM(event->y()));
			if (object) {
				int pin = m_screen->getPin(object, NORM(event->x()), NORM(event->y()));
				if (pin != -1) {
					to = object->getPins()[pin].rect.center();
				}
			}

			bool firstPoints = m_points.empty();

			if (firstPoints) {
				m_points.push_back(from);
			}

			if (m_screen->getObject(from.x(), to.y()) == m_fromObject/* &&
				m_screen->getPin(m_moving, from.x(), to.y()) != -1*/) {
				m_points.push_back(QPoint(to.x(), from.y()));
			}
			else {
				m_points.push_back(QPoint(from.x(), to.y()));
			}

// 			if (!firstPoints) {
				m_points.push_back(to);
// 			}

			int point;
			Connection *c = getPoint(NORM(event->x()), NORM(event->y()), point);
			if (point != -1) {
                ScreenObject *object = m_screen->getObject(NORM(event->x()), NORM(event->y()));
                if (object) {
                    m_points.erase(m_points.end() - 1);
                    m_points.erase(m_points.end() - 1);
                    return false;
                }

				addConnectionNode(c, point, event->x(), event->y(), m_points);

				m_fromPin = -1;
				m_points.clear();
// 				qDebug() << newPoints.size() << c->points.size() << "\n";
				return true;
			}
			else {
				QPointF intersectPnt;
				int point;
				c = getConnection(NORM(event->x()), NORM(event->y()), point, &intersectPnt);
				if (c) {
					QPoint p = intersectPnt.toPoint();
					p = QPoint(NORM(p.x()), NORM(p.y()));
					c->points.insert(c->points.begin() + point, p);
					addConnectionNode(c, point, event->x(), event->y(), m_points);
					m_fromPin = -1;
					m_points.clear();
					return true;
				}
			}

			if (object) {
				int pin = m_screen->getPin(object, NORM(event->x()), NORM(event->y()));
				if (pin != -1) {
					addConnection(m_fromObject, m_fromPin, object, pin, m_points);
					m_fromPin = -1;
					m_points.clear();
					return true;
				}
			}

			m_movingX = NORM(event->x());
			m_movingY = NORM(event->y());
			return true;
		}

// 		qDebug() << NORM(event->x()) << NORM(event->y());
		int point;
		Connection *c = getPoint(NORM(event->x()), NORM(event->y()), point);
		if (point != -1) {
			if (point == 0) {
				m_fromObject = c->from;
			}
			else if (point == c->points.size() - 1) {
				m_fromObject = c->to;
			}
			else {
				m_fromObject = 0;
			}
			m_movingConn = c;
			m_moving = &c->points[point];
			m_movingX = NORM(event->x());
			m_movingY = NORM(event->y());
			return true;
		}

		ScreenObject *object = m_screen->getObject(NORM(event->x()), NORM(event->y()));
		if (!object) {
			return false;
		}

		m_fromPin = m_screen->getPin(object, NORM(event->x()), NORM(event->y()));
		if (m_fromPin != -1) {
			m_fromObject = object;
			m_movingX = object->getPins()[m_fromPin].rect.center().x();
			m_movingY = object->getPins()[m_fromPin].rect.center().y();
			return true;
		}
	}
	return false;
}
Exemple #20
0
SEXP attribute_hidden do_cat(SEXP call, SEXP op, SEXP args, SEXP rho)
{
    cat_info ci;
    RCNTXT cntxt;
    SEXP objs, file, fill, sepr, labs, s;
    int ifile;
    Rconnection con;
    int append;
    int i, iobj, n, nobjs, pwidth, width, sepw, lablen, ntot, nlsep, nlines;
    char buf[512];
    const char *p = "";

    checkArity(op, args);

    /* Use standard printing defaults */
    PrintDefaults();

    objs = CAR(args);
    args = CDR(args);

    file = CAR(args);
    ifile = asInteger(file);
    con = getConnection(ifile);
    if(!con->canwrite) /* if it is not open, we may not know yet */
	error(_("cannot write to this connection"));
    args = CDR(args);

    sepr = CAR(args);
    if (!isString(sepr))
	error(_("invalid '%s' specification"), "sep");
    nlsep = 0;
    for (i = 0; i < LENGTH(sepr); i++)
	if (strstr(CHAR(STRING_ELT(sepr, i)), "\n")) nlsep = 1; /* ASCII */
    args = CDR(args);

    fill = CAR(args);
    if ((!isNumeric(fill) && !isLogical(fill)) || (length(fill) != 1))
	error(_("invalid '%s' argument"), "fill");
    if (isLogical(fill)) {
	if (asLogical(fill) == 1)
	    pwidth = R_print.width;
	else
	    pwidth = INT_MAX;
    }
    else pwidth = asInteger(fill);
    if(pwidth <= 0) {
	warning(_("non-positive 'fill' argument will be ignored"));
	pwidth = INT_MAX;
    }
    args = CDR(args);

    labs = CAR(args);
    if (!isString(labs) && labs != R_NilValue)
	error(_("invalid '%s' argument"), "labels");
    lablen = length(labs);
    args = CDR(args);

    append = asLogical(CAR(args));
    if (append == NA_LOGICAL)
	error(_("invalid '%s' specification"), "append");

    ci.wasopen = con->isopen;

    ci.changedcon = switch_stdout(ifile, 0);
    /* will open new connection if required, and check for writeable */
#ifdef Win32
    /* do this after re-sinking output */
    WinCheckUTF8();
#endif

    ci.con = con;

    /* set up a context which will close the connection if there is an error */
    begincontext(&cntxt, CTXT_CCODE, R_NilValue, R_BaseEnv, R_BaseEnv,
		 R_NilValue, R_NilValue);
    cntxt.cend = &cat_cleanup;
    cntxt.cenddata = &ci;

    nobjs = length(objs);
    width = 0;
    ntot = 0;
    nlines = 0;
    for (iobj = 0; iobj < nobjs; iobj++) {
	s = VECTOR_ELT(objs, iobj);
	if (iobj != 0 && !isNull(s))
	    cat_printsep(sepr, ntot++);
	n = length(s);
	/* 0-length objects are ignored */
	if (n > 0) {
	    if (labs != R_NilValue && (iobj == 0)
		&& (asInteger(fill) > 0)) {
		Rprintf("%s ", trChar(STRING_ELT(labs, nlines % lablen)));
		/* FIXME -- Rstrlen allows for double-width chars */
		width += Rstrlen(STRING_ELT(labs, nlines % lablen), 0) + 1;
		nlines++;
	    }
	    if (isString(s))
		p = trChar(STRING_ELT(s, 0));
	    else if (isSymbol(s)) /* length 1 */
		p = CHAR(PRINTNAME(s));
	    else if (isVectorAtomic(s)) {
		/* Not a string, as that is covered above.
		   Thus the maximum size is about 60.
		   The copy is needed as cat_newline might reuse the buffer.
		   Use strncpy is in case these assumptions change.
		*/
		p = EncodeElement0(s, 0, 0, OutDec);
		strncpy(buf, p, 512); buf[511] = '\0';
		p = buf;
	    }
#ifdef fixed_cat
	    else if (isVectorList(s)) {
	      /* FIXME:	 call EncodeElement() for every element of  s.

		 Real Problem: `s' can be large;
		 should do line breaking etc.. (buf is of limited size)
	      */
	    }
#endif
	    else
		errorcall(call,
			  _("argument %d (type '%s') cannot be handled by 'cat'"),
			  1+iobj, type2char(TYPEOF(s)));
	    /* FIXME : cat(...) should handle ANYTHING */
	    size_t w = strlen(p);
	    cat_sepwidth(sepr, &sepw, ntot);
	    if ((iobj > 0) && (width + w + sepw > pwidth)) {
		cat_newline(labs, &width, lablen, nlines);
		nlines++;
	    }
	    for (i = 0; i < n; i++, ntot++) {
		Rprintf("%s", p);
		width += (int)(w + sepw);
		if (i < (n - 1)) {
		    cat_printsep(sepr, ntot);
		    if (isString(s))
			p = trChar(STRING_ELT(s, i+1));
		    else {
			p = EncodeElement0(s, i+1, 0, OutDec);
			strncpy(buf, p, 512); buf[511] = '\0';
			p = buf;
		    }
		    w = (int) strlen(p);
		    cat_sepwidth(sepr, &sepw, ntot);
		    /* This is inconsistent with the version above.
		       As from R 2.3.0, fill <= 0 is ignored. */
		    if ((width + w + sepw > pwidth) && pwidth) {
			cat_newline(labs, &width, lablen, nlines);
			nlines++;
		    }
		} else ntot--; /* we don't print sep after last, so don't advance */
	    }
	}
    }
    if ((pwidth != INT_MAX) || nlsep)
	Rprintf("\n");

    /* end the context after anything that could raise an error but before
       doing the cleanup so the cleanup doesn't get done twice */
    endcontext(&cntxt);

    cat_cleanup(&ci);

    return R_NilValue;
}
Exemple #21
0
int fetch_list_data(char *username, struct listdata **list) {
	char *query;
	struct listdata *result;
	int col_mesgid = 0;
	int col_size = 1;
	sqlite3_stmt *stmt;
	int retval;
	sqlite3 *handle;
	int rowCount = 0;
	int stat_details = 0;
	int stat_sizesum = 0;

	generateListQuery(username, &query);
	getConnection(DBNAME, &handle);
	rowCount = getQueryCount(handle, query);

	result = (struct listdata *) malloc (sizeof (struct listdata *) * (rowCount + 1));
	if (result == NULL) {
		perror("ERROR: Cannot allocate memory");
		freeConnection(handle);
		return(-1);
	}

	if (rowCount > 0) {
		int rCounter = 0;
		retval = sqlite3_prepare_v2(handle, query, -1, &stmt, 0);
		if (retval) {
			printf("Selecting data from DB Failed\n");
			freeConnection(handle);
			return -1;
		}

		rCounter++;

		// Read the number of rows fetched
		// int cols = sqlite3_column_count(stmt);
		while(1)
		{
			// fetch a row's status
			retval = sqlite3_step(stmt);

			if(retval == SQLITE_ROW)
			{
				// SQLITE_ROW means fetched a row
				result[rCounter].count = rCounter;
				result[rCounter].mesgid = sqlite3_column_int(stmt,col_mesgid);
				result[rCounter].mesgsize = sqlite3_column_int(stmt,col_size);
				stat_sizesum += result[rCounter].mesgsize;
				rCounter++;
			}
			else if(retval == SQLITE_DONE)
			{
				break;
			}
			else
			{
				// Some error encountered
				printf("Some error encountered\n");
				freeConnection(handle);
				return -1;
			}
		}
		sqlite3_finalize(stmt);
	}

	//SET STAT DETAILS
	result[stat_details].count = stat_details;
	result[stat_details].mesgid = rowCount;
	result[stat_details].mesgsize = stat_sizesum;


	*list = result;

	free(query);
	freeConnection(handle);

	return(rowCount);
}
Exemple #22
0
void ProtocolAdmin::parsePacket(NetworkMessage& msg)
{
	if(g_game.getGameState() == GAME_STATE_SHUTDOWN)
	{
		getConnection()->closeConnection();
		return;
	}

	uint8_t recvbyte = msg.GetByte();

	OutputMessagePool* outputPool = OutputMessagePool::getInstance();

	OutputMessage_ptr output = outputPool->getOutputMessage(this, false);
	if(output)
	{
		TRACK_MESSAGE(output);

		switch(m_state)
		{
			case ENCRYPTION_NO_SET:
			{
				if(g_adminConfig->requireEncryption())
				{
					if((time(NULL) - m_startTime) > 30000)
					{
						getConnection()->closeConnection();
						addLogLine(this, LOGTYPE_WARNING, 1, "encryption timeout");
						return;
					}

					if(recvbyte != AP_MSG_ENCRYPTION && recvbyte != AP_MSG_KEY_EXCHANGE)
					{
						output->AddByte(AP_MSG_ERROR);
						output->AddString("encryption needed");
						outputPool->send(output);
						getConnection()->closeConnection();
						addLogLine(this, LOGTYPE_WARNING, 1, "wrong command while ENCRYPTION_NO_SET");
						return;
					}
					break;
				}
				else
					m_state = NO_LOGGED_IN;
			}

			case NO_LOGGED_IN:
			{
				if(g_adminConfig->requireLogin())
				{
					if((time(NULL) - m_startTime) > 30000)
					{
						//login timeout
						getConnection()->closeConnection();
						addLogLine(this, LOGTYPE_WARNING, 1, "login timeout");
						return;
					}

					if(m_loginTries > 3)
					{
						output->AddByte(AP_MSG_ERROR);
						output->AddString("too many login tries");
						outputPool->send(output);
						getConnection()->closeConnection();
						addLogLine(this, LOGTYPE_WARNING, 1, "too many login tries");
						return;
					}

					if(recvbyte != AP_MSG_LOGIN)
					{
						output->AddByte(AP_MSG_ERROR);
						output->AddString("you are not logged in");
						outputPool->send(output);
						getConnection()->closeConnection();
						addLogLine(this, LOGTYPE_WARNING, 1, "wrong command while NO_LOGGED_IN");
						return;
					}
					break;
				}
				else
					m_state = LOGGED_IN;
			}

			case LOGGED_IN:
			{
				//can execute commands
				break;
			}

			default:
				getConnection()->closeConnection();
				return;
		}

		m_lastCommand = time(NULL);

		switch(recvbyte)
		{
			case AP_MSG_LOGIN:
			{
				if(m_state == NO_LOGGED_IN && g_adminConfig->requireLogin())
				{
					std::string password = msg.GetString();
					if(g_adminConfig->passwordMatch(password))
					{
						m_state = LOGGED_IN;
						output->AddByte(AP_MSG_LOGIN_OK);
						addLogLine(this, LOGTYPE_EVENT, 1, "login ok");
					}
					else
					{
						m_loginTries++;
						output->AddByte(AP_MSG_LOGIN_FAILED);
						output->AddString("wrong password");
						addLogLine(this, LOGTYPE_WARNING, 1, "login failed.("+ password + ")");
					}
				}
				else
				{
					output->AddByte(AP_MSG_LOGIN_FAILED);
					output->AddString("can not login");
					addLogLine(this, LOGTYPE_WARNING, 1, "wrong state at login");
				}
				break;
			}

			case AP_MSG_ENCRYPTION:
			{
				if(m_state == ENCRYPTION_NO_SET && g_adminConfig->requireEncryption())
				{
					uint8_t keyType = msg.GetByte();
					switch(keyType)
					{
						case ENCRYPTION_RSA1024XTEA:
						{
							RSA* rsa = g_adminConfig->getRSAKey(ENCRYPTION_RSA1024XTEA);
							if(!rsa)
							{
								output->AddByte(AP_MSG_ENCRYPTION_FAILED);
								addLogLine(this, LOGTYPE_WARNING, 1, "no valid server key type");
								break;
							}

							if(RSA_decrypt(rsa, msg))
							{
								m_state = NO_LOGGED_IN;
								uint32_t k[4];
								k[0] = msg.GetU32();
								k[1] = msg.GetU32();
								k[2] = msg.GetU32();
								k[3] = msg.GetU32();

								//use for in/out the new key we have
								enableXTEAEncryption();
								setXTEAKey(k);

								output->AddByte(AP_MSG_ENCRYPTION_OK);
								addLogLine(this, LOGTYPE_EVENT, 1, "encryption ok");
							}
							else
							{
								output->AddByte(AP_MSG_ENCRYPTION_FAILED);
								output->AddString("wrong encrypted packet");
								addLogLine(this, LOGTYPE_WARNING, 1, "wrong encrypted packet");
							}
							break;
						}

						default:
							output->AddByte(AP_MSG_ENCRYPTION_FAILED);
							output->AddString("no valid key type");
							addLogLine(this, LOGTYPE_WARNING, 1, "no valid client key type");
							break;
					}
				}
				else
				{
					output->AddByte(AP_MSG_ENCRYPTION_FAILED);
					output->AddString("can not set encryption");
					addLogLine(this, LOGTYPE_EVENT, 1, "can not set encryption");
				}
				break;
			}

			case AP_MSG_KEY_EXCHANGE:
			{
				if(m_state == ENCRYPTION_NO_SET && g_adminConfig->requireEncryption())
				{
					uint8_t keyType = msg.GetByte();
					switch(keyType)
					{
						case ENCRYPTION_RSA1024XTEA:
						{
							RSA* rsa = g_adminConfig->getRSAKey(ENCRYPTION_RSA1024XTEA);
							if(!rsa)
							{
								output->AddByte(AP_MSG_KEY_EXCHANGE_FAILED);
								addLogLine(this, LOGTYPE_WARNING, 1, "no valid server key type");
								break;
							}

							output->AddByte(AP_MSG_KEY_EXCHANGE_OK);
							output->AddByte(ENCRYPTION_RSA1024XTEA);
							char RSAPublicKey[128];
							rsa->getPublicKey(RSAPublicKey);
							output->AddBytes(RSAPublicKey, 128);
							break;
						}

						default:
							output->AddByte(AP_MSG_KEY_EXCHANGE_FAILED);
							addLogLine(this, LOGTYPE_WARNING, 1, "no valid client key type");
							break;
					}
				}
				else
				{
					output->AddByte(AP_MSG_KEY_EXCHANGE_FAILED);
					output->AddString("can not get public key");
					addLogLine(this, LOGTYPE_WARNING, 1, "can not get public key");
				}
				break;
			}

			case AP_MSG_COMMAND:
			{
				if(m_state != LOGGED_IN)
				{
					addLogLine(this, LOGTYPE_ERROR, 1, "recvbyte == AP_MSG_COMMAND && m_state != LOGGED_IN !!!");
					//never should reach this point!!
					break;
				}

				uint8_t command = msg.GetByte();
				switch(command)
				{
					case CMD_BROADCAST:
					{
						const std::string message = msg.GetString();
						addLogLine(this, LOGTYPE_EVENT, 1, "broadcast: " + message);
						g_dispatcher.addTask(createTask(boost::bind(&Game::broadcastMessage, &g_game, message, MSG_STATUS_WARNING)));
						output->AddByte(AP_MSG_COMMAND_OK);
						break;
					}

					case CMD_CLOSE_SERVER:
					{
						g_dispatcher.addTask(createTask(boost::bind(&ProtocolAdmin::adminCommandCloseServer, this)));
						break;
					}

					case CMD_PAY_HOUSES:
					{
						g_dispatcher.addTask(createTask(boost::bind(&ProtocolAdmin::adminCommandPayHouses, this)));
						break;
					}

					case CMD_OPEN_SERVER:
					{
						g_dispatcher.addTask(createTask(boost::bind(&ProtocolAdmin::adminCommandOpenServer, this)));
						break;
					}

					case CMD_SHUTDOWN_SERVER:
					{
						g_dispatcher.addTask(createTask(boost::bind(&ProtocolAdmin::adminCommandShutdownServer, this)));
						getConnection()->closeConnection();
						return;
					}

					case CMD_KICK:
					{
						const std::string name = msg.GetString();
						g_dispatcher.addTask(createTask(boost::bind(&ProtocolAdmin::adminCommandKickPlayer, this, name)));
						break;
					}

					case CMD_SETOWNER:
					{
						const std::string param = msg.GetString();
						g_dispatcher.addTask(createTask(boost::bind(&ProtocolAdmin::adminCommandSetOwner, this, param)));
						break;
					}

					default:
					{
						output->AddByte(AP_MSG_COMMAND_FAILED);
						output->AddString("not known server command");
						addLogLine(this, LOGTYPE_WARNING, 1, "not known server command");
					}
				}
				break;
			}

			case AP_MSG_PING:
				output->AddByte(AP_MSG_PING_OK);
				break;

			default:
				output->AddByte(AP_MSG_ERROR);
				output->AddString("not known command byte");
				addLogLine(this, LOGTYPE_WARNING, 1, "not known command byte");
				break;
		}

		if(output->getMessageLength() > 0)
			outputPool->send(output);
	}
}
Exemple #23
0
int fetch_user_data(char *username, char *password, struct userdata **user) {
	char *query;
	struct userdata *result;
	int col_username = 0;
	int col_password = 1;
	sqlite3_stmt *stmt;
	int retval;
	sqlite3 *handle;
	int rowCount = 0;

	getConnection(DBNAME, &handle);

	generateUserQuery(username, password, &query);
	rowCount = getQueryCount(handle, query);
	if (rowCount > 0) {
		int rCounter = 0;
		retval = sqlite3_prepare_v2(handle, query, -1, &stmt, 0);
		if (retval) {
			printf("Selecting data from DB Failed\n");
			freeConnection(handle);
			return -1;
		}

		result = (struct userdata *) malloc (sizeof (struct userdata *) * rowCount);
		if (result == NULL) {
			perror("ERROR: Cannot allocate memory");
			freeConnection(handle);
			return(-1);
		}

		// Read the number of rows fetched
		// int cols = sqlite3_column_count(stmt);
		while(1)
		{
			// fetch a row's status
			retval = sqlite3_step(stmt);

			if(retval == SQLITE_ROW)
			{
				// SQLITE_ROW means fetched a row
				strcpy(result[rCounter].username,(const char*)sqlite3_column_text(stmt,col_username));
				strcpy(result[rCounter].password,(const char*)sqlite3_column_text(stmt,col_password));
				rCounter++;
			}
			else if(retval == SQLITE_DONE)
			{
				break;
			}
			else
			{
				// Some error encountered
				printf("Some error encountered\n");
				freeConnection(handle);
				return -1;
			}
		}
		sqlite3_finalize(stmt);
		*user = result;
	}

	free(query);
	freeConnection(handle);

	return(rowCount);
}
Exemple #24
0
void ProtocolLogin::onRecvFirstMessage(NetworkMessage& msg)
{
	if(
#if defined(WINDOWS) && !defined(_CONSOLE)
		!GUI::getInstance()->m_connections ||
#endif
		g_game.getGameState() == GAMESTATE_SHUTDOWN)
	{
		getConnection()->close();
		return;
	}

	uint32_t clientIp = getConnection()->getIP();
	msg.get<uint16_t>();
	uint16_t version = msg.get<uint16_t>();

	msg.skip(12);
	#ifdef _MULTIPLATFORM77
	if(!RSA_decrypt(msg))
	{
		getConnection()->close();
		return;
	}

	uint32_t key[4] = {msg.get<uint32_t>(), msg.get<uint32_t>(), msg.get<uint32_t>(), msg.get<uint32_t>()};
	enableXTEAEncryption();
	setXTEAKey(key);
	#endif
	uint32_t name = msg.get<uint32_t>();
	std::string password = msg.getString();

	if(!name)
	{
		name = 10;
	}

	if(!g_config.getBool(ConfigManager::MANUAL_ADVANCED_CONFIG))
	{
		if(version < CLIENT_VERSION_MIN || version > CLIENT_VERSION_MAX)
		{
			disconnectClient(0x0A, CLIENT_VERSION_STRING);
			return;
		}
	else
		if(version < g_config.getNumber(ConfigManager::VERSION_MIN) || version > g_config.getNumber(ConfigManager::VERSION_MAX))
		{
			disconnectClient(0x0A, g_config.getString(ConfigManager::VERSION_MSG).c_str());
			return;
		}
	}
#ifdef CLIENT_VERSION_DATA

	if(sprSignature != CLIENT_VERSION_SPR)
	{
		disconnectClient(0x0A, CLIENT_VERSION_DATA);
		return;
	}

	if(datSignature != CLIENT_VERSION_DAT)
	{
		disconnectClient(0x0A, CLIENT_VERSION_DATA);
		return;
	}

	if(picSignature != CLIENT_VERSION_PIC)
	{
		disconnectClient(0x0A, CLIENT_VERSION_DATA);
		return;
	}
#endif

	if(g_game.getGameState() < GAMESTATE_NORMAL)
	{
		disconnectClient(0x0A, "Server is just starting up, please wait.");
		return;
	}

	if(g_game.getGameState() == GAMESTATE_MAINTAIN)
	{
		disconnectClient(0x0A, "Server is under maintenance, please re-connect in a while.");
		return;
	}

	if(ConnectionManager::getInstance()->isDisabled(clientIp, protocolId))
	{
		disconnectClient(0x0A, "Too many connections attempts from your IP address, please try again later.");
		return;
	}

	if(IOBan::getInstance()->isIpBanished(clientIp))
	{
		disconnectClient(0x0A, "Your IP is banished!");
		return;
	}

	uint32_t id = 1;
	if(!IOLoginData::getInstance()->getAccountId(name, id))
	{
		ConnectionManager::getInstance()->addAttempt(clientIp, protocolId, false);
		disconnectClient(0x0A, "Invalid account id.");
		return;
	}

	Account account = IOLoginData::getInstance()->loadAccount(id);
	if (name != 10 && !encryptTest(account.salt + password, account.password))
	{
		ConnectionManager::getInstance()->addAttempt(clientIp, protocolId, false);
		disconnectClient(0x0A, "Invalid password.");
		return;
	}

	Ban ban;
	ban.value = account.number;

	ban.type = BAN_ACCOUNT;
	if(IOBan::getInstance()->getData(ban) && !IOLoginData::getInstance()->hasFlag(account.number, PlayerFlag_CannotBeBanned))
	{
		bool deletion = ban.expires < 0;
		std::string name_ = "Automatic ";
		if(!ban.adminId)
			name_ += (deletion ? "deletion" : "banishment");
		else
			IOLoginData::getInstance()->getNameByGuid(ban.adminId, name_, true);

		std::stringstream ss;
		ss << "Your account has been " << (deletion ? "deleted" : "banished") << " at:\n" << formatDateEx(ban.added, "%d %b %Y").c_str()
			<< " by: " << name_.c_str() << "\nReason:\n" << getReason(ban.reason).c_str() << ".\nComment:\n" << ban.comment.c_str() << ".\nYour " << (deletion ?
			"account won't be undeleted" : "banishment will be lifted at:\n") << (deletion ? "" : formatDateEx(ban.expires).c_str());

		disconnectClient(0x0A, ss.str().c_str());
		return;
	}

	// remove premium days
	#ifndef __LOGIN_SERVER__
	IOLoginData::getInstance()->removePremium(account);
	if(account.name != "10" && !g_config.getBool(ConfigManager::ACCOUNT_MANAGER) && !account.charList.size())
	{
		disconnectClient(0x0A, std::string("This account does not contain any character yet.\nCreate a new character on the "
			+ g_config.getString(ConfigManager::SERVER_NAME) + " website at " + g_config.getString(ConfigManager::URL) + ".").c_str());
		return;
	}
	#else
	Characters charList;
	for(Characters::iterator it = account.charList.begin(); it != account.charList.end(); ++it)
	{
		if(version >= it->second.server->getVersionMin() && version <= it->second.server->getVersionMax())
			charList[it->first] = it->second;
	}

	IOLoginData::getInstance()->removePremium(account);
	if(account.name != "10" && !g_config.getBool(ConfigManager::ACCOUNT_MANAGER) && !charList.size())
	{
		disconnectClient(0x0A, std::string("This account does not contain any character on this client yet.\nCreate a new character on the "
			+ g_config.getString(ConfigManager::SERVER_NAME) + " website at " + g_config.getString(ConfigManager::URL) + ".").c_str());
		return;
	}
	#endif

	ConnectionManager::getInstance()->addAttempt(clientIp, protocolId, true);
	if(OutputMessage_ptr output = OutputMessagePool::getInstance()->getOutputMessage(this, false))
	{
		TRACK_MESSAGE(output);
		output->put<char>(0x14);
		uint32_t serverIp = serverIps.front().first;
		for(std::list<std::pair<uint32_t, uint32_t> >::iterator it = serverIps.begin(); it != serverIps.end(); ++it)
		{
			if((it->first & it->second) != (clientIp & it->second))
				continue;

			serverIp = it->first;
			break;
		}

		char motd[1300];
		sprintf(motd, "%d\n%s", g_game.getMotdId(), g_config.getString(ConfigManager::MOTD).c_str());
		output->putString(motd);

		//Add char list
		output->put<char>(0x64);
		if(account.name == "10" && account.name != "0")
		{
			PlayerVector players;
			for(AutoList<Player>::iterator it = Player::autoList.begin(); it != Player::autoList.end(); ++it)
			{
				if(!it->second->isRemoved() && it->second->client->isBroadcasting())
					players.push_back(it->second);
			}

			std::sort(players.begin(), players.end(), Player::sort);
			output->put<char>(players.size());
			for(PlayerVector::iterator it = players.begin(); it != players.end(); ++it)
			{
				std::stringstream s;
				s << (*it)->getLevel();
				if(!(*it)->client->check(password))
					s << "*";

				output->putString((*it)->getName());
				output->putString(s.str());
				output->put<uint32_t>(serverIp);

				output->put<uint16_t>(g_config.getNumber(ConfigManager::GAME_PORT));
			}
		}
		else
		{
			if(g_config.getBool(ConfigManager::ACCOUNT_MANAGER) && account.number != 1)
			{
				output->put<char>(account.charList.size() + 1);
				output->putString("Account Manager");

				output->putString(g_config.getString(ConfigManager::SERVER_NAME));
				output->put<uint32_t>(serverIp);

				output->put<uint16_t>(g_config.getNumber(ConfigManager::GAME_PORT));
			}
			else
				output->put<char>((uint8_t)account.charList.size());

#ifndef __LOGIN_SERVER__
			for(Characters::iterator it = account.charList.begin(); it != account.charList.end(); ++it)
			{
				output->putString((*it));
				if(g_config.getBool(ConfigManager::ON_OR_OFF_CHARLIST)
					&& !g_config.getBool(ConfigManager::CHARLIST_INFO))
				{
					if(g_game.getPlayerByName((*it)))
						output->putString("Online");
					else
						output->putString("Offline");
				}
				else if(g_config.getBool(ConfigManager::CHARLIST_INFO))
				{
					std::stringstream str;
					Player *player = g_game.getPlayerByName((*it));
					bool v = false;
					if(g_config.getBool(ConfigManager::ON_OR_OFF_CHARLIST))
					{
						if(player)
							str << "On";
						else
							str << "Off";

						str << "/";
					}

					if(!player)
					{
						v = true;
						player = g_game.getPlayerByNameEx((*it));
					}

					str << player->getLevel();
					str << "/";
					str << player->getVocation()->getName();
					output->putString(str.str());
					if(v)
						delete player;
					}
				else
					output->putString(g_config.getString(ConfigManager::SERVER_NAME));

				output->put<uint32_t>(serverIp);
				output->put<uint16_t>(g_config.getNumber(ConfigManager::GAME_PORT));
				}
#else
			for(Characters::iterator it = charList.begin(); it != charList.end(); ++it)
			{
				output->putString(it->second.name);
				if(!g_config.getBool(ConfigManager::ON_OR_OFF_CHARLIST) || it->second.status < 0)
					output->putString(it->second.server->getName());
				else if(it->second.status)
					output->putString("Online");
				else
					output->putString("Offline");

				output->put<uint32_t>(it->second.server->getAddress());
				IntegerVec games = it->second.server->getPorts();
				output->put<uint16_t>(games[random_range(0, games.size() - 1)]);
			}
#endif
			}

		//Add premium days
		if(g_config.getBool(ConfigManager::FREE_PREMIUM))
			output->put<uint16_t>(GRATIS_PREMIUM);
		else
			output->put<uint16_t>(account.premiumDays);

		OutputMessagePool::getInstance()->send(output);
	}

	getConnection()->close();
}
Exemple #25
0
void loadCurrentCursorData() {
    CGError err;
    CGSConnectionRef connection = getConnection();
	
	if (!connection) {
		if (!maxFailsRemaining)
			return;
	}
	
    if (CGSGetGlobalCursorDataSize(connection, &cursorDataSize) != kCGErrorSuccess) {
        rfbLog("Error obtaining cursor data - cursor not sent\n");
        return;
    }
	
	if (cursorData)
		free(cursorData);
    cursorData = (unsigned char*)malloc(sizeof(unsigned char) * cursorDataSize);
    err = CGSGetGlobalCursorData(connection,
                                 cursorData,
                                 &cursorDataSize,
                                 &cursorRowBytes,
                                 &cursorRect,
                                 &hotspot,
                                 &cursorDepth,
                                 &components,
                                 &cursorBitsPerComponent);
	
    //CGSReleaseConnection(connection);
    if (err != kCGErrorSuccess) {
		free(cursorData);
		cursorData = NULL;
        rfbLog("Error obtaining cursor data - cursor not sent\n");
        return;
    }
	
    cursorFormat.depth = (cursorDepth == 32 ? 24 : cursorDepth);
    cursorFormat.bitsPerPixel = cursorDepth;
    cursorFormat.bigEndian = TRUE;
    cursorFormat.trueColour = TRUE;
    cursorFormat.redMax = cursorFormat.greenMax = cursorFormat.blueMax = (unsigned short) ((1<<cursorBitsPerComponent) - 1);
	cursorFormat.bigEndian = !littleEndian;
	cursorFormat.redShift   = (unsigned char) (cursorBitsPerComponent * 2);
	cursorFormat.greenShift = (unsigned char) (cursorBitsPerComponent * 1);
	cursorFormat.blueShift  = (unsigned char) (cursorBitsPerComponent * 0);
	    
    cursorMaskSize = floor((cursorRect.size.width+7)/8) * cursorRect.size.height;

	if (cursorMaskData)
		free(cursorMaskData);
	cursorMaskData = (unsigned char*)malloc(sizeof(unsigned char) * cursorMaskSize);
	
	// Apple Cursors can use a full Alpha channel.
    // Since we can only send a bit mask - to get closer we will compose the full color with a white
	
    // For starters we'll set mask to OFF (transparent) everywhere)
    memset(cursorMaskData, 0, cursorMaskSize);
    // This algorithm assumes the Alpha channel is the first component
    {
		unsigned char *maskPointer = cursorMaskData;
        unsigned char *cursorRowData = cursorData;
        unsigned char *cursorColumnData = cursorData;
        unsigned int cursorBytesPerPixel = (cursorDepth/8);
        unsigned char mask = 0;
		unsigned int alphaShift = (8 - cursorBitsPerComponent);
        unsigned char fullOn = (0xFF) >> alphaShift;
        unsigned char alphaThreshold = (0x60) >> alphaShift; // Only include the pixel if it's coverage is greater than this
        int dataX, dataY, componentIndex;
		
        for (dataY = 0; dataY < cursorRect.size.height; dataY++) {
            cursorColumnData = cursorRowData;
            for (dataX = 0; dataX < cursorRect.size.width; dataX++) {
				if (littleEndian)
					mask = (unsigned char)(*(cursorColumnData+(cursorBytesPerPixel-1))) >> alphaShift;
				else
					mask = (unsigned char)(*cursorColumnData) >> alphaShift;
                if (mask > alphaThreshold) {
                    // Write the Bit For The Mask to be ON (opaque)
					maskPointer[(dataX/8)] |= (0x0080 >> (dataX % 8));
                    // Composite Alpha into the cursors other channels - only for 32 bit
                    if (cursorDepth == 32 && mask != fullOn) {
                        for (componentIndex = 0; componentIndex < components; componentIndex++) {
                            *cursorColumnData = (unsigned char) (fullOn - mask + ((*cursorColumnData * mask)/fullOn)) & 0xFF;
                            cursorColumnData++;
                        }
                    }
                    else
                        cursorColumnData += cursorBytesPerPixel;
                }
                else
                    cursorColumnData += cursorBytesPerPixel;
            }
Exemple #26
0
void ProtocolAdmin::parsePacket(NetworkMessage& msg)
{
	if(g_game.getGameState() == GAMESTATE_SHUTDOWN)
	{
		getConnection()->close();
		return;
	}

	uint8_t recvbyte = msg.get<char>();
	OutputMessage_ptr output = OutputMessagePool::getInstance()->getOutputMessage(this, false);
	if(!output)
		return;

	TRACK_MESSAGE(output);
	switch(m_state)
	{
		case ENCRYPTION_NO_SET:
		{
			if(Admin::getInstance()->isEncypted())
			{
				if((time(NULL) - m_startTime) > 30000)
				{
					getConnection()->close();
					addLogLine(LOGTYPE_EVENT, "encryption timeout");
					return;
				}

				if(recvbyte != AP_MSG_ENCRYPTION && recvbyte != AP_MSG_KEY_EXCHANGE)
				{
					output->put<char>(AP_MSG_ERROR);
					output->putString("encryption needed");
					OutputMessagePool::getInstance()->send(output);

					getConnection()->close();
					addLogLine(LOGTYPE_EVENT, "wrong command while ENCRYPTION_NO_SET");
					return;
				}
			}
			else
				m_state = NO_LOGGED_IN;

			break;
		}

		case NO_LOGGED_IN:
		{
			if(g_config.getBool(ConfigManager::ADMIN_REQUIRE_LOGIN))
			{
				if((time(NULL) - m_startTime) > 30000)
				{
					//login timeout
					getConnection()->close();
					addLogLine(LOGTYPE_EVENT, "login timeout");
					return;
				}

				if(m_loginTries > 3)
				{
					output->put<char>(AP_MSG_ERROR);
					output->putString("too many login tries");
					OutputMessagePool::getInstance()->send(output);

					getConnection()->close();
					addLogLine(LOGTYPE_EVENT, "too many login tries");
					return;
				}

				if(recvbyte != AP_MSG_LOGIN)
				{
					output->put<char>(AP_MSG_ERROR);
					output->putString("you are not logged in");
					OutputMessagePool::getInstance()->send(output);

					getConnection()->close();
					addLogLine(LOGTYPE_EVENT, "wrong command while NO_LOGGED_IN");
					return;
				}
			}
			else
				m_state = LOGGED_IN;

			break;
		}

		case LOGGED_IN:
			break;

		default:
		{
			getConnection()->close();
			addLogLine(LOGTYPE_EVENT, "no valid connection state!!!");
			return;
		}
	}

	m_lastCommand = time(NULL);
	switch(recvbyte)
	{
		case AP_MSG_LOGIN:
		{
			if(m_state == NO_LOGGED_IN && g_config.getBool(ConfigManager::ADMIN_REQUIRE_LOGIN))
			{
				std::string pass = msg.getString(), word = g_config.getString(ConfigManager::ADMIN_PASSWORD);
				_encrypt(word, false);
				if(pass == word)
				{
					m_state = LOGGED_IN;
					output->put<char>(AP_MSG_LOGIN_OK);
					addLogLine(LOGTYPE_EVENT, "login ok");
				}
				else
				{
					m_loginTries++;
					output->put<char>(AP_MSG_LOGIN_FAILED);
					output->putString("wrong password");
					addLogLine(LOGTYPE_EVENT, "login failed.("+ pass + ")");
				}
			}
			else
			{
				output->put<char>(AP_MSG_LOGIN_FAILED);
				output->putString("cannot login");
				addLogLine(LOGTYPE_EVENT, "wrong state at login");
			}

			break;
		}

		case AP_MSG_ENCRYPTION:
		{
			if(m_state == ENCRYPTION_NO_SET && Admin::getInstance()->isEncypted())
			{
				uint8_t keyType = msg.get<char>();
				switch(keyType)
				{
					case ENCRYPTION_RSA1024XTEA:
					{
						RSA* rsa = Admin::getInstance()->getRSAKey(ENCRYPTION_RSA1024XTEA);
						if(!rsa)
						{
							output->put<char>(AP_MSG_ENCRYPTION_FAILED);
							addLogLine(LOGTYPE_EVENT, "no valid server key type");
							break;
						}

						if(RSA_decrypt(rsa, msg))
						{
							m_state = NO_LOGGED_IN;
							uint32_t k[4]= {msg.get<uint32_t>(), msg.get<uint32_t>(), msg.get<uint32_t>(), msg.get<uint32_t>()};

							//use for in/out the new key we have
							enableXTEAEncryption();
							setXTEAKey(k);

							output->put<char>(AP_MSG_ENCRYPTION_OK);
							addLogLine(LOGTYPE_EVENT, "encryption ok");
						}
						else
						{
							output->put<char>(AP_MSG_ENCRYPTION_FAILED);
							output->putString("wrong encrypted packet");
							addLogLine(LOGTYPE_EVENT, "wrong encrypted packet");
						}

						break;
					}

					default:
					{
						output->put<char>(AP_MSG_ENCRYPTION_FAILED);
						output->putString("no valid key type");

						addLogLine(LOGTYPE_EVENT, "no valid client key type");
						break;
					}
				}
			}
			else
			{
				output->put<char>(AP_MSG_ENCRYPTION_FAILED);
				output->putString("cannot set encryption");
				addLogLine(LOGTYPE_EVENT, "cannot set encryption");
			}

			break;
		}

		case AP_MSG_KEY_EXCHANGE:
		{
			if(m_state == ENCRYPTION_NO_SET && Admin::getInstance()->isEncypted())
			{
				uint8_t keyType = msg.get<char>();
				switch(keyType)
				{
					case ENCRYPTION_RSA1024XTEA:
					{
						RSA* rsa = Admin::getInstance()->getRSAKey(ENCRYPTION_RSA1024XTEA);
						if(!rsa)
						{
							output->put<char>(AP_MSG_KEY_EXCHANGE_FAILED);
							addLogLine(LOGTYPE_EVENT, "no valid server key type");
							break;
						}

						output->put<char>(AP_MSG_KEY_EXCHANGE_OK);
						output->put<char>(ENCRYPTION_RSA1024XTEA);

						char RSAPublicKey[128];
						rsa->getPublicKey(RSAPublicKey);

						output->put<char>s(RSAPublicKey, 128);
						break;
					}

					default:
					{
						output->put<char>(AP_MSG_KEY_EXCHANGE_FAILED);
						addLogLine(LOGTYPE_EVENT, "no valid client key type");
						break;
					}
				}
			}
			else
			{
				output->put<char>(AP_MSG_KEY_EXCHANGE_FAILED);
				output->putString("cannot get public key");
				addLogLine(LOGTYPE_EVENT, "cannot get public key");
			}

			break;
		}

		case AP_MSG_COMMAND:
		{
			if(m_state != LOGGED_IN)
			{
				addLogLine(LOGTYPE_EVENT, "recvbyte == AP_MSG_COMMAND && m_state != LOGGED_IN !!!");
				break;
			}

			uint8_t command = msg.get<char>();
			switch(command)
			{
				case CMD_SAVE_SERVER:
				case CMD_SHALLOW_SAVE_SERVER:
				{
					uint8_t flags = (uint8_t)SAVE_PLAYERS | (uint8_t)SAVE_MAP | (uint8_t)SAVE_STATE;
					if(command == CMD_SHALLOW_SAVE_SERVER)
						flags |= SAVE_PLAYERS_SHALLOW;

					addLogLine(LOGTYPE_EVENT, "saving server");
					Dispatcher::getInstance().addTask(createTask(boost::bind(&Game::saveGameState, &g_game, flags)));

					output->put<char>(AP_MSG_COMMAND_OK);
					break;
				}

				case CMD_CLOSE_SERVER:
				{
					addLogLine(LOGTYPE_EVENT, "closing server");
					Dispatcher::getInstance().addTask(createTask(boost::bind(
						&Game::setGameState, &g_game, GAMESTATE_CLOSED)));

					output->put<char>(AP_MSG_COMMAND_OK);
					break;
				}

				case CMD_OPEN_SERVER:
				{
					addLogLine(LOGTYPE_EVENT, "opening server");
					g_game.setGameState(GAMESTATE_NORMAL);

					output->put<char>(AP_MSG_COMMAND_OK);
					break;
				}

				case CMD_SHUTDOWN_SERVER:
				{
					addLogLine(LOGTYPE_EVENT, "shutting down server");
					Dispatcher::getInstance().addTask(createTask(boost::bind(
						&Game::setGameState, &g_game, GAMESTATE_SHUTDOWN)));

					output->put<char>(AP_MSG_COMMAND_OK);
					break;
				}

				case CMD_PAY_HOUSES:
				{
					Dispatcher::getInstance().addTask(createTask(boost::bind(
						&ProtocolAdmin::adminCommandPayHouses, this)));
					break;
				}

				case CMD_RELOAD_SCRIPTS:
				{
					const int8_t reload = msg.get<char>();
					Dispatcher::getInstance().addTask(createTask(boost::bind(
						&ProtocolAdmin::adminCommandReload, this, reload)));
					break;
				}

				case CMD_KICK:
				{
					const std::string param = msg.getString();
					Dispatcher::getInstance().addTask(createTask(boost::bind(
						&ProtocolAdmin::adminCommandKickPlayer, this, param)));
					break;
				}

				case CMD_SEND_MAIL:
				{
					const std::string xmlData = msg.getString();
					Dispatcher::getInstance().addTask(createTask(boost::bind(
						&ProtocolAdmin::adminCommandSendMail, this, xmlData)));
					break;
				}

				case CMD_BROADCAST:
				{
					const std::string param = msg.getString();
					addLogLine(LOGTYPE_EVENT, "broadcasting: " + param);
					Dispatcher::getInstance().addTask(createTask(boost::bind(
						&Game::broadcastMessage, &g_game, param, MSG_STATUS_WARNING)));

					output->put<char>(AP_MSG_COMMAND_OK);
					break;
				}

				default:
				{
					output->put<char>(AP_MSG_COMMAND_FAILED);
					output->putString("not known server command");
					addLogLine(LOGTYPE_EVENT, "not known server command");
				}
			}
			break;
		}

		case AP_MSG_PING:
			output->put<char>(AP_MSG_PING_OK);
			break;

		case AP_MSG_KEEP_ALIVE:
			break;

		default:
		{
			output->put<char>(AP_MSG_ERROR);
			output->putString("not known command byte");

			addLogLine(LOGTYPE_EVENT, "not known command byte");
			break;
		}
	}

	if(output->size() > 0)
		OutputMessagePool::getInstance()->send(output);
}
Exemple #27
0
SEXP readtablehead(SEXP args)
{
    SEXP file, comstr, ans = R_NilValue, ans2, quotes, sep;
    int nlines, i, c, quote=0, nread, nbuf, buf_size = BUF_SIZE, blskip;
    const char *p; char *buf;
    Rboolean empty, skip;
    LocalData data = {NULL, 0, 0, '.', NULL, NO_COMCHAR, 0, NULL, FALSE,
		      FALSE, 0, FALSE, FALSE};
    data.NAstrings = R_NilValue;

    args = CDR(args);

    file = CAR(args);		   args = CDR(args);
    nlines = asInteger(CAR(args)); args = CDR(args);
    comstr = CAR(args);		   args = CDR(args);
    blskip = asLogical(CAR(args)); args = CDR(args);
    quotes = CAR(args);		   args = CDR(args);
    sep = CAR(args);

    if (nlines <= 0 || nlines == NA_INTEGER)
	error(_("invalid '%s' argument"), "nlines");
    if (blskip == NA_LOGICAL) blskip = 1;
    if (isString(quotes)) {
	const char *sc = translateChar(STRING_ELT(quotes, 0));
	if (strlen(sc)) data.quoteset = strdup(sc);
	else data.quoteset = "";
    } else if (isNull(quotes))
	data.quoteset = "";
    else
	error(_("invalid quote symbol set"));

    if (TYPEOF(comstr) != STRSXP || length(comstr) != 1)
	error(_("invalid '%s' argument"), "comment.char");
    p = translateChar(STRING_ELT(comstr, 0));
    data.comchar = NO_COMCHAR; /*  here for -Wall */
    if (strlen(p) > 1)
	error(_("invalid '%s' argument"), "comment.char");
    else if (strlen(p) == 1) data.comchar = (int)*p;
    if (isString(sep) || isNull(sep)) {
	if (length(sep) == 0) data.sepchar = 0;
	else data.sepchar = (unsigned char) translateChar(STRING_ELT(sep, 0))[0];
	/* gets compared to chars: bug prior to 1.7.0 */
    } else error(_("invalid '%s' argument"), "sep");

    i = asInteger(file);
    data.con = getConnection(i);
    data.ttyflag = (i == 0);
    data.wasopen = data.con->isopen;
    if(!data.wasopen) {
	strcpy(data.con->mode, "r");
	if(!data.con->open(data.con)) error(_("cannot open the connection"));
    } else { /* for a non-blocking connection, more input may
		have become available, so re-position */
	if(data.con->canseek && !data.con->blocking)
	    data.con->seek(data.con, data.con->seek(data.con, -1, 1, 1), 1, 1);
    }

    buf = (char *) malloc(buf_size);
    if(!buf)
	error(_("cannot allocate buffer in 'readTableHead'"));

    PROTECT(ans = allocVector(STRSXP, nlines));
    for(nread = 0; nread < nlines; ) {
	nbuf = 0; empty = TRUE, skip = FALSE;
	if (data.ttyflag) sprintf(ConsolePrompt, "%d: ", nread);
	/* want to interpret comments here, not in scanchar */
	while((c = scanchar(TRUE, &data)) != R_EOF) {
	    if(nbuf >= buf_size -1) {
		buf_size *= 2;
		char *tmp = (char *) realloc(buf, buf_size);
		if(!tmp) {
		    free(buf);
		    error(_("cannot allocate buffer in 'readTableHead'"));
		} else buf = tmp;
	    }
	    /* Need to handle escaped embedded quotes, and how they are
	       escaped depends on 'sep' */
	    if(quote) {
		if(data.sepchar == 0 && c == '\\') {
		    /* all escapes should be passed through */
		    buf[nbuf++] = (char) c;
		    c = scanchar(TRUE, &data);
		    if(c == R_EOF)
			error(_("\\ followed by EOF"));
		    buf[nbuf++] = (char) c;
		    continue;
		} else if(quote && c == quote) {
		    if(data.sepchar == 0)
			quote = 0;
		    else { /* need to check for doubled quote */
			char c2 = (char) scanchar(TRUE, &data);
			if(c2 == quote)
			    buf[nbuf++] = (char) c; /* and c = c2 */
			else {
			    unscanchar(c2, &data);
			    quote = 0;
			}
		    }
		}
	    } else if(!quote && !skip && strchr(data.quoteset, c)) quote = c;
	    /* A line is empty only if it contains nothing before
	       EOL, EOF or a comment char.
	       A line containing just white space is not empty if sep=","
	       However foo\nEOF does not have a final empty line.
	    */
	    if(empty && !skip)
		if(c != '\n' && c != data.comchar) empty = FALSE;
	    if(!quote && !skip && c == data.comchar) skip = TRUE;
	    if(quote || c != '\n') buf[nbuf++] = (char) c; else break;
	}
	buf[nbuf] = '\0';
	if(data.ttyflag && empty) goto no_more_lines;
	if(!empty || (c != R_EOF && !blskip)) { /* see previous comment */
	    SET_STRING_ELT(ans, nread, mkChar(buf));
	    nread++;
	}
	if(c == R_EOF) goto no_more_lines;
    }
    UNPROTECT(1);
    free(buf);
    if(!data.wasopen) data.con->close(data.con);
    if (data.quoteset[0]) free(data.quoteset);
    return ans;

no_more_lines:
    if(!data.wasopen) data.con->close(data.con);
    if(nbuf > 0) { /* incomplete last line */
	if(data.con->text && data.con->blocking) {
	    warning(_("incomplete final line found by readTableHeader on '%s'"),
		    data.con->description);
	} else
	    error(_("incomplete final line found by readTableHeader on '%s'"),
		  data.con->description);
    }
    free(buf);
    PROTECT(ans2 = allocVector(STRSXP, nread));
    for(i = 0; i < nread; i++)
	SET_STRING_ELT(ans2, i, STRING_ELT(ans, i));
    UNPROTECT(2);
    if (data.quoteset[0]) free(data.quoteset);
    return ans2;
}
Exemple #28
0
void ProtocolGame::disconnect(uint8_t reason)
{
	getConnection()->write(&reason, 1);
	getConnection()->close();
}
Exemple #29
0
void Protocol::writeRaw(char const *buff, long len)
{
  ULXR_TRACE("writeRaw");
  getConnection()->write(buff, len);
}
bool ProtocolLogin::parseFirstPacket(NetworkMessage& msg)
{
	if(server.game().getGameState() == GAME_STATE_SHUTDOWN)
	{
		getConnection()->close();
		return false;
	}

	uint32_t clientIp = getConnection()->getIP();
	/*uint16_t operatingSystem = msg.GetU16();*/msg.SkipBytes(2);
	uint16_t version = msg.GetU16();

	msg.SkipBytes(12);
	if(!RSA_decrypt(msg))
	{
		getConnection()->close();
		return false;
	}

	uint32_t key[4] = {msg.GetU32(), msg.GetU32(), msg.GetU32(), msg.GetU32()};
	enableXTEAEncryption();
	setXTEAKey(key);

	std::string name = msg.GetString(), password = msg.GetString();
	if(name.empty())
	{
		if(!server.configManager().getBool(ConfigManager::ACCOUNT_MANAGER))
		{
			disconnectClient(0x0A, "Invalid account name.");
			return false;
		}

		name = "1";
		password = "******";
	}

	if(version < CLIENT_VERSION_MIN || version > CLIENT_VERSION_MAX)
	{
		disconnectClient(0x0A, CLIENT_VERSION_STRING);
		return false;
	}

	if(server.game().getGameState() < GAME_STATE_NORMAL)
	{
		disconnectClient(0x0A, "Server is just starting up, please wait.");
		return false;
	}

	if(server.game().getGameState() == GAME_STATE_MAINTAIN)
	{
		disconnectClient(0x0A, "Server is under maintenance, please re-connect in a while.");
		return false;
	}

	if(ConnectionManager::getInstance()->isDisabled(clientIp, protocolId))
	{
		disconnectClient(0x0A, "Too many connections attempts from your IP address, please try again later.");
		return false;
	}

	if(IOBan::getInstance()->isIpBanished(clientIp))
	{
		disconnectClient(0x0A, "Your IP is banished!");
		return false;
	}

	uint32_t id = 1;
	if(!IOLoginData::getInstance()->getAccountId(name, id))
	{
		ConnectionManager::getInstance()->addAttempt(clientIp, protocolId, false);
		disconnectClient(0x0A, "Invalid account name.");
		return false;
	}

	AccountP account = IOLoginData::getInstance()->loadAccount(id);
	if (account == nullptr) {
		disconnectClient(0x0A, "Invalid account name.");
		return false;
	}

	if(!encryptTest(password, account->getPassword()))
	{
		ConnectionManager::getInstance()->addAttempt(clientIp, protocolId, false);
		disconnectClient(0x0A, "Invalid password.");
		return false;
	}

	Ban ban;
	ban.value = account->getId();

	ban.type = BAN_ACCOUNT;
	if(IOBan::getInstance()->getData(ban) && !IOLoginData::getInstance()->hasFlag(account->getId(), PlayerFlag_CannotBeBanned))
	{
		bool deletion = ban.expires < 0;
		std::string name_ = "Automatic ";
		if(!ban.adminId)
			name_ += (deletion ? "deletion" : "banishment");
		else
			IOLoginData::getInstance()->getNameByGuid(ban.adminId, name_, true);

		char buffer[500 + ban.comment.length()];
		sprintf(buffer, "Your account has been %s at:\n%s by: %s,\nfor the following reason:\n%s.\nThe action taken was:\n%s.\nThe comment given was:\n%s.\nYour %s%s.",
			(deletion ? "deleted" : "banished"), formatDateShort(ban.added).c_str(), name_.c_str(),
			getReason(ban.reason).c_str(), getAction(ban.action, false).c_str(), ban.comment.c_str(),
			(deletion ? "account won't be undeleted" : "banishment will be lifted at:\n"),
			(deletion ? "." : formatDateShort(ban.expires, true).c_str()));

		disconnectClient(0x0A, buffer);
		return false;
	}

	const Account::Characters& characters = account->getCharacters();
	if(!server.configManager().getBool(ConfigManager::ACCOUNT_MANAGER) && characters.empty())
	{
		disconnectClient(0x0A, std::string("This account does not contain any character yet.\nCreate a new character on the "
			+ server.configManager().getString(ConfigManager::SERVER_NAME) + " website at " + server.configManager().getString(ConfigManager::URL) + ".").c_str());
		return false;
	}

	ConnectionManager::getInstance()->addAttempt(clientIp, protocolId, true);
	if(OutputMessage_ptr output = OutputMessagePool::getInstance()->getOutputMessage(this, false))
	{
		TRACK_MESSAGE(output);
		output->AddByte(0x14);

		char motd[1300];
		sprintf(motd, "%d\n%s", server.game().getMotdId(), server.configManager().getString(ConfigManager::MOTD).c_str());
		output->AddString(motd);

		uint32_t serverIp = serverIps[0].first;
		for(IpList::iterator it = serverIps.begin(); it != serverIps.end(); ++it)
		{
			if((it->first & it->second) != (clientIp & it->second))
				continue;

			serverIp = it->first;
			break;
		}

		//Add char list
		output->AddByte(0x64);
		if(server.configManager().getBool(ConfigManager::ACCOUNT_MANAGER) && id != 1)
		{
			output->AddByte(characters.size() + 1);
			output->AddString("Account Manager");
			output->AddString(server.configManager().getString(ConfigManager::SERVER_NAME));
			output->AddU32(serverIp);
			output->AddU16(server.configManager().getNumber(ConfigManager::GAME_PORT));
		}
		else
			output->AddByte((uint8_t)characters.size());

		for (auto it = characters.cbegin(); it != characters.cend(); ++it) {
			auto& character = *it;

#ifndef __LOGIN_SERVER__
			output->AddString(character->getName());
			output->AddString(character->getType());
			output->AddU32(serverIp);
			output->AddU16(server.configManager().getNumber(ConfigManager::GAME_PORT));
#else
			if(version < it->second->getVersionMin() || version > it->second->getVersionMax())
				continue;

			output->AddString(it->first);
			output->AddString(it->second->getName());
			output->AddU32(it->second->getAddress());
			output->AddU16(it->second->getPort());
#endif
		}

		Days premiumDays = account->getPremiumDays();
		if (premiumDays.count() >= std::numeric_limits<uint16_t>::max()) {
			output->AddU16(std::numeric_limits<uint16_t>::max());
		}
		else {
			output->AddU16(static_cast<uint16_t>(premiumDays.count()));
		}

		OutputMessagePool::getInstance()->send(output);
	}

	getConnection()->close();
	return true;
}