gsoap c++ android device encoding - c++

8.15,
I can connect my microsoft web service and I can insert record with this service easily.
I get a confirmation code as a response for record insert. But I have a problem with encoding. The response message must like this 1Exa9GwOIO6pP35l4TJ1Bw== but instead of this I get a response like this 4�� u #
When I try this service on a browser I get the expected response as
in 1Exa9GwOIO6pP35l4TJ1Bw==
But when I try it on an android device with gsoap I get a response such as this one 4�� u #
How can I solve this encoding problem?
TheGameSoapProxy service;
_ns1__PlayerRegisterResponse* response = new _ns1__PlayerRegisterResponse();
std::string telNO =m_pEditTel->getText();
std::string telefonIME = "111";
std::string simCardID = "222";
std::string Username = m_pEditName->getText();
std::string takim = Takim.c_str();
_ns1__PlayerRegister* ps = new _ns1__PlayerRegister();
ps->telefonNumarasi = &telNO;
ps->telefonIME = &telefonIME;
ps->simCardID = &simCardID;
ps->Username = &Username;
ps->takim = &takim;
if (service.PlayerRegister(ps, response) == SOAP_OK)
{
string *ptrSonuc = response->PlayerRegisterResult;
CCLog( (char*)ptrSonuc );
}

As per other question here on SO:
add the line below to your typemap.dat file:
xsd__string = | wchar_t* | wchar_t*
And then use wstrings instead of strings.

Related

LDAP C++ how do I check that a user has a valid password?

I am trying to figure out how to check if a user has a valid password with LDAP c++ code. This seems maddeningly difficult for what seems to be it's intended purpose.
The only working example code I could find was ldapsearch. I can log in as the default user and search for the user:
ldapsearch -x -D "cn=ldap,cn=Users,dc=company,dc=local" -W -H ldap://localhost:389 -b "ou=company_account,dc=company,dc=local" -s sub 'uid=my_id'
This seems to correspond to this code (note: lots of error checking removed)
LDAP *ld = NULL;
string sHostIP = session.ini["ldap_host"];
string sPort = session.ini["ldap_port"];
string sURL = sHostIP+":"+sPort;
ldap_initialize( &ld, sURL.c_str() );
int iVersion = LDAP_VERSION3;
ldap_set_option( ld, LDAP_OPT_PROTOCOL_VERSION, &iVersion );
string sLDAPPW = session.ini["ldap_server_pw"];
struct berval pServerPassword = { 0, NULL };
pServerPassword.bv_val = ber_strdup( &sLDAPPW[0] );
pServerPassword.bv_len = strlen( pServerPassword.bv_val );
//can't bind without this code block, but what does it even do?
int iMsgid;
int nsctrls = 0;
LDAPControl c;
c.ldctl_oid = LDAP_CONTROL_PASSWORDPOLICYREQUEST;
c.ldctl_value.bv_val = NULL;
c.ldctl_value.bv_len = 0;
c.ldctl_iscritical = 0;
LDAPControl sctrl[3];
sctrl[nsctrls] = c;
LDAPControl *sctrls[4];
sctrls[nsctrls] = &sctrl[nsctrls];
sctrls[++nsctrls] = NULL;
LDAPControl **sctrlsp = NULL;
if ( nsctrls )
{
sctrlsp = sctrls;
}
KString sBindDN = session.ini["ldap_bind_dn"];
ldap_sasl_bind( ld, sBindDN.c_str(), LDAP_SASL_SIMPLE, &pServerPassword,sctrlsp, NULL, &iMsgid );
This is where, if we kept the hashed userPassword value I could search for a uid and userPassword combination. but since my company doesn't keep userPassword, that won't work.
I'm told that the other way to check the password is to bind as the user with the user password. But I need to use a different DN so I'm binding as user? Or I log in as the admin first then do a second bind as the user? And apparently this code is depreciated, but every non-depreciated example code I try to build crashes? Is there something I'm missing? Is there a good working example I use to authenticate users? I know apache can authenticate off of this LDAP server, but I don't know how.
Apache ldap.conf info here:
AuthLDAPURL "ldap://localhost:389/ou=company_account,dc=company,dc=local?sAMAccountName?sub?(objectClass=*)"
AuthLDAPBindDN "cn=ldap,cn=Users,dc=company,dc=local"
AuthLDAPBindPassword "removed"
you need just to perform ldap bind or sasl_bind
void TLDAP::sasl_simple_bind(const std::string & ldapDn, const std::string & ldapPw)
{
struct berval c_passwd = { 0, 0 };
c_passwd.bv_val = const_cast<char*>(ldapPw.c_str());
c_passwd.bv_len = ldapPw.size();
Check(ldap_sasl_bind_s(l.get(), ldapDn.c_str(), LDAP_SASL_SIMPLE, &c_passwd, NULL, NULL, NULL));
}
void TLDAP::simple_bind(const std::string & ldapDn, const std::string & ldapPw)
{
Check(ldap_simple_bind_s(l.get(), ldapDn.c_str(), ldapPw.c_str()));
}
ldap_simple_bind for non-encrypted connection, sasl_bind for encrypted
invocation example:
TLDAP::sasl_simple_bind("andrey#mydomain.local", "1234asdf%^^&");
function Check just checks the return value and throws exception

