Couldn't resolve host Error from curl on NACL - google-chrome

im new to nacl. In my application i have use native curl. I checked out curl through nacl port. im getting "Couldn't resolve host name" error.
Any help will be appriciated.
Below is the example code :
hello_tutorial.cc :
// Copyright (c) 2013 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include <unistd.h>
#include <stdio.h>
#include <sys/socket.h>
#include <sys/ioctl.h>
#include "nacl_io/nacl_io.h"
#include "ppapi/cpp/instance.h"
#include "ppapi/cpp/module.h"
#include "ppapi/cpp/var.h"
#include "ppapi/utility/completion_callback_factory.h"
#include "ppapi/utility/threading/simple_thread.h"
#include "curl/curl.h"
namespace {
// The expected string sent by the browser.
const char* const kHelloString = "hello";
// The string sent back to the browser upon receipt of a message
// containing "hello".
const char* const kReplyString = "hello from NaCl";
} // namespace
class HelloTutorialInstance : public pp::Instance {
public:
explicit HelloTutorialInstance(PP_Instance instance)
: pp::Instance(instance),
callback_factory_(this),
file_thread_(this){}
virtual ~HelloTutorialInstance() {}
int download_progress_callback(void *clientp, double dltotal, double dlnow, double ultotal, double ulnow) {
fprintf(stderr, "### Progress : %f : %f : %f", dlnow/dltotal, dlnow, dltotal);
return 0;
}
int download_callback(char *buffer, size_t size, size_t nitems, void *outstream) {
static int downloadSize = 0;
downloadSize += (size * nitems);
fprintf(stderr, "SIZE : %d", downloadSize);
return nitems * size;
}
void curlTest(int32_t /* result */)
{
CURLM *multiCurlHandle = NULL;
CURL *curlHandle = NULL;
int res = curl_global_init(CURL_GLOBAL_ALL);
if (res == CURLE_OK) {
multiCurlHandle = curl_multi_init();
curlHandle = curl_easy_init();
curl_easy_setopt(curlHandle, CURLOPT_URL, "www.google.com");
curl_easy_setopt(curlHandle, CURLOPT_VERBOSE, 1);
curl_easy_setopt(curlHandle, CURLOPT_NOPROGRESS, 0);
curl_easy_setopt(curlHandle, CURLOPT_PROGRESSFUNCTION ,&HelloTutorialInstance::download_progress_callback);
curl_easy_setopt(curlHandle, CURLOPT_WRITEFUNCTION, &HelloTutorialInstance::download_callback);
res = curl_easy_perform(curlHandle);
//curl_multi_add_handle(multiCurlHandle, curlHandle);
//curl_multi_perform(multiCurlHandle, &handle_count);
if (CURLE_OK != res) {
fprintf(stderr, "curl_easy_perform failed !!\nReason : %s", curl_easy_strerror((CURLcode)res));
}
} }
virtual void HandleMessage(const pp::Var& var_message) {
// Ignore the message if it is not a string.
if (!var_message.is_string())
return;
// Get the string message and compare it to "hello".
std::string message = var_message.AsString();
if (message == kHelloString) {
// If it matches, send our response back to JavaScript.
pp::Var var_reply(kReplyString);
nacl_io_init_ppapi(pp::Instance::pp_instance(),pp::Module::Get()->get_browser_interface());
file_thread_.Start();
file_thread_.message_loop().PostWork(
callback_factory_.NewCallback(&HelloTutorialInstance::curlTest));
PostMessage(var_reply);
}
}
private:
pp::CompletionCallbackFactory<HelloTutorialInstance> callback_factory_;
pp::SimpleThread file_thread_;
};
class HelloTutorialModule : public pp::Module {
public:
HelloTutorialModule() : pp::Module() {}
virtual ~HelloTutorialModule() {}
virtual pp::Instance* CreateInstance(PP_Instance instance) {
return new HelloTutorialInstance(instance);
}
};
namespace pp {
Module* CreateModule() {
return new HelloTutorialModule();
}
} // namespace pp
makefile :
# Copyright (c) 2013 The Chromium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
# GNU Makefile based on shared rules provided by the Native Client SDK.
# See README.Makefiles for more details.
VALID_TOOLCHAINS := pnacl newlib glibc
NACL_SDK_ROOT ?= $(abspath $(CURDIR)/../..)
TARGET = part2
include $(NACL_SDK_ROOT)/tools/common.mk
CHROME_ARGS += --allow-nacl-socket-api=localhost
LIBS = ppapi_cpp ppapi pthread nacl_io curl ssl crypto stdc++ z glibc-compat
CFLAGS = -Wall
SOURCES = hello_tutorial.cc
# Build rules generated by macros from common.mk:
$(foreach src,$(SOURCES),$(eval $(call COMPILE_RULE,$(src),$(CFLAGS))))
# The PNaCl workflow uses both an unstripped and finalized/stripped binary.
# On NaCl, only produce a stripped binary for Release configs (not Debug).
ifneq (,$(or $(findstring pnacl,$(TOOLCHAIN)),$(findstring Release,$(CONFIG))))
$(eval $(call LINK_RULE,$(TARGET)_unstripped,$(SOURCES),$(LIBS),$(DEPS)))
$(eval $(call STRIP_RULE,$(TARGET),$(TARGET)_unstripped))
else
$(eval $(call LINK_RULE,$(TARGET),$(SOURCES),$(LIBS),$(DEPS)))
endif
$(eval $(call NMF_RULE,$(TARGET),))
Execution in terminal :
part2$ NACL_SDK_ROOT=~/nacl_sdk/pepper_40 NACL_ARCH=x86_64 TOOLCHAIN=newlib make clean run
~/nacl_sdk/pepper_40/tools/common.mk:495: Using chrome at: /Applications/Google Chrome.app/Contents/MacOS/Google Chrome
CXX newlib/Release/hello_tutorial_x86_64.o
LINK newlib/Release/part2_unstripped_x86_64.nexe
VALIDATE newlib/Release/part2_unstripped_x86_64.nexe
STRIP newlib/Release/part2_x86_64.nexe
CREATE_NMF newlib/Release/part2.nmf
python ~/nacl_sdk/pepper_40/tools/run.py -C ~/nacl_sdk/pepper_40/getting_started/part2 -P "index.html?tc=newlib&config=Release" \
-- /Applications/Google\ Chrome.app/Contents/MacOS/Google\ Chrome \
--enable-nacl --enable-pnacl --no-first-run --user-data-dir=~/nacl_sdk/pepper_40/getting_started/part2/user-data-dir --allow-nacl-socket-api=localhost \
--register-pepper-plugins="~/nacl_sdk/pepper_40/getting_started/part2/mac/Debug/part2.so;application/x-ppapi-debug~nacl_sdk/pepper_40/getting_started/part2/mac/Release/part2.so;application/x-ppapi-release"
Serving ~/nacl_sdk/pepper_40/getting_started/part2 on http://localhost:5103/...
Running: /Applications/Google Chrome.app/Contents/MacOS/Google Chrome --enable-nacl --enable-pnacl --no-first-run --user-data-dir=~/nacl_sdk/pepper_40/getting_started/part2/user-data-dir --allow-nacl-socket-api=localhost --register-pepper-plugins=~/nacl_sdk/pepper_40/getting_started/part2/mac/Debug/part2.so;application/x-ppapi-debug,~/nacl_sdk/pepper_40/getting_started/part2/mac/Release/part2.so;application/x-ppapi-release http://localhost:5103/index.html?tc=newlib&config=Release...
Output :
127.0.0.1 - - [10/Apr/2015 15:05:26] "GET /index.html?tc=newlib&config=Release HTTP/1.1" 200 -
127.0.0.1 - - [10/Apr/2015 15:05:26] "GET /common.js HTTP/1.1" 200 -
127.0.0.1 - - [10/Apr/2015 15:05:26] "GET /example.js HTTP/1.1" 200 -
127.0.0.1 - - [10/Apr/2015 15:05:26] "GET /newlib/Release/part2.nmf HTTP/1.1" 200 -
127.0.0.1 - - [10/Apr/2015 15:05:26] "GET /newlib/Release/part2_x86_64.nexe HTTP/1.1" 200 -
127.0.0.1 - - [10/Apr/2015 15:05:26] code 404, message File not found
127.0.0.1 - - [10/Apr/2015 15:05:26] "GET /favicon.ico HTTP/1.1" 404 -
[43852,1925374720:15:05:26.885906] Native Client module will be loaded at base address 0x000052a200000000
* Rebuilt URL to: www.google.com/
* timeout on name lookup is not supported
* Hostname was NOT found in DNS cache
* Curl_ipv4_resolve_r failed for www.google.com
* Couldn't resolve host 'www.google.com'
* Closing connection 0
curl_easy_perform failed !!
Reason : Couldn't resolve host name

