Connect to PostgreSQL server with "cert" authentication method using QSqlDatabase - qt

I need to communicate with PostgreSQL database from my Qt application, but the server uses "cert" authentication method, so I need to pass my certificates to the server.
The only solution I see for now is to obtain PGconn* like this:
QSqlDatabase db;
//.....
PGconn* conn = (PGconn*)db.driver()->handle()->data();
and do some work with it. Or even reject QSqlDatabase and use libpq directly.
Is there any other way to do this without using libpq from my code? For example, something like this:
//hypothetic QSqlDatabase methods:
QSqlDatabase db;
//.....
db.SetSslCert("/path/to/my/cert.crt");
db.SetSslKey("/path/to/my/cert.key");
//.....

I need to pass my certificates to the server.
There's no function in Qt for that because there's no equivalent function in libpq for that either. It happens automatically, as described in Client Certificates inside SSL support from libpq documentation
Excerpt:
If the server requests a trusted client certificate, libpq will send
the certificate stored in file ~/.postgresql/postgresql.crt in the
user's home directory. The certificate must be signed by one of the
certificate authorities (CA) trusted by the server. A matching private
key file ~/.postgresql/postgresql.key must also be present
(in Windows, ~/.postgresql is going to be %APPDATA%\postgresql)
The same will happen for a Qt application since the Qt's QPSQL driver is built on top of libpq. The fact that the connection uses SSL and certificates is essentially transparent even for the driver itself.
EDIT: if ~/.posgresql is not convenient as when they are multiple certificates, alternatives exist:
The location of the certificate and key files can be overridden by the
connection parameters sslcert and sslkey or the environment variables
PGSSLCERT and PGSSLKEY
The connection parameters are set through QSqlDatabase::setConnectOptions. Despite its doc mentioning only an handful of postgresql-specific parameters, it actually will accept any parameter, so anything supported by libpq will work.

Related

Unable to connect to remote MySql server in Asp.Net

I needed to connect to MYSQL databases via asp.net. I am using MySQL Connector to make connection with database but while doing this I am having this Error:
Authentication with old password no longer supported, use 4.1 style passwords.
From MySQL 4.1 and higher they use a new protocol that is not compatible with earlier versions. Which is why when you upgrade the server from an earlier version to 4.1 or higher you receive the authentication error message.
If you need to connect to the database with both clients before and after version 4.1 you must have two passwords stored. One the old way and one the new way.
You can set a users password to the new way using:
SET PASSWORD for <username> = PASSWORD('new password')
SET PASSWORD FOR 'steve'#'10.15.2.67' = PASSWORD('my secure password');
If needed you can also set passwords to the old way using:
SET PASSWORD for <username> = OLD_PASSWORD('new password')
SET PASSWORD FOR 'steve'#'10.15.2.67' = OLD_PASSWORD('my secure password');
There is a great page in the MySQL manual which will detail the process
You can actually for the server if newer than 4.1 to still use the old password method however this isn't recommended.
To do this, you can start the server with the --old-passwords option.
So, either the server has updated and you're using a old client - or you've updated your client (which now uses the new password system) and your connecting to a server below 4.1
ok but if you do not have the authorization to do this,simply because you are in a shared hosting environment:
SET PASSWORD for <username> = OLD_PASSWORD('new password')
SET PASSWORD FOR 'steve'#'10.15.2.67' = OLD_PASSWORD('my secure password');
What can you do?
I have not found a workaround and my hosting provider has changed the mysql configuration without warning...nor giving solutions.
UNCOMPLETE SOLUTION
You can force the web.config to use the old connector. It seems to work, but mysql errors occur... so I think there is a bug somewhere in the connectors.

SSL Certificate will not save

I am trying to install an SSL Certificate (from GoDaddy.com) onto IIS 7. I can add the certificate following the directions found here and it shows up in my list of Server Certificates but once I leave the Server Certificates page and return to it, the certificate no longer shows up in the list.
This certificate is also used on an Apache box to authenticate our website (I am using IIS for a WCF Service API). The certificate is assigned to *.mydomain.com so I thought I could use it for the Apache website server (www.mydomain.com) as well as my API (services.mydomain.com). Am I incorrect in this assumption? Do I need to do something different then the instructions I referenced above to install?
Brian,
I assume you just grabbed the .cer file and imported this onto your IIS box. Sadly this is not possible as your certificate will not contain a private key so it won't be an option in IIS.
The GlobalSign instruction you referenced are fine but that is if you created the CSR on the IIS server itself.
What you will have to do is to create a PFX from from your .key and .cer files from the Apache server and then you can import this PFX onto your IIS Server followed by assigning it for use.
So use this to create your PFX file;
https://support.globalsign.com/customer/portal/articles/1229676-back-up-certificate---apache-openssl
Followed by;
https://support.globalsign.com/customer/portal/articles/1217281
As for everyone else if you just have a .CER file you and did not create the request you need a private key. So create a new CSR and request a reissue from your relevant CA.
The fact you cannot assign a certificate in IIS is because you do not have a private key that corresponds to the certificate.
You have two options:
If you have access to the old machine you first created the certificate just go to that and export ".pfx" file from the certificate, then in the new machine you could easily import it and Done.
If you don't have access to the old machine, so you must reissue the SSL certificate with the help of the seller company.
Hope this help.
See how godaddy response for this case:
https://sg.godaddy.com/community/SSL-And-Security/completing-certificate-request-disappears-from-server/td-p/36299
But it doesn't work.
I tried in my way :
- Use https://www.sslshopper.com/ssl-converter.html to convert my CRT file to PFX file.
- Then go to the IIS -> Server certificates -> Import -> Choose the generated PFX file in previous step.
It worked with me.

Certificate validation failed