About get event log use EvtOpenSession (Why filling the domain parameter with any text can be success?)

I need to connect to the remote server to read the event log. I use EvtOpenSession function to connect and connect successfully.
My question is: why setting the parameter of Domain to any string will connect successfully?(The actual domain is "testad.com" ex:Set Credentials.Domain = L"123"; or Credentials.Domain = NULL;)
void main()
{
const wchar_t *channelPath = L"Security";
const wchar_t *query = L"Event/System[((EventID=4728) or (EventID = 4729))]";
//Remote handle
EVT_HANDLE hRemoteHandle;
EVT_RPC_LOGIN Credentials;
RtlZeroMemory(&Credentials, sizeof(EVT_RPC_LOGIN));
wstring comp_name = L"TEST-AD"; //server name
wstring user_name = L"<username>";
wstring password = L"<password>";
Credentials.Server = &comp_name[0];
Credentials.Domain = L"testad.com"; //NULL; //L"123"; //Will be connected successfully, No matter what string is
Credentials.User = &user_name[0];
Credentials.Password = &password[0];
Credentials.Flags = EvtRpcLoginAuthNTLM;
hRemoteHandle = EvtOpenSession(EvtRpcLogin, &Credentials, 0, 0);
hResults = EvtQuery(hRemoteHandle , channelPath, query, EvtQueryChannelPath|
EvtQueryForwardDirection);
}

How can I issue a POST request that contains a basic authentication header, and a JSON body?

I am trying to use the CPPRESTSDK (a.k.a. Casablanca) to POST data to a RESTful server. To do this, I create a request, and assign a header:
// create request, and add header information
web::http::http_request req(methods::POST);
req.headers().add(header_names::authorization, authStr); // authStr is base64 representation of username & password
req.headers().add(header_names::content_type, http::details::mime_types::application_json);
Next, I make a web::json::value object that contains all the key-value pairs:
web::json::value obj = json::value::object();
obj[U("Key1")] = web::json::value::string(U("Val1")];
obj[U("Key2")] = web::json::value::string(U("Val2")];
obj[U("Key3")] = web::json::value::string(U("Val3")];
I then store this object in the request's body by calling:
req.set_body(obj);
Finally, I send the request to the server using an http_client:
// create http client
web::http::client::http_client client(addr); // addr is wstring
return client.request(req).then([](http_response response) {
return response;
});
The problem is that this doesn't do anything. If I place a breakpoint on this line, I get information about "400 Bad Request." I would assume that the request's body is somehow malformed, but it could also be that I am missing some information in the header. This error does not happen when I issue a GET request on the same URL, so it is definitely a problem with POSTs specifically. What do you think?
Here is a working example:
// create a new channel
pplx::task<web::http::http_response> postChannel(http_client client, std::wstring authStr, std::wstring cDesc, std::wstring cName, std::string cDiagCap, int cNormFloat, int cWriteDuty,
int cWriteMeth, std::string cItemPersist, std::wstring cItemPersistDat) {
// create request
http_request req(methods::POST);
req.headers().add(header_names::authorization, authStr);
std::wstring url = L"/config/v1/project/channels";
req.set_request_uri(url);
json::value obj = json::value::object();
obj[U("common.ALLTYPES_DESCRIPTION")] = json::value::string(cDesc);
obj[U("common.ALLTYPES_NAME")] = json::value::string(cName);
obj[U("servermain.CHANNEL_DIAGNOSTICS_CAPTURE")] = json::value(cDiagCap == "true" || cDiagCap == "t");
obj[U("servermain.CHANNEL_NON_NORMALIZED_FLOATING_POINT_HANDLING")] = json::value(cNormFloat);
obj[U("servermain.CHANNEL_WRITE_OPTIMIZATIONS_DUTY_CYCLE")] = json::value(cWriteDuty);
obj[U("servermain.CHANNEL_WRITE_OPTIMIZATIONS_METHOD")] = json::value(cWriteMeth);
obj[U("servermain.MULTIPLE_TYPES_DEVICE_DRIVER")] = json::value::string(U("Simulator")); // right now, Simulator channels are the only option
obj[U("simulator.CHANNEL_ITEM_PERSISTENCE")] = json::value(cItemPersist == "true" || cItemPersist == "t");
obj[U("simulator.CHANNEL_ITEM_PERSISTENCE_DATA_FILE")] = json::value::string(cItemPersistDat);
req.set_body(obj);
return client.request(req).then([](http_response response) {
return response;
});
}