I managed to get the example working (at least resolving host names)
by changing the LIBS line the Makefile. I removed glibc-compat
and moved nacl_io to the end of the line:
LIBS = ppapi_cpp ppapi pthread curl ssl crypto z nacl_io
The reason it was required is that glibc-compat contains a lot of
stub/dummy/non-working functions whereas nacl_io contains working
implemenations.
-Thanks to Sam (from native google groups) for pointing this

I'm trying to build curl with pepper_49 but there's still some problems when building
Makefile:
LIBS = ppapi_cpp ppapi pthread curl ssl crypto z nacl_io
build with TOOLCHAIN=pnacl make clean run
/Users/fu/nacl_sdk/pepper_49/tools/common.mk:500: Using chrome at: /Applications/Google Chrome.app/Contents/MacOS/Google Chrome
CXX pnacl/Release/hello_tutorial.o
LINK pnacl/Release/curltest_unstripped.bc
/Users/fu/nacl_sdk/pepper_49/toolchain/mac_pnacl/le32-nacl/usr/lib/libcurl.a: error: undefined reference to 'alarm'
make: *** [pnacl/Release/curltest_unstripped.bc] Error 1
It resolved after I changed Makefile to
LIBS = ppapi_cpp ppapi pthread curl ssl crypto z glibc-compat nacl_io
and the example works fine.

Related