Actors
-Asp.net site - Client
-Wcf services - Server
Both applications runs on IIS-7.
I want to make integration test between the two applications. The client access the Server through 'https'.
I have created a certificate and assigned it to the server. I also added the certificate to the 'Trusted Root Certification Authorities' to be considered a valid certificate. When I 'hit' the server's services through my browser (IE, chrome...) the certificate appears to be valid. But when my client application tries to access the server then I get the following error:
Could not establish trust relationship for the SSL/TLS secure channel with authority **** --->
The remote certificate is invalid according to the validation procedure.
Is there any way to skip the validation procedure or to make the certificate valid for my client application?
Just to know:
1. I cannot purchase a certificate because I will only use it for testing purposes.
2. I cannot make any changes on any of the application's code (server-client)
I finally managed to figured it out.
The problem was a previous (expired) certificate with the same name that was already added to the 'Trusted Root Certification Authorities'. Every time I was installing my new certificate through the 'Certificate Import Wizard' (or through MMC) the wizard informed me that it was successfully added. However, it was keeping the instance of the previous certificate without overwriting it.
Modify the validation callback to always return true:
ServicePointManager.ServerCertificateValidationCallback += (sender, certificate, chain, policyErrors) => true;
Or does that violate the 'no changes to code' condition?
How did you install the certificate into your trusted root store?
If you went through a browser to do it, most likely you only added it to the current user. Try adding it through the MMC snap-in for the Local Computer Account instead; this is where we install our self-signed IIS Express certificates and WCF seems happy with them.

WCF Certificate Authentication without installing on the Client

Our setup includes a WCF service and a number of clients written by us. Some of the clients include Silverlight applications, whereas others include Web and Windows applications.
I (think) I would like to authenticate clients based on X.509 certificates. Typically you would install a private key on the client to encrypt (aka digitaly sign) the messages. The server can the use the clients public key to de-crypt it to ensure the message has not been changed and prove the message is from who we expect (aka authenticated).
I dont want to install a certificate on a client machine. Its a hassel to deploy, and we cant really ask our clients to do it. I was speaking to someone the other day who sugested embeding the cert in a client assembly, reading it and using that. Is that possible?
It would be great if someone could point me to an example.
Thanks in advance,
David
Yes, you can load X509certificate2 by passing a certificate byte array with a password like
var certificate = new X509Certificate2(theByteArrary, "password");
To get the certificate byte array, you can simply copy paste the contents in .pfx file, which is a combination of .cer (public key) and .pvk (private key)
and then you can load this certificate on your client by doing:
var channelFactory = new ChannelFactory<IYourService>();
channelFactory.Credentials.ClientCertificate.Certificate =
clientCertificate;
If you use auto-generated client proxy, or you prefer configure the certificate via .config file then you might want to have a look at this from codeproject
Here is a suggestion. Could also be tweaked to use an embedded certificate.
http://www.codeproject.com/KB/WCF/wcfcertificates.aspx

BizTalk SOAP port password in binding file

I've inherited a BizTalk 2006 application that uses several SOAP ports to request data from a 3rd party web service. The web service is secured by "basic" authentication - username / password. After making a few enhancements to the application I deployed to an integration test server which has access to the 3rd party web service. The BizTalk app was unable to retrieve the data and I soon realised that I had forgotten to set the username / password on the SOAP send ports. I wanted the make deployment of the BizTalk app as automated as possible because I may not be present when it is deployed to the live server. I opened up the binding file, located the 1st of the problem SOAP send ports and looked for the * that BizTalk uses to replace the password - except that it doesn't! It seems that the password for SOAP ports is set to NULL rather than *, see here for more details:
http://msdn.microsoft.com/en-us/library/aa547319.aspx
I proceeded to update the binding but when I came to test, after importing my amended binding file, I found that I had the same problem as before. I've double checked and can confirm that the correct password is now present in the binding file but, although BizTalk doesn't complain during the import, when I run the app I get the following exception:
Details:"ArgumentNullException: String reference not set to an instance of a String.
Parameter name: s
".
If I then manually amend the password through the BizTalk admin console everything work fine.
Has anyone else had a similar problem with the bindings for a SOAP port - does anyone have a solution?
I've been bit by something like this in the past. The password is either put in as '****'. This is ok. I wouldn't want all of my secrets exported with the binding file. What does get you is when you export the bindings and you leave the password NULL. The Variable Type (vt) attribute on the XML element for the password is set to vt="1" which is the same as NULL. It won't matter what you put in for the password. It may even cause the error you described. I would suggest you include a copy of the binding XML for review.
I've never seen this problem before - I'm doing exactly what you are trying to do and it works perfectly.
I've included the <TransportTypeData> element from one of my BizTalk bindings that works. Hopefully having something to compare against helps.
<TransportTypeData>
<CustomProps>
<AuthenticationScheme vt="8">Basic</AuthenticationScheme>
<AssemblyName vt="8">WebService.ProxyClass, Version=1.0.0.0,
Culture=neutral, PublicKeyToken=xyz</AssemblyName>
<Username vt="8">soapUser</Username>
<UseProxy vt="11">0</UseProxy>
<UseSoap12 vt="11">0</UseSoap12><UsingOrchestration vt="11">0</UsingOrchestration>
<UseSSO vt="11">0</UseSSO>
<Password vt="8">MYPASSWORD</Password>
<ProxyPort vt="3">80</ProxyPort><AssemblyPath
vt="8">C:\ProxyClass\bin\Debug\ProxyClass.dll</AssemblyPath>
<TypeName vt="8">ProxyClass.Webservice.servicesService</TypeName>
<MethodName vt="8">PickupRequest</MethodName>
<UseHandlerSetting vt="11">-1</UseHandlerSetting>
</CustomProps>
</TransportTypeData>

Resources