Unable to pass username & password in jaxws

I'm trying to call a webservice using username/pwd using the below client but I don't see the username/password being set in the headers
Client code
AttachmentWSImplService service = new AttachmentWSImplService();
AttachmentWS aws = service.getAttachmentWS();
BindingProvider bindingProvider = (BindingProvider) aws;
SOAPBinding sopadBinding = (SOAPBinding) bindingProvider.getBinding();
sopadBinding.setMTOMEnabled(true);
bindingProvider.getRequestContext().put(bindingProvider.USERNAME_PROPERTY,"p3xferdt");
bindingProvider.getRequestContext().put(bindingProvider.PASSWORD_PROPERTY,"92mnGg1Cb14D9hVhG1W5fZra4UI=");
Server code
SOAPMessageContext ctx = (SOAPMessageContext) wsCtx
.getMessageContext();
java.util.Map<java.lang.String, java.util.List<java.lang.String>> headers = (Map<String, List<String>>) ctx
.get(MessageContext.HTTP_REQUEST_HEADERS);
if (headers.keySet() != null && !headers.keySet().isEmpty()) {
Iterator<String> keys = headers.keySet().iterator();
while (keys.hasNext()) {
String key = (String) keys.next();
logger.info("HeaderKey->" + key);
logger.info("Header values->" + headers.get(key));
// getting Basic Authentication
String tmpusername = getUsernameFromAuthentication(key,
headers.get(key).toString());
Code looks ok to me, should work fine.
Anyways try accessing Request Header by
Headers headers = ex.getRequestHeaders();
List<String> ulist = headers.get(BindingProvider.USERNAME_PROPERTY);
List<String> plist = headers.get(BindingProvider.PASSWORD_PROPERTY);
PS: Remember USERNAME_PROPERTY is static string from BindingProvider interface, can be accessed in Static way. (Coding standards :))

Why does SQL Server CLR procedure hang in GetResponse() call to web service

Environment: C#, .Net 3.5, Sql Server 2005
I have a method that works in a stand-alone C# console application project. It creates an XMLElement from data in the database and uses a private method to send it to a web service on our local network. When run from VS in this test project, it runs in < 5 seconds.
I copied the class into a CLR project, built it, and installed it in SQL Server (WITH PERMISSION_SET = EXTERNAL_ACCESS). The only difference is the SqlContext.Pipe.Send() calls that I added for debugging.
I am testing it by using an EXECUTE command one stored procedure (in the CLR) from an SSMS query window. It never returns. When I stop execution of the call after a minute, the last thing displayed is "Calling GetResponse() using http://servername:53694/odata.svc/Customers/". Any ideas as to why the GetResponse() call doesn't return when executing within SQL Server?
private static string SendPost(XElement entry, SqlString url, SqlString entityName)
{
// Send the HTTP request
string serviceURL = url.ToString() + entityName.ToString() + "/";
HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(serviceURL);
request.Method = "POST";
request.Accept = "application/atom+xml,application/xml";
request.ContentType = "application/atom+xml";
request.Timeout = 20000;
request.Proxy = null;
using (var writer = XmlWriter.Create(request.GetRequestStream()))
{
entry.WriteTo(writer);
}
try
{
SqlContext.Pipe.Send("Calling GetResponse() using " + request.RequestUri);
WebResponse response = request.GetResponse();
SqlContext.Pipe.Send("Back from GetResponse()");
/*
string feedData = string.Empty;
Stream stream = response.GetResponseStream();
using (StreamReader streamReader = new StreamReader(stream))
{
feedData = streamReader.ReadToEnd();
}
*/
HttpStatusCode StatusCode = ((HttpWebResponse)response).StatusCode;
response.Close();
if (StatusCode == HttpStatusCode.Created /* 201 */ )
{
return "Created # Location= " + response.Headers["Location"];
}
return "Creation failed; StatusCode=" + StatusCode.ToString();
}
catch (WebException ex)
{
return ex.Message.ToString();
}
finally
{
if (request != null)
request.Abort();
}
}
The problem turned out to be the creation of the request content from the XML. The original:
using (var writer = XmlWriter.Create(request.GetRequestStream()))
{
entry.WriteTo(writer);
}
The working replacement:
using (Stream requestStream = request.GetRequestStream())
{
using (var writer = XmlWriter.Create(requestStream))
{
entry.WriteTo(writer);
}
}
You need to dispose the WebResponse. Otherwise, after a few calls it goes to timeout.
You are asking for trouble doing this in the CLR. And you say you are calling this from a trigger? This belongs in the application tier.
Stuff like this is why when the CLR functionality came out, DBAs were very concerned about how it would be misused.