Search code examples
csslopensslmongoose-web-server

How to run SSL with mongoose webserver API


I use the Mongoose webserver API in C to implement a small HTTP API. It's working fine so far but if I want to use SSL, the server rejects the requests.

To generate the ssl key and certificate, I used the following approach:

# openssl version
OpenSSL 1.0.0-beta2 21 Apr 2009

# openssl req -x509 -newkey rsa:2048 -keyout key.pem -out cert.pem -days 1000 -nodes

# cat key.pem > ssl.pem; cat cert.pem >> ssl.pem

According to this manual, mongoose wants the key and cert in one file.

I also set the NS_ENABLE_SSL compile flag to enable the ssl part of mongoose.

To initialize mongoose I do the following in my C source:

struct mg_server *server;
server = mg_create_server(NULL, ev_handler);
printf("%s",mg_set_option(server, "document_root", "/var/www"));
printf("%s",mg_set_option(server, "listening_port", "80"));
printf("%s",mg_set_option(server, "ssl_certificate", "ssl.pem"));

My event handler does nothing but logging the requests on the console at the moment:

static int ev_handler(struct mg_connection *conn, enum mg_event ev) {

 switch(ev){
    case MG_AUTH: printf("MG_AUTH event handler called with uri = '%s'\n", conn->uri);
    break;
 case MG_REQUEST:
     printf("MG_REQUEST event handler called with uri = '%s'\n", conn->uri);
     break;
 case MG_POLL:
     printf("MG_POLL event handler called with uri = '%s'\n", conn->uri);
     break;
 case MG_HTTP_ERROR:
     printf("MG_HTTP_ERROR event handler called with uri = '%s'\n", conn->uri);
     break;
 default:
     DBG("MG_CLOSE event handler called with uri = '%s'\n", conn->uri);
     break;
 }
 return MG_FALSE;
}

If I try to open a HTML file from the document root in the browser, the server closes the connection without delivering content.

Console output:

(null)
(null)
(null)
MG_POLL event handler called with uri = '(null)'
MG_CLOSE event handler called with uri = '(null)'

The first three (null) are the return values from the mg_set_option which are NULL if no problem occurs while setting an option.

What's going wrong here?


Solution

    1. Make sure you're using "https://my.ip:80" when connecting to the server. Otherwise, browser is going to use HTTP protocol, and mongoose will reject the connection because it expects SSL handshake, and gets plain HTTP data. I think that is what's going on.

    2. You're returning MG_FALSE on MG_AUTH event, which tells mongoose "connection is not authenticated, close it immediately."

    Solution:

    • return MG_TRUE on MG_AUTH event. For other events, returning MG_FALSE is fine.
    • use listening_port 443, and https:// when connecting to the server