insert multiple char * into a const char* with pre filled text - c++

i have setup a working mysql connector for my c++ project. Now i'm making a login for registered users.
i want to get the username and password into the SQLquery string.
i am trying to get this working:
currently its displaying noting and the game crashes.
#include "boost/lexical_cast.hpp" //boost
#include <cgl\cgl.h> // game library (core media library)
#include <sstream> // sstream
char* username=DEFSER;
char* password=PASS12345;
const char *SQLquery;
std::string SQLquery("SELECT * FROM Users WHERE UserName='" + boost::lexical_cast<std::string>(username) + "' AND PassWord='" + boost::lexical_cast<std::string>(password) + "'");
what i want to get out of SQLquery:
SELECT * FROM Users WHERE UserName='DEFSER' AND PassWord='PASS12345'
and i execute it in this way:
res = stmt->executeQuery(SQLquery);
this is not a fully working code i only want to know how i can get the username and password into the SQLquery.
error when i try to run the query:
Run-Time Check Failure #3 - The variable 'SQLquery' is being used without being initialized.

What you are doing is not concatenating strings, you are adding std::string objects to a literal string pointer.
The std::string class handles concatenation of C-style strings just fine without any lexical_cast, so just do e.g.
std::string SQLquery = "SELECT * FROM Users WHERE UserName='" +
username + "' AND PassWord='" + password + "'";
After testing the above solution doesn't actually work for me. But the following does:
std::string SQLQuery = (std::ostringstream() << "SELECT * FROM Users WHERE UserName='"
<< username << "' AND PassWord='" << password << "'").str();

Related

How to create Password Digest for ONVIF in C++?

Following ONVIF documentation, the password digest for making ONVIF Soap request should be like this.
PasswordDigest = B64ENCODE( SHA1( B64DECODE( Nonce ) + Date + Password ) )
For example:
Nonce – LKqI6G/AikKCQrN0zqZFlg==
Date – 2010-09-16T07:50:45Z
Password – userpassword
Resulting Digest – tuOSpGlFlIXsozq4HFNeeGeFLEI=
Below is how I have written in C++, which resulted in an invalid user token.
std::string dateTime = "2022-09-10T10:10:59.000Z";
std::string nonce = "secret";
std::string password = "mypassword";
std::string str = decode_str(nonce) + dateTime + password;
unsigned char hash[SHA_DIGEST_LENGTH];
SHA1((const unsigned char *) str.c_str(), strlen(str.c_str()) - 1, hash);
uint8_t * hash_ptr = hash;
std::string psswrd = encode_str(hash_ptr, sizeof(hash));
std::cout << psswrd << std::endl; // +cz8/SJS89Uee7cTjW9aiMG9CTE=
But the above password is invalid, resulted the request to fail after timeout.
How to create Password Digest for ONVIF in C++?
I believe your problem is in the call to SHA1. The second parameter (length of the string to be hashed) is strlen(str) - 1, meaning you cut off the final character of the password, which will then result in an invalid hash.
Please either use the length function of std::string or strlen without that decrement (which does not include the \0).
The second 'problem' is in the string nonce, which is not a Base64 string at all, however I am willing to assume this to be a plain 'example value' because you do not wish you disclose your actual nonce value.
Below is a valid digest password.
std::string dateTime = "2022-09-10T10:10:59.000Z";
std::string nonce = "secret";
std::string password = "mypassword";
std::string str = nonce + dateTime + password;
unsigned char hash[SHA_DIGEST_LENGTH];
SHA1((const unsigned char *) str.c_str(), str.size(), hash);
uint8_t * hash_ptr = hash;
std::string psswrd = encode_str(hash_ptr, sizeof(hash));

PQexecParams in C++, query error