error while connecting mariadb with c : undefined reference to `mysql_init#4'

I am trying to connect to mariadb database using c program. Initially it was showing error for #include <mysql.h> as no such file or directory.
But after including directory name, that problem is solved now, but it is showing another error.
Following is the code I was trying to run:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
// #include "C:/Program Files/MariaDB 10.11/include/mysql/my_global.h"
#include "mysql/mysql.h"
int main (int argc, char* argv[])
{
// Initialize Connection
MYSQL *conn;
if (!(conn = mysql_init(0)))
{
fprintf(stderr, "unable to initialize connection struct\n");
exit(1);
}
// Connect to the database
if (!mysql_real_connect(
conn, // Connection
"mariadb.example.net", // Host
"db_user", // User account
"db_user_password", // User password
"test", // Default database
3306, // Port number
NULL, // Path to socket file
0 // Additional options
));
{
// Report the failed-connection error & close the handle
fprintf(stderr, "Error connecting to Server: %s\n", mysql_error(conn));
mysql_close(conn);
exit(1);
}
// Use the Connection
// ...
// Close the Connection
mysql_close(conn);
return 0;
}
I am getting following error in output:
PS C:\Dev\Win> gcc Db_con.c -o Db_con
C:\Users\hajos\AppData\Local\Temp\ccGZ2Rhz.o:Db_con.c:(.text+0x1e): undefined reference to `mysql_init#4'
C:\Users\hajos\AppData\Local\Temp\ccGZ2Rhz.o:Db_con.c:(.text+0xa1): undefined reference to `mysql_real_connect#32'
C:\Users\hajos\AppData\Local\Temp\ccGZ2Rhz.o:Db_con.c:(.text+0xaf): undefined reference to `mysql_error#4'
C:\Users\hajos\AppData\Local\Temp\ccGZ2Rhz.o:Db_con.c:(.text+0xd9): undefined reference to `mysql_close#4'
collect2.exe: error: ld returned 1 exit status
Can anyone explain what is the problem and how to solve it?
You have to link against the MariaDB Connector/C libraries.
From MariaDB Connector/C documentation:
Linking your application against MariaDB Connector/C
Windows
For static linking the library libmariadb.lib is required, for dynamic linking use libmariadb.dll. Using the MSI installer, these libraries can be found in the lib directory of your MariaDB Connector/C installation.
Unless you use the experimental plugin remote_io (which requires the curl library) there are no dependencies to other libraries than the Windows system libraries.

SIM800L GSM Module working with http and shows error with https, why?

I'm trying to send some sensor data to MySQL database using Arduino and sim800l GSM module. And it's working perfectly when I use HTTP for the URL and remove the SSL certificate from my website. But when I have enabled the SSL certificate on my website it shows HTTP response code 606 in the serial monitor.
Here is my working code without SSL certificate(this code works perfectly)
#include <SoftwareSerial.h>
SoftwareSerial gprsSerial(3, 2);
void setup()
{
gprsSerial.begin(19200);
Serial.begin(19200);
Serial.println("Config SIM900...");
delay(2000);
Serial.println("Done!...");
gprsSerial.flush();
Serial.flush();
// attach or detach from GPRS service
gprsSerial.println("AT+CGATT?");
delay(100);
toSerial();
// bearer settings
gprsSerial.println("AT+SAPBR=3,1,\"CONTYPE\",\"GPRS\"");
delay(2000);
toSerial();
// bearer settings
gprsSerial.println("AT+SAPBR=3,1,\"APN\",\"myapn\"");
delay(2000);
toSerial();
// bearer settings
gprsSerial.println("AT+SAPBR=0,1");
delay(2000);
gprsSerial.println("AT+SAPBR=1,1");
delay(2000);
toSerial();
}
void loop()
{
// initialize http service
gprsSerial.println("AT+HTTPINIT");
delay(2000);
toSerial();
// set http param value
gprsSerial.println("AT+HTTPPARA=\"URL\",\"http://www.website123456.com/data/index.php?data1=2.88&data2=2.93\"");
delay(20000);
toSerial();
// set http action type 0 = GET, 1 = POST, 2 = HEAD
gprsSerial.println("AT+HTTPACTION=0");
delay(6000);
toSerial();
// read server response
gprsSerial.println("AT+HTTPREAD");
delay(10000);
toSerial();
gprsSerial.println("");
gprsSerial.println("AT+HTTPTERM");
toSerial();
delay(300);
gprsSerial.println("");
delay(10000);
}
void toSerial()
{
while(gprsSerial.available()!=0)
{
Serial.write(gprsSerial.read());
}
}
Here is the output when I replace the URL with https and enable my website ssl. (as you can see it shows http response code 606 "Not Acceptable
The user's agent was contacted successfully but some aspects of the session description such as the requested media, bandwidth, or addressing style were not acceptable"
23:16:48.974 -> Config SIM800L...
23:16:50.946 -> Done!...
23:16:51.079 -> AT+CGATT?
23:16:51.079 -> +CGATT: 1
23:16:51.079 ->
23:16:51.079 -> OK
23:16:53.107 -> AT+SAPBR=3,1,"CONTYPE","GPRS"
23:16:53.107 -> OK
23:16:55.100 -> AT+SAPBR=3,1,"APN","dialogbb"
23:16:55.133 -> OK
23:16:59.122 -> AT+SAPBR=0,1
23:16:59.155 -> OK
23:16:59.155 -> AT+SAPBR=1,1
23:17:01.151 -> OK
23:17:03.185 -> AT+HTTPPARA="URL","https://www.mywebsitttte.com/index.php?dAT+HTTPSSL=1
23:17:08.207 -> OK
23:17:14.221 -> AT+HTTPACTION=0
23:17:14.255 -> OK
23:17:14.255 ->
23:17:14.255 -> +HTTPACTION: 0,606,0
23:17:24.266 -> AT+HTTPREAD
23:17:24.266 -> OK
23:17:36.595 ->
AT+HTTPTERM
23:17:36.595 -> OK
So what are the modifications I should do to this code, to be able to upload data to the website with SSL certificate? I have seen people say I need to enter to SSL mode using this code AT+HTTPSSL=1 where should I put this code. Thanks
I have figured out it finally, It happens because this sim800 only supports TLS 1.0. But it's a deprecated version and many websites and host services have disabled it. You can check your server SSL version from here cdn77.com/tls-test
Check your SIM800 firmware first, I had old firmware on my 808 module that had no SSL and I only bought it a few weeks ago. you can check using this AT command:
AT+HTTPSSL=?
If you get error then check and update the firmware.
Otherwise if working this is the order I use:
client.println("AT+HTTPINIT");
getresponse();
delay(1000);
client.println("AT+HTTPSSL=1"); // set SSL for HTTPS
getresponse();
delay(1000);
client.println("AT+HTTPPARA=\"CID\",1");
getresponse();
delay(1000);
I can reliably HTTPS connect to my Firebase database.

JDBC: SunCertPathBuilderException: unable to find valid certification path to requested target [duplicate]

I have a class that will download a file from a https server. When I run it, it returns a lot of errors. It seems that I have a problem with my certificate. Is it possible to ignore the client-server authentication? If so, how?
package com.da;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.CharBuffer;
import java.util.concurrent.Future;
import org.apache.http.HttpResponse;
import org.apache.http.client.utils.URIUtils;
import org.apache.http.impl.nio.client.DefaultHttpAsyncClient;
import org.apache.http.nio.IOControl;
import org.apache.http.nio.client.HttpAsyncClient;
import org.apache.http.nio.client.methods.AsyncCharConsumer;
import org.apache.http.nio.client.methods.HttpAsyncGet;
import org.apache.http.nio.client.methods.HttpAsyncPost;
public class RSDDownloadFile {
static FileOutputStream fos;
public void DownloadFile(String URI, String Request) throws Exception
{
java.net.URI uri = URIUtils.createURI("https", "176.66.3.69:6443", -1, "download.aspx",
"Lang=EN&AuthToken=package", null);
System.out.println("URI Query: " + uri.toString());
HttpAsyncClient httpclient = new DefaultHttpAsyncClient();
httpclient.start();
try {
Future<Boolean> future = httpclient.execute(
new HttpAsyncGet(uri),
new ResponseCallback(), null);
Boolean result = future.get();
if (result != null && result.booleanValue()) {
System.out.println("\nRequest successfully executed");
} else {
System.out.println("Request failed");
}
}
catch(Exception e){
System.out.println("[DownloadFile] Exception: " + e.getMessage());
}
finally {
System.out.println("Shutting down");
httpclient.shutdown();
}
System.out.println("Done");
}
static class ResponseCallback extends AsyncCharConsumer<Boolean> {
#Override
protected void onResponseReceived(final HttpResponse response) {
System.out.println("Response: " + response.getStatusLine());
System.out.println("Header: " + response.toString());
try {
//if(response.getStatusLine().getStatusCode()==200)
fos = new FileOutputStream( "Response.html" );
}catch(Exception e){
System.out.println("[onResponseReceived] Exception: " + e.getMessage());
}
}
#Override
protected void onCharReceived(final CharBuffer buf, final IOControl ioctrl) throws IOException {
try
{
while (buf.hasRemaining())
{
//System.out.print(buf.get());
fos.write(buf.get());
}
}catch(Exception e)
{
System.out.println("[onCharReceived] Exception: " + e.getMessage());
}
}
#Override
protected void onCleanup() {
try
{
if(fos!=null)
fos.close();
}catch(Exception e){
System.out.println("[onCleanup] Exception: " + e.getMessage());
}
System.out.println("onCleanup()");
}
#Override
protected Boolean buildResult() {
return Boolean.TRUE;
}
}
}
Errors:
URI Query: https://176.66.3.69:6443/download.aspx?Lang=EN&AuthToken=package
Aug 2, 2011 3:47:57 PM org.apache.http.impl.nio.client.NHttpClientProtocolHandler exception
SEVERE: I/O error: General SSLEngine problem
javax.net.ssl.SSLHandshakeException: General SSLEngine problem
at com.sun.net.ssl.internal.ssl.Handshaker.checkThrown(Unknown Source)
at com.sun.net.ssl.internal.ssl.SSLEngineImpl.checkTaskThrown(Unknown Source)
at com.sun.net.ssl.internal.ssl.SSLEngineImpl.writeAppRecord(Unknown Source)
at com.sun.net.ssl.internal.ssl.SSLEngineImpl.wrap(Unknown Source)
at javax.net.ssl.SSLEngine.wrap(Unknown Source)
at org.apache.http.impl.nio.reactor.SSLIOSession.doHandshake(SSLIOSession.java:154)
at org.apache.http.impl.nio.reactor.SSLIOSession.isAppInputReady(SSLIOSession.java:276)
at org.apache.http.impl.nio.client.InternalClientEventDispatch.inputReady(InternalClientEventDispatch.java:79)
at org.apache.http.impl.nio.reactor.BaseIOReactor.readable(BaseIOReactor.java:161)
at org.apache.http.impl.nio.reactor.AbstractIOReactor.processEvent(AbstractIOReactor.java:335)
at org.apache.http.impl.nio.reactor.AbstractIOReactor.processEvents(AbstractIOReactor.java:315)
at org.apache.http.impl.nio.reactor.AbstractIOReactor.execute(AbstractIOReactor.java:275)
at org.apache.http.impl.nio.reactor.BaseIOReactor.execute(BaseIOReactor.java:104)
at org.apache.http.impl.nio.reactor.AbstractMultiworkerIOReactor$Worker.run(AbstractMultiworkerIOReactor.java:542)
at java.lang.Thread.run(Unknown Source)
Caused by: javax.net.ssl.SSLHandshakeException: General SSLEngine problem
at com.sun.net.ssl.internal.ssl.Alerts.getSSLException(Unknown Source)
at com.sun.net.ssl.internal.ssl.SSLEngineImpl.fatal(Unknown Source)
at com.sun.net.ssl.internal.ssl.Handshaker.fatalSE(Unknown Source)
at com.sun.net.ssl.internal.ssl.Handshaker.fatalSE(Unknown Source)
at com.sun.net.ssl.internal.ssl.ClientHandshaker.serverCertificate(Unknown Source)
at com.sun.net.ssl.internal.ssl.ClientHandshaker.processMessage(Unknown Source)
at com.sun.net.ssl.internal.ssl.Handshaker.processLoop(Unknown Source)
at com.sun.net.ssl.internal.ssl.Handshaker$1.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at com.sun.net.ssl.internal.ssl.Handshaker$DelegatedTask.run(Unknown Source)
at org.apache.http.impl.nio.reactor.SSLIOSession.doHandshake(SSLIOSession.java:180)
... 9 more
Caused by: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
at sun.security.validator.PKIXValidator.doBuild(Unknown Source)
at sun.security.validator.PKIXValidator.engineValidate(Unknown Source)
at sun.security.validator.Validator.validate(Unknown Source)
at com.sun.net.ssl.internal.ssl.X509TrustManagerImpl.checkServerTrusted(Unknown Source)
at com.sun.net.ssl.internal.ssl.JsseX509TrustManager.checkServerTrusted(Unknown Source)
... 16 more
Caused by: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
at sun.security.provider.certpath.SunCertPathBuilder.engineBuild(Unknown Source)
at java.security.cert.CertPathBuilder.build(Unknown Source)
... 21 more
onCleanup()
[DownloadFile] Exception: javax.net.ssl.SSLHandshakeException: General SSLEngine problem
Shutting down
Done
The problem appears when your server has self signed certificate. To workaround it you can add this certificate to the list of trusted certificates of your JVM.
In this article author describes how to fetch the certificate from your browser and add it to cacerts file of your JVM. You can either edit JAVA_HOME/jre/lib/security/cacerts file or run you application with -Djavax.net.ssl.trustStore parameter. Verify which JDK/JRE you are using too as this is often a source of confusion.
See also: How are SSL certificate server names resolved/Can I add alternative names using keytool? If you run into java.security.cert.CertificateException: No name matching localhost found exception.
Here's what reliably works for me on macOS. Make sure to replace example.com and 443 with the actual hostname and port you're trying to connect to, and give a custom alias. The first command downloads the provided certificate from the remote server and saves it locally in x509 format. The second command loads the saved certificate into Java's SSL trust store.
openssl x509 -in <(openssl s_client -connect example.com:443 -prexit 2>/dev/null) -out ~/example.crt
sudo keytool -importcert -file ~/example.crt -alias example -keystore $(/usr/libexec/java_home)/jre/lib/security/cacerts -storepass changeit
I had the same issue with a valid signed wildcard certificate from symantec.
First try running your java application with -Djavax.net.debug=SSL to see what is really going on.
I ended up importing the intermediate certificate which was causing the cert chain to break.
I downloaded the missing intermediate cert from symantec (you can see the download link to the missing cert in the ssl handshake log: http://svrintl-g3-aia.verisign.com/SVRIntlG3.cer in my case).
And I imported the cert in the java keystore. After importing the intermediate certificate my wildcard ssl cert finally started working:
keytool -import -keystore ../jre/lib/security/cacerts -trustcacerts -alias "VeriSign Class 3 International Server CA - G3" -file /pathto/SVRIntlG3.cer
Export the SSL certificate using Firefox. You can export it by hitting the URL in the browser and then select the option to export the certificate. Let's assume the cert file name is your.ssl.server.name.crt
Go to your JRE_HOME/bin or JDK/JRE/bin
Type the command
keytool -keystore ..\lib\security\cacerts -import -alias your.ssl.server.name -file .\relative-path-to-cert-file\your.ssl.server.name.crt
Restart your Java process
#Gabe Martin-Dempesy's answer is helped to me. And I wrote a small script related to it. The usage is very simple.
Install a certificate from host:
> sudo ./java-cert-importer.sh example.com
Remove the certificate that installed already.
> sudo ./java-cert-importer.sh example.com --delete
java-cert-importer.sh
#!/usr/bin/env bash
# Exit on error
set -e
# Ensure script is running as root
if [ "$EUID" -ne 0 ]
then echo "WARN: Please run as root (sudo)"
exit 1
fi
# Check required commands
command -v openssl >/dev/null 2>&1 || { echo "Required command 'openssl' not installed. Aborting." >&2; exit 1; }
command -v keytool >/dev/null 2>&1 || { echo "Required command 'keytool' not installed. Aborting." >&2; exit 1; }
# Get command line args
host=$1; port=${2:-443}; deleteCmd=${3:-${2}}
# Check host argument
if [ ! ${host} ]; then
cat << EOF
Please enter required parameter(s)
usage: ./java-cert-importer.sh <host> [ <port> | default=443 ] [ -d | --delete ]
EOF
exit 1
fi;
if [ "$JAVA_HOME" ]; then
javahome=${JAVA_HOME}
elif [[ "$OSTYPE" == "linux-gnu" ]]; then # Linux
javahome=$(readlink -f $(which java) | sed "s:bin/java::")
elif [[ "$OSTYPE" == "darwin"* ]]; then # Mac OS X
javahome="$(/usr/libexec/java_home)/jre"
fi
if [ ! "$javahome" ]; then
echo "WARN: Java home cannot be found."
exit 1
elif [ ! -d "$javahome" ]; then
echo "WARN: Detected Java home does not exists: $javahome"
exit 1
fi
echo "Detected Java Home: $javahome"
# Set cacerts file path
cacertspath=${javahome}/lib/security/cacerts
cacertsbackup="${cacertspath}.$$.backup"
if ( [ "$deleteCmd" == "-d" ] || [ "$deleteCmd" == "--delete" ] ); then
sudo keytool -delete -alias ${host} -keystore ${cacertspath} -storepass changeit
echo "Certificate is deleted for ${host}"
exit 0
fi
# Get host info from user
#read -p "Enter server host (E.g. example.com) : " host
#read -p "Enter server port (Default 443) : " port
# create temp file
tmpfile="/tmp/${host}.$$.crt"
# Create java cacerts backup file
cp ${cacertspath} ${cacertsbackup}
echo "Java CaCerts Backup: ${cacertsbackup}"
# Get certificate from speficied host
openssl x509 -in <(openssl s_client -connect ${host}:${port} -prexit 2>/dev/null) -out ${tmpfile}
# Import certificate into java cacerts file
sudo keytool -importcert -file ${tmpfile} -alias ${host} -keystore ${cacertspath} -storepass changeit
# Remove temp certificate file
rm ${tmpfile}
# Check certificate alias name (same with host) that imported successfully
result=$(keytool -list -v -keystore ${cacertspath} -storepass changeit | grep "Alias name: ${host}")
# Show results to user
if [ "$result" ]; then
echo "Success: Certificate is imported to java cacerts for ${host}";
else
echo "Error: Something went wrong";
fi;
Quoting from No more 'unable to find valid certification path to requested target'
when trying to open an SSL connection to a host using JSSE. What this usually means is that the server is using a test certificate (possibly generated using keytool) rather than a certificate from a well known commercial Certification Authority such as Verisign or GoDaddy. Web browsers display warning dialogs in this case, but since JSSE cannot assume an interactive user is present it just throws an exception by default.
Certificate validation is a very important part of SSL security, but I am not writing this entry to explain the details. If you are interested, you can start by reading the Wikipedia blurb. I am writing this entry to show a simple way to talk to that host with the test certificate, if you really want to.
Basically, you want to add the server's certificate to the KeyStore with your trusted certificates
Try the code provided there. It might help.
This solved my issue,
We need to import the cert onto the local java. If not we could get the below exception.
javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
at sun.security.ssl.Alerts.getSSLException(Alerts.java:192)
at sun.security.ssl.SSLSocketImpl.fatal(SSLSocketImpl.java:1949)
at sun.security.ssl.Handshaker.fatalSE(Handshaker.java:302)
SSLPOKE is a tool where you can test the https connectivity from your local machine.
Command to test the connectivity:
"%JAVA_HOME%/bin/java" SSLPoke <hostname> 443
sun.security.validator.ValidatorException: PKIX path building failed:
sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
at sun.security.validator.PKIXValidator.doBuild(PKIXValidator.java:387)
at sun.security.validator.PKIXValidator.engineValidate(PKIXValidator.java:292)
at sun.security.validator.Validator.validate(Validator.java:260)
at sun.security.ssl.X509TrustManagerImpl.validate(X509TrustManagerImpl.java:324)
at sun.security.ssl.X509TrustManagerImpl.checkTrusted(X509TrustManagerImpl.java:229)
at sun.security.ssl.X509TrustManagerImpl.checkServerTrusted(X509TrustManagerImpl.java:124)
at sun.security.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:1496)
at sun.security.ssl.ClientHandshaker.processMessage(ClientHandshaker.java:216)
at sun.security.ssl.Handshaker.processLoop(Handshaker.java:1026)
at sun.security.ssl.Handshaker.process_record(Handshaker.java:961)
at sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:1062)
at sun.security.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1375)
at sun.security.ssl.SSLSocketImpl.writeRecord(SSLSocketImpl.java:747)
at sun.security.ssl.AppOutputStream.write(AppOutputStream.java:123)
at sun.security.ssl.AppOutputStream.write(AppOutputStream.java:138)
at SSLPoke.main(SSLPoke.java:31)
Caused by: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to
requested target
at sun.security.provider.certpath.SunCertPathBuilder.build(SunCertPathBuilder.java:141)
at sun.security.provider.certpath.SunCertPathBuilder.engineBuild(SunCertPathBuilder.java:126)
at java.security.cert.CertPathBuilder.build(CertPathBuilder.java:280)
at sun.security.validator.PKIXValidator.doBuild(PKIXValidator.java:382)
... 15 more
keytool -import -alias <anyname> -keystore "%JAVA_HOME%/jre/lib/security/cacerts" -file <cert path>
this would first prompt to "Enter keystore password:" changeit is the default password. and finally a prompt "Trust this certificate? [no]:", provide "yes" to add the cert to keystore.
Verfication:
C:\tools>"%JAVA_HOME%/bin/java" SSLPoke <hostname> 443
Successfully connected
Simple Steps that I followed.
problem: I was trying to connect to an endpoint(https://%s.blob.core.windows.net) using a simple java class(main method).
So I was getting this certification issue as mentioned above, in the question.
Solution:
Get the certificate using a browser(chrome). To do this paste your endpoint URL in the browser and enter. Now you will see a lock icon, click on that -->certificate--> details --> copy to files--> download it.
open the cmd(i am using windows) as admin and then navigate to the directory where you have downloaded the .cer file.
3.(Optional)If you are using multiple JDK in the same machine then change your JDK version the same as you are using in your application.
Now use the below command
keytool -import -alias mycertificate -keystore "C:\Program
Files\Java\jdk-11.0.5\lib\security\cacerts" -file myurlcrt.cer
Give the default password: changeit
Trust this certificate: yes
And you are done.
Thanks!
I was able to get it working with code only, i.e. no need to use keytool:
import com.netflix.config.DynamicBooleanProperty;
import com.netflix.config.DynamicIntProperty;
import com.netflix.config.DynamicPropertyFactory;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.config.Registry;
import org.apache.http.config.RegistryBuilder;
import org.apache.http.conn.ssl.SSLContexts;
import org.apache.http.conn.ssl.TrustStrategy;
import org.apache.http.conn.ssl.X509HostnameVerifier;
import org.apache.http.impl.nio.client.CloseableHttpAsyncClient;
import org.apache.http.impl.nio.client.HttpAsyncClients;
import org.apache.http.impl.nio.conn.PoolingNHttpClientConnectionManager;
import org.apache.http.impl.nio.reactor.DefaultConnectingIOReactor;
import org.apache.http.impl.nio.reactor.IOReactorConfig;
import org.apache.http.nio.conn.NoopIOSessionStrategy;
import org.apache.http.nio.conn.SchemeIOSessionStrategy;
import org.apache.http.nio.conn.ssl.SSLIOSessionStrategy;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLException;
import javax.net.ssl.SSLSession;
import javax.net.ssl.SSLSocket;
import java.io.IOException;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
public class Test
{
private static final DynamicIntProperty MAX_TOTAL_CONNECTIONS = DynamicPropertyFactory.getInstance().getIntProperty("X.total.connections", 40);
private static final DynamicIntProperty ROUTE_CONNECTIONS = DynamicPropertyFactory.getInstance().getIntProperty("X.total.connections", 40);
private static final DynamicIntProperty CONNECT_TIMEOUT = DynamicPropertyFactory.getInstance().getIntProperty("X.connect.timeout", 60000);
private static final DynamicIntProperty SOCKET_TIMEOUT = DynamicPropertyFactory.getInstance().getIntProperty("X.socket.timeout", -1);
private static final DynamicIntProperty CONNECTION_REQUEST_TIMEOUT = DynamicPropertyFactory.getInstance().getIntProperty("X.connectionrequest.timeout", 60000);
private static final DynamicBooleanProperty STALE_CONNECTION_CHECK = DynamicPropertyFactory.getInstance().getBooleanProperty("X.checkconnection", true);
public static void main(String[] args) throws Exception
{
SSLContext sslcontext = SSLContexts.custom()
.useTLS()
.loadTrustMaterial(null, new TrustStrategy()
{
#Override
public boolean isTrusted(X509Certificate[] chain, String authType) throws CertificateException
{
return true;
}
})
.build();
SSLIOSessionStrategy sslSessionStrategy = new SSLIOSessionStrategy(sslcontext, new AllowAll());
Registry<SchemeIOSessionStrategy> sessionStrategyRegistry = RegistryBuilder.<SchemeIOSessionStrategy>create()
.register("http", NoopIOSessionStrategy.INSTANCE)
.register("https", sslSessionStrategy)
.build();
DefaultConnectingIOReactor ioReactor = new DefaultConnectingIOReactor(IOReactorConfig.DEFAULT);
PoolingNHttpClientConnectionManager connectionManager = new PoolingNHttpClientConnectionManager(ioReactor, sessionStrategyRegistry);
connectionManager.setMaxTotal(MAX_TOTAL_CONNECTIONS.get());
connectionManager.setDefaultMaxPerRoute(ROUTE_CONNECTIONS.get());
RequestConfig requestConfig = RequestConfig.custom()
.setSocketTimeout(SOCKET_TIMEOUT.get())
.setConnectTimeout(CONNECT_TIMEOUT.get())
.setConnectionRequestTimeout(CONNECTION_REQUEST_TIMEOUT.get())
.setStaleConnectionCheckEnabled(STALE_CONNECTION_CHECK.get())
.build();
CloseableHttpAsyncClient httpClient = HttpAsyncClients.custom()
.setSSLStrategy(sslSessionStrategy)
.setConnectionManager(connectionManager)
.setDefaultRequestConfig(requestConfig)
.build();
httpClient.start();
// use httpClient...
}
private static class AllowAll implements X509HostnameVerifier
{
#Override
public void verify(String s, SSLSocket sslSocket) throws IOException
{}
#Override
public void verify(String s, X509Certificate x509Certificate) throws SSLException {}
#Override
public void verify(String s, String[] strings, String[] strings2) throws SSLException
{}
#Override
public boolean verify(String s, SSLSession sslSession)
{
return true;
}
}
}
The source of this error on my Apache 2.4 instance (using a Comodo wildcard certificate) was an incomplete path to the SHA-1 signed root certificate. There were multiple chains in the issued certificate, and the chain leading to a SHA-1 root certificate was missing an intermediate certificate. Modern browsers know how to handle this, but Java 7 doesn't handle it by default (although there are some convoluted ways to accomplish this in code). The result is error messages that look identical to the case of self-signed certificates:
Caused by: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
at sun.security.provider.certpath.SunCertPathBuilder.engineBuild(SunCertPathBuilder.java:196)
at java.security.cert.CertPathBuilder.build(CertPathBuilder.java:268)
at sun.security.validator.PKIXValidator.doBuild(PKIXValidator.java:380)
... 22 more
In this case, the "unable to find valid certification path to requested target" message is being produced due to the missing intermediate certificate. You can check which certificate is missing using SSL Labs test against the server. Once you find the appropriate certificate, download it and (if the server is under your control) add it to the certificate bundle. Alternatively, you can import the missing certificate locally. Accommodating this issue on the server is a more general solution to the problem.
For Windows only, follow these steps:
In Chrome go to settings.
In Settings click show advance settings.
Under HTTPS/SSL Click on Manage Certificates.
Export Your Certificate.
In Windows searchs (Pressing windows key on keyboard) type java.
Select (Configure Java) Option Which will open Java Control Panel
Select Security tab in Java Control Panel
Select Manage Certificates
Click Import
Under (User) tab selected and certificate type as (Trusted Certificates)
Click import button and browse to downloaded certificate and import it.
There is a lot of way to solve this...
One way is set the TrustStore certificates in a keystore file and put it in the path of the application, and set these system properties in the main method:
public static void main(String[] args) {
System.setProperty("javax.net.ssl.trustStore", "trust-store.jks");
System.setProperty("javax.net.ssl.trustStorePassword", "TrustStore");
...
}
Other way is place the keystore as resource file inside the project jar file and load it:
public static SSLContext createSSLContext(String resourcePath, String pass) throws NoSuchAlgorithmException, KeyStoreException, IOException, CertificateException, UnrecoverableKeyException, KeyManagementException {
// initialise the keystore
final char[] password = pass.toCharArray();
KeyStore ks = KeyStore.getInstance("JKS");
ks.load(ThisClass.class.getResourceAsStream(resourcePath
), password);
// Setup the key manager factory.
KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509");
kmf.init(ks, password);
// Setup the trust manager factory.
TrustManagerFactory tmf = TrustManagerFactory.getInstance("SunX509");
tmf.init(ks);
SSLContext sslc = SSLContext.getInstance("TLS");
sslc.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null);
return sslc;
}
public static void main(String[] args) {
SSLContext.setDefault(
createSSLContext("/trust-store.jks", "TrustStore"));
...
}
In windows you can try this solution too: https://stackoverflow.com/a/59056537/980442
I created the keystore file from a Certificate authority CA .crt file in this way:
keytool -import -alias ca -keystore trust-store.jks -storepass TrustStore -trustcacerts -file ca.crt
FYI: https://docs.oracle.com/javadb/10.8.3.0/adminguide/cadminsslclient.html
For those who like Debian and prepackaged Java:
sudo mkdir /usr/share/ca-certificates/test/ # don't mess with other certs
sudo cp ~/tmp/test.loc.crt /usr/share/ca-certificates/test/
sudo dpkg-reconfigure --force ca-certificates # check your cert in curses GUI!
sudo update-ca-certificates --fresh --verbose
Don't forget to check /etc/default/cacerts for:
# enable/disable updates of the keystore /etc/ssl/certs/java/cacerts
cacerts_updates=yes
To remove cert:
sudo rm /usr/share/ca-certificates/test/test.loc.crt
sudo rm /etc/ssl/certs/java/cacerts
sudo update-ca-certificates --fresh --verbose
UPDATE: That a reboot helped was coincidental (I hoped so, hooray!). The real cause of the problem was this: When Gradle is directed to use a specific keystore, that keystore must also contain all the official root certificates. Otherwise it cannot access libraries from regular repositories. What I had to do was this:
Import the self-signed certificate:
keytool -import -trustcacerts -alias myselfsignedcert -file /Users/me/Desktop/selfsignedcert.crt -keystore ./privateKeystore.jks
Add the official root certificates:
keytool -importkeystore -srckeystore <java-home>/lib/security/cacerts -destkeystore ./privateKeystore.jks
Maybe the Gradle daemon also got in the way. Might be worth killing all running daemons found with ./gradlew --status if things start looking bleak.
ORIGINAL POSTING:
Nobody will believe this, I know. Still, if all else fails, give it a try:
After a reboot of my Mac the problem was gone. Grrr.
Background:
./gradlew jar kept giving me "unable to find valid certification path to requested target"
I am stuck with a self-signed certificate, saved from browser, imported in privateKeystore.jks. Then instructed Gradle to work with privateKeystore.jks:
org.gradle.jvmargs=-Djavax.net.debug=SSL -Djavax.net.ssl.trustStore="/Users/me/IntelliJ/myproject/privateKeystore.jks" -Djavax.net.ssl.trustStorePassword=changeit
As mentioned, this only worked after a reboot.
Had the issue like this image.
Tried a few solutions.
But found that even if it's same project, when it's on other one's working place, it's totally fine. No extra settings needed. So we guessed it's an enviroment issue. We tried changing JDK version, IDE but didn't work. it took about 4 hours for investigation, until we tried the top-rated answer. I didn't find the error mentioned in that answer but I found via my browser about HTTP URL (lock) that there was a certification of Charles. Then I realized my charles was on all the time. As long as I turned that off, it's working all fine.
So I left my experience that could be helpful for your case.
This can also be caused by using GoDaddy certs with Java 7 that are signed using SHA2.
Chrome and all other browsers are starting to deprecate SSL certs that are signed using SHA1, as it's not as secure.
More info on the issue can be found here, as well as how to resolve it on your server if you need to now.
AVG version 18.1.3044 (with Windows 10) interfer with my local Spring application.
Solution: enter in AVG section called "Web and email" and disable the "email protection".
AVG block the certificate if the site isn't secure.
I had the same problem with the certificates error and it was because of SNI: the http client that I used didn't have SNI implemented. So a version update did the job
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>4.3.6</version>
</dependency>
Download the certificate from Nexus3 Browser (click on the lock-pad for View Site Information in case of Edge broser)
Click on Connection is secure
Click on the certificate details
Click on Copy To file (it opens up export certificate wizard)
Choose Base-64 encoding
Browse and select a download location and file-name (let’s say mycert)
Open cmd
Goto the download location and execute the below command
keytool -import -alias mycert -keystore "<<your-JAVA_HOME-directory>>\jre\lib\security\cacerts" -file mycert.cer
Restart the machine
Execute maven build again.
And if you are here in 2022 and are on mac follow this
1. Download the certificate.
echo -n | openssl s_client -connect <ServerName>:<PORT> -servername <ServerName> \
| openssl x509 > /tmp/<ServerName>.cert
2. Find your JDK path by executing the command.
/usr/libexec/java_home
3. Now import the cert into the cert-store of jdk.
sudo keytool -import -alias mycertificate -keystore "<JDK_HOME>/lib/security/cacerts" -file /tmp/<ServerName>.cert
You have two options, import the self-signed cert into java's keystore for each jvm the software will run on or try the non-validating ssl factory:
jdbc:postgresql://myserver.com:5432/mydatabasename?ssl=true&sslfactory=org.postgresql.ssl.NonValidatingFactory
Make sure that the https://176.66.3.69:6443/ have a valid certificate.
you can check it via browser firstly if it works in browser it will work in java.
that is working for me
If getting this error in maven, or maven with TestNG :
download the certificate from the target website and install certificate on your machine (using keytool as suggested above, or on windows)
add the following content to the maven arguments (command line and/or IDE):
-Djavax.net.ssl.trustStore=C:\Users\me.keystore -Djavax.net.ssl.trustStorePassword=X
Where X is the password you used at the keytool step.
note : C:\Users\me.keystore should also be set to match your machine.
For instance :
mvn -ea -Dtestng.dtd.http=true -Djavax.net.ssl.trustStore=C:\Users\me\.keystore -Djavax.net.ssl.trustStorePassword=X -Dmaven.wagon.http.ssl.insecure=true -Dmaven.wagon.http.ssl.allowall=true -Dmaven.wagon.http.ssl.ignore.validity.dates=true -Dcucumber.features=src/test/resources -Dcucumber.glue=com.myapp -Dcucumber.filter.tags="#MY_TEST"
In my case I'm running MacOs High Sierra with Java 1.6. The cacert file is in a different location than referenced above in Gabe Martin-Dempesy's answer. The cacert file was also already linked to another location (/Library/Internet Plug-Ins/JavaAppletPlugin.plugin/Contents/Home/lib/security/cacerts).
Using FireFox, I exported the certificate from the web site in question to a local file called "exportedCertFile.crt". From there, I used keytool to move the certificate into the cacert file. This fixed the problem.
bash-3.2# cd /Library/Java/JavaVirtualMachines/1.6.0.jdk/Contents/Home/lib/security/
bash-3.2# keytool -importcert -file ~/exportedCertFile.crt -alias example -keystore cacerts -storepass changeit
first Download the ssl certificate then you can go to your java bin path execute the below command in the console.
C:\java\JDK1.8.0_66-X64\bin>keytool -printcert -file C:\Users\lova\openapi.cer -keystore openapistore
In my case I had both keystore and truststore having the same certificate so removing truststore helped. Sometimes the chain of certificates can be an issue if you've multiple copies of certificates.
As original question was - how to ignore the cert error, here is solution for those using SpringBoot and RestTemplate
#Service
public class SomeService {
private final RestTemplate restTemplate;
private final ObjectMapper objectMapper;
private static HttpComponentsClientHttpRequestFactory createRequestFactory() {
try {
SSLContextBuilder sslContext = new SSLContextBuilder();
sslContext.loadTrustMaterial(null, new TrustAllStrategy());
CloseableHttpClient client = HttpClients.custom().setSSLContext(sslContext.build()).setSSLHostnameVerifier(NoopHostnameVerifier.INSTANCE).build();
HttpComponentsClientHttpRequestFactory requestFactory = new HttpComponentsClientHttpRequestFactory();
requestFactory.setHttpClient(client);
return requestFactory;
} catch (KeyManagementException | KeyStoreException | NoSuchAlgorithmException var3) {
throw new IllegalStateException("Couldn't create HTTP Request factory ignore SSL cert validity: ", var3);
}
}
#Autowired
public SomeService(RestTemplate restTemplate, ObjectMapper objectMapper) {
this.objectMapper = objectMapper;
this.dimetorURL = dimetorURL;
restTemplate.setRequestFactory(createRequestFactory());
}
public ResponseEntity<ResponseObject> sendRequest(RequestObject requestObject) {
//...
return restTemplate.exchange(url, HttpMethod.GET, ResponseObject.class);
//...
}
}
This is what worked for me on macOS. Replace server-name and server-port with your own.
Run these two commands on your terminal.
Download certificate from the remote server
openssl x509 -in <(openssl s_client -connect server-name:server-port -prexit 2>/dev/null) -out ~/server-name.crt
Import cert to Java keystore
sudo keytool -importcert -file ~/server-name.crt -alias server-name -keystore $JAVA_HOME/jre/lib/security/cacerts -storepass changeit
Restart your application and the certs errors should go away!
This works on any OS you just need JDK installed :
Download the certificate from the remote server :
keytool -printcert -rfc -sslserver <your remote server hostname> > /tmp/remorte-cert.crt
Import the certificate to your JDK keystore :
keytool -importcert -file /tmp/remorte-cert.crt -alias <an alias for your remote server> -storepass changeit -keystore "${JAVA_HOME}/lib/security/cacerts" -noprompt

Embedded MariaDB C/C++ API

I'm trying to get an embedded MariaDB (i.e. not connecting to running server) setup going but I'm failing to get any of the examples I find to work.
The most recent example I have is from this post https://stackoverflow.com/a/24548826/400048
When the app runs it produces:
Can't connect to local MySQL server through socket '/tmp/mysql.sock' (2)
The docs https://mariadb.com/kb/en/library/embedded-mariadb-interface/ isn't much help on this.
For convenience the code from that StackOverflow post is:
#include <my_global.h>
#include <mysql.h>
int main(int argc, char **argv) {
static char *server_options[] = {
"mysql_test", // An unused string
"--datadir=/tmp/mysql_embedded_data", // Your data dir
NULL };
int num_elements = (sizeof(server_options) / sizeof(char *)) - 1;
static char *server_groups[] = { "libmysqld_server",
"libmysqld_client", NULL };
// Init MySQL lib and connection
mysql_library_init(num_elements, server_options, server_groups);
MYSQL *con = mysql_init(NULL);
if (con == NULL) {
fprintf(stderr, "%s\n", mysql_error(con));
exit(1);
}
mysql_options(con, MYSQL_READ_DEFAULT_GROUP, "libmysqld_client");
mysql_options(con, MYSQL_OPT_USE_EMBEDDED_CONNECTION, NULL);
// Connect to no host/port -> Embedded mode
if (mysql_real_connect(con, NULL, NULL, NULL, NULL, 0, NULL, 0) == NULL) {
fprintf(stderr, "%s\n", mysql_error(con));
mysql_close(con);
exit(1);
}
// Create a sample empty DB, named "aNewDatabase"
if (mysql_query(con, "CREATE DATABASE aNewDatabase")) {
fprintf(stderr, "%s\n", mysql_error(con));
mysql_close(con);
exit(1);
}
// Close connection
mysql_close(con);
exit(0);
}
I had a cursory look at https://github.com/MariaDB/server but didn't know where to really look...or in fact what I was looking for.
How does one go about getting an embedded mariadb going?
I'm running on Mac OS High Sierra, MariaDB was installed with brew install mariadb --with-embedded.
UPDATE:
I'm fairly certain I'm linking to the correct lib.
ls /usr/local/lib | grep maria
FIND_LIBRARY(mariadb mariadb)
MESSAGE(FATAL_ERROR "BOOM ${mariadb}")
Output of which is:
BOOM /usr/local/lib/libmariadb.dylib
UPDATE 2
I'm now linking to the following. Note that I started with just libmysqld and added libraries until all link errors went away. The trouble here is I may not have all the correct libs or versions.
TARGET_LINK_LIBRARIES(sql_fn /usr/local/lib/libmysqld.a)
TARGET_LINK_LIBRARIES(sql_fn /usr/local/opt/openssl/lib/libcrypto.a)
TARGET_LINK_LIBRARIES(sql_fn /usr/local/opt/openssl/lib/libssl.a)
TARGET_LINK_LIBRARIES(sql_fn /usr/local/opt/bzip2/lib/libbz2.a)
TARGET_LINK_LIBRARIES(sql_fn /usr/local/lib/liblz4.a)
TARGET_LINK_LIBRARIES(sql_fn /usr/local/opt/zlib/lib/libz.a)
TARGET_LINK_LIBRARIES(sql_fn /usr/local/opt/xz/lib/liblzma.a)
TARGET_LINK_LIBRARIES(sql_fn /usr/local/lib/libsnappy.a)
It now compiles but exits with code 6
Process finished with exit code 6
Looking at https://stackoverflow.com/a/7495907/400048 if it's points to the same thing/is still true then exit code 6 means EX_ILLEGAL_TABLE 6, unfortunately I don't know what table that would be. The mysql_test and datadir strings passed in are valid identifiers/path.
Ok first a little explanation about your example. The user is using gcc to compile and I can see you are using cmake.
First what does -lz and mysql_config --include --libmysqld-libs means. The first is link zlib to link zlib in cmake you can refer to this answer, but long story short:
find_package( ZLIB REQUIRED )
if ( ZLIB_FOUND )
include_directories( ${ZLIB_INCLUDE_DIRS} )
target_link_libraries( sql_fn ${ZLIB_LIBRARIES} )
endif( ZLIB_FOUND )
Then you need the mariaDB library and that is the second part. mysql_config --include --libmysqld-libs this means execute the command mysql_config --include --libmysqld-libs which will return a string with the link options so execute the command:
$mysql_config --include --libmysqld-libs
-I/usr/local/mysql/include
-L/usr/local/mysql/lib -lmysqld
And you should get an output like the one above. The -I is to look for headers in a given directory and the -L is to search a library in a directory, the -l is to link a given library it serves the same purpose as -lz only you are adding -lmysqld.
Well now that all is explained you need only include the -I -L and -l options with mysql however this is not such a standard library so you need to include directories and libraries through a script as explained in this anwer. So again long story short there is no bullet proof for this for example my library is in /usr/local/mysql/lib and yours is in /usr/local/lib. Since that is the case it will be easier to use the second method.
execute_process(COMMAND mysql_config --include
OUTPUT_VARIABLE MYSQL_INCLUDE)
execute_process(COMMAND mysql_config --libmysqld-libs
OUTPUT_VARIABLE MYSQL_LIBS)
target_compile_options(sql_fn PUBLIC ${MYSQL_INCLUDE})
target_link_libraries(sql_fn ${MYSQL_LIBS})
And that is all the required information you need. Now we are glad we have Cmake to make things easier for us don't we. ;)
Here is my CMakeLists.txt
cmake_minimum_required(VERSION 3.6)
project(embedded_mysql)
set(CMAKE_CXX_STANDARD 14)
set(SOURCE_FILES main.cpp)
add_executable(embedded_mysql ${SOURCE_FILES})
find_package( ZLIB REQUIRED )
if ( ZLIB_FOUND )
include_directories( ${ZLIB_INCLUDE_DIRS} )
target_link_libraries( embedded_mysql ${ZLIB_LIBRARIES} )
endif( ZLIB_FOUND )
execute_process(COMMAND mysql_config --include
OUTPUT_VARIABLE MYSQL_INCLUDE)
execute_process(COMMAND mysql_config --libmysqld-libs
OUTPUT_VARIABLE MYSQL_LIBS)
string(STRIP ${MYSQL_LIBS} MYSQL_LIBS)
target_compile_options(embedded_mysql PUBLIC ${MYSQL_INCLUDE})
target_link_libraries(embedded_mysql ${MYSQL_LIBS})
You can see the code in github here

MySql from Lua undefined symbol problen at runtime

I have a lua web service, and it needs use MySql. If I try access the MySql from lua console I get success, like you can see:
$lua
Lua 5.1.4 Copyright (C) 1994-2008 Lua.org, PUC-Rio
> local luasql = require('luasql.mysql')
> local json = require('json')
> mysql = assert(luasql.mysql())
> ret = {}
> db_name = "luaTest"
> db_host = "localhost"
> db_user = "root"
> db_pass = ""
> con = assert(mysql:connect(db_name, db_user, db_pass, db_host))
> cur = assert(con:execute("SELECT version()"))
> ret["driver_version"] = luasql._MYSQLVERSION
> ret["copyright"] = luasql._COPYRIGHT
> ret["description"] = luasql._DESCRIPTION
> ret["version"] = luasql._VERSION
> con:close()
> mysql:close()
> print(json.encode(ret))
{"copyright":"Copyright (C) 2003-2008 Kepler Project","version":"LuaSQL 2.1.2","driver_version":"5.5.29-MariaDB","description":"LuaSQL is a simple interface from Lua to a DBMS"}
I have that code my server (file: /etc/nginx/www/ademar/app.lua):
local sinatra = require('sinatra')
local json = require('json')
local luasql = require('luasql.mysql')
local app = sinatra.app:new()
app:post("/signin", function()
ret = {}
mysql = assert(luasql.mysql())
db_name = "luaTest"
db_host = "localhost"
db_user = "root"
db_pass = ""
con = assert(mysql:connect(db_name, db_user, db_pass, db_host))
cur = assert(con:execute("SELECT version()"))
ret["driver_version"] = luasql._MYSQLVERSION
ret["copyright"] = luasql._COPYRIGHT
ret["description"] = luasql._DESCRIPTION
ret["version"] = luasql._VERSION
con:close()
mysql:close()
return json.encode(ret)
end)
app:run()
if I try run it with $curl -X POST http://127.0.0.1/signin i get a html error, and on server log i get it:
2014/01/11 17:32:20 [error] 5104#0: *2 lua entry thread aborted: runtime error: error loading module 'luasql.mysql' from file '/usr/lib/lua/5.1/luasql/mysql.so':
/usr/lib/lua/5.1/luasql/mysql.so: undefined symbol: luaL_openlib
stack traceback:
coroutine 0:
[C]: ?
[C]: in function 'require'
/etc/nginx/www/ademar/app.lua:3: in function </etc/nginx/www/ademar/app.lua:1>, client: 127.0.0.1, server: adem.ar, request: "POST /signin HTTP/1.1", host: "127.0.0.1"
My Nginx conf:
$cat nginx.conf
user nginx www-data;
worker_processes 1;
pid /var/run/nginx.pid;
events {
worker_connections 768;
}
http {
sendfile on;
tcp_nopush on;
tcp_nodelay on;
keepalive_timeout 65;
types_hash_max_size 2048;
include /etc/nginx/mime.types;
default_type application/octet-stream;
access_log /var/log/nginx/access.log;
error_log /var/log/nginx/error.log;
gzip on;
gzip_disable "msie6";
include /etc/nginx/conf.d/*.conf;
include /etc/nginx/sites-enabled/*;
}
and:
$cat sites-enabled/xicoh.conf
lua_package_path './?.lua;/usr/share/lua/5.1/?.lua;/usr/share/lua/5.1/?/init.lua;/usr/lib/lua/5.1/?.lua;/usr/lib/lua/5.1/?/init.lua;;';
lua_package_cpath './?.so;/usr/lib/lua/5.1/?.so;/usr/lib/lua/5.1/loadall.so;;';
server {
listen 80;
server_name adem.ar;
charset utf-8;
root /etc/nginx/www/ademar;
location / {
default_type 'text/plain';
content_by_lua_file "/etc/nginx/www/ademar/app.lua";
}
error_page 500 502 503 504 /50x.html;
location = /50x.html { root html; }
}
edited
Some variables from lua console:
package.path = ./?.lua;/usr/share/lua/5.1/?.lua;/usr/share/lua/5.1/?/init.lua;/usr/lib/lua/5.1/‌​?.lua;/usr/lib/lua/5.1/?/init.lua
package.cpath = ./?.so;/usr/lib/lua/5.1/?.so;/usr/lib/lua/5.1/loadall.so.
LD_LIBRARY_PATH = nil
and from nginx script:
package.path = ./?.lua;/usr/share/lua/5.1/?.lua;/usr/share/lua/5.1/?/init.lua;/usr/lib/lua/5.1/‌​?.lua;/usr/lib/lua/5.1/?/init.lua;/usr/local/openresty/nginx/lualib/?.lua;/usr/lo‌​cal/openresty/nginx/lualib/?/init.lua;./?.lua;/usr/local/share/lua/5.1/?.lua;/usr‌​/local/share/lua/5.1/?/init.lua;/usr/local/lib/lua/5.1/?.lua;/usr/local/lib/lua/5‌​.1/?/init.lua;
package.cpath = ./?.so;/usr/lib/lua/5.1/?.so;/usr/lib/lua/5.1/loadall.so;/usr/local/openresty/ng‌​inx/lualib/?.so;./?.so;/usr/local/lib/lua/5.1/?.so;/usr/local/lib/lua/5.1/loadall‌​.so;
LD_LIBRARY_PATH = nil
The luaL_openlib is a function that was in Lua 5.0 but not in 5.1. In 5.1 it was replaced by luaL_register. So likely the luasql you installed is for Lua 5.0, whereas you have (I presume, based on your package path) Lua 5.1 installed on your system.
If you don't have 5.0 installed at all (not somewhere under nginx as well), maybe a path difference? if mysql.so links to another .so or requires a Lua module (who knows what mysql does, it may call Lua's require), but the path seen in both environments is different, it may find wrong lib: that lib may be using 5.0 luaL_openlib. Or, the environment being different (such as user permissions) makes mysql behave differently, such as looking for a different lib. Print the package.path and package.cpath and os.getenv("LD_LIBRARY_PATH") from the script.
OK so I checked the source for luasql/mysql module on github. Version 2.2.x (released 6 years ago) and older use the old luaL_openlib (must have been for Lua 5.0), although the commit log indicates there was a compatibility file for 5.1. Probably your version of mysql.so was built for 5.0. Version 2.3 uses luaL_setfuncs which is only in Lua 5.2, so there is again probably a build setting you have to use to tell the compiler to use 5.1 headers and link to 5.1.