I'm using pqlib with postgresql version 9.1.11
I have the following code
const char *spid = std::to_string(pid).c_str();
PGresult *res;
const char *paramValues[2] = {u->getID().c_str(), spid};
std::string table;
table = table.append("public.\"").append(Constants::USER_PATTERNS_TABLE).append("\"");
std::string param_name_pid = Constants::RELATION_TABLE_PATTERN_ID;
std::string param_name_uid = Constants::RELATION_TABLE_USER_ID;
std::string command = Constants::INSERT_COMMAND + table + " (" + param_name_uid + ", " + param_name_pid + ") VALUES ($1, $2::int)";
std::cout << "command: " << command << std::endl;
res = PQexecParams(conn, command.c_str(), 2, NULL, paramValues, NULL, NULL,0);
Where
INSERT_COMMAND = "INSERT INTO " (string)
USER_PATTERN_TABLE = "User_Patterns" (string)
RELATION_TABLE_PATTERN_ID = "pattern_id" (string)
RELATION_TABLE_USER_ID = "user_id" (string)
pid = an int
u->getID() = a string
conn = the connection to the db
The table "User_Patterns" is defined as
CREATE TABLE "User_Patterns"(
user_id TEXT references public."User" (id) ON UPDATE CASCADE ON DELETE CASCADE
,pattern_id BIGSERIAL references public."Pattern" (id) ON UPDATE CASCADE
,CONSTRAINT user_patterns_pkey PRIMARY KEY (user_id,pattern_id) -- explicit pk
)WITH (
OIDS=FALSE
);
I already have a user and a pattern loaded into their respective tables.
The command generated is :
INSERT INTO public."User_Patterns" (user_id, pattern_id) VALUES ($1, $2::int)
I also tried with $2, $2::bigint, $2::int4
The problem is:
I receive the error :
ERROR: invalid input syntax for integer: "public.""
I already use PQexecParams to store users and patterns, the only difference is that they all have text/xml fields (the only int field on patterns is a serial one and I don't store that value myself) but because the user_patterns is a relation table I need to store and int for the pattern_id.
I already read the docs for pqlib and saw the examples, both are useless.
The problem is in the lines:
const char *spid = std::to_string(pid).c_str();
const char *paramValues[2] = {u->getID().c_str(), spid};
std::to_string(pid) creates temporary string and .c_str() returns a pointer to an internal representation of this string, which is destroyed at the end of the line, resulting in a dead pointer. You may also see answer to the question
stringstream::str copy lifetime

Improving performance of WURFL code

I tested the following code which prints the properties of the UserAgent. However I notice that it takes noticeable time to execute the code.
// Initialize the WURFL library.
String projRoot = System.getProperty("user.dir");
wurflFile = projRoot + File.separator + "wurfl-2.3.3" + File.separator + "wurfl.xml";
File dataFile = new File(wurflFile);
wurfl = new CustomWURFLHolder(dataFile);
String deviceUrl = "Apple-iPhone5C1";
WURFLManager manager = wurfl.getWURFLManager();
Device device = manager.getDeviceForRequest(deviceUrl);
System.out.println("Device: " + device.getId());
System.out.println("Capability: " + device.getCapability("preferred_markup"));
System.out.println("Device UA: " + device.getUserAgent());
Map capabilities = device.getCapabilities();
System.out.println("Size of the map: " + capabilities.keySet().size());
Iterator itr = capabilities.keySet().iterator();
while (itr.hasNext()) {
String str = (String) itr.next();
System.out.println(str);
}
One of the reason is that it takes time to load and parse the WURFL XML database file (which is about 20MB size).
I want to know if there is any different WURFL API, which will improve this performance? Eventually, I would be putting this code in a HTTP Proxy where I want to check the device profile parameter for adaptation of the content.
Thanks.

Passing A Variable To SQL

I have a variable that is an IP address. It is saved as text in my Access 2010 database. I am trying to run this query with ipSrc and the query always fails. My guess is that its seeing ipSrc as ipSrc and not as the actual IP address. I tried it with 'ipSrc' and just plain ipSrc and both reurn fail. Also tried ""ipSrc"", failed as well. This failed to. '&ipSrc'. Here is the statement.
SQLCHAR* query = (SQLCHAR*)"SELECT tblIP.[IPAddress], tblIP.[IPType], tblIP.[IPStatus], tblIP.[IPMax] FROM tblIP WHERE tblIP.[IPAddress]= ipSrc AND tblIP.[IPType]=3 AND tblIP.[IPStatus]=1 AND tblIP.[IPMax]=0;";
and here is the definition of ipSrc.
translate_ip(ip_header->source_ip, ipSrc);
Using printf it prints out as an actual IP address.
printf("\n Source IP: %s", ipSrc);
There's no way for the code to know, from what you have there, that ipSrc should be treated specially, it's just going to pass it through as-is.
You can probably try to construct the query string dynamically as a C++ string, and then use that to populate the query. Something like:
std::string strqry =
"SELECT tblIP.[IPAddress], "
+ " tblIP.[IPType], "
+ " tblIP.[IPStatus], "
+ " tblIP.[IPMax] "
+ "FROM tblIP "
+ "WHERE tblIP.[IPAddress] = '" + ipSrc + "' "
+ "AND tblIP.[IPType] = 3 "
+ "AND tblIP.[IPStatus] = 1 "
+ "AND tblIP.[IPMax] = 0"
+ ";";
SQLCHAR *query = (SQLCHAR *)(strqry.c_str());
// Now use query
And make sure you have control over the ipSrc value. Otherwise, you're subject to SQL injection attacks (in which case you'll want to use prepared/parameterised statements).

C++ Mysql Real Escape String Issue

Hmm, for some reason, its only doing this on the first username (and password) and does it for how big my my vector is. Any ideas on why?
int eMysql::strip(string &input) {
char* from = new char[strlen(input.c_str()) * 3 + 1];
mysql_real_escape_string(&mysql, from, input.c_str(), input.length());
input = input.assign(from);
delete from;
}
Where its used:
if(query.size() > 0) {
mysql->strip(query[0]);
mysql->strip(query[1]);
mysql->query("SELECT `username` FROM `users` where `username` = '"+ query[0] +"';");
I suggest building the query as a separate string variable rather than passing the mess in the argument:
static const char fixed_text[] = "SELECT `username` FROM `users` where `username` = '";
std::string query_text(fixed_text);
query_text += query[0];
query_text += "';";
mysql->query(query_text);
This technique allows you to examine the query before it is sent to MySql.
I suggest you examine the query[0] variable for any strange characters such as \r and \n. The MySql manual has a section listing characters that need to be escaped.