c++ - Client Certificate in fastCGI? -
i have implemented simple fastcgi in c++. server using nginx. have problem when trying implement https in nginx , setting certificate. server certificate have created server certificate , embed nginx config as:
ssl_certificate /home/nilav/certificates/ssl/server.crt; ssl_certificate_key /home/nilav/certificates/ssl/server.key;
now client certificate not figure out how send client certificate fastcgi nginx. offcourse there way verify client certificate in nginx as:
ssl_client_certificate /home/nilav/certificates/ssl/ca.pem; ssl_verify_client on;
the client certificate works when installed in browser. want certificate send code code hits request , act client. not figure out how send client certificate fastcgi code in c++. below code:
#include <stdlib.h> #include <stdio.h> #include <sstream> #include <iostream> #include <string> #include "string.h" #include "fcgio.h" #include <fcgi_stdio.h> #include <boost/algorithm/string.hpp> using namespace std; using namespace boost; // maximum bytes const unsigned long stdin_max = 1000000; /** * note not thread safe due static allocation of * content_buffer. */ string get_request_content(const fcgx_request & request) { char * content_length_str = fcgx_getparam("content_length", request.envp); unsigned long content_length = stdin_max; if (content_length_str) { content_length = strtol(content_length_str, &content_length_str, 10); if (*content_length_str) { cerr << "can't parse 'content_length='" << fcgx_getparam("content_length", request.envp) << "'. consuming stdin " << stdin_max << endl; } if (content_length > stdin_max) { content_length = stdin_max; } } else { // not read stdin if content_length missing content_length = 0; } char * content_buffer = new char[content_length]; cin.read(content_buffer, content_length); content_length = cin.gcount(); // chew remaining stdin - shouldn't necessary // because mod_fastcgi doesn't handle correctly. // ignore() doesn't set eof bit in versions of glibc++ // use gcount() instead of eof()... cin.ignore(1024); while (cin.gcount() == 1024); string content(content_buffer, content_length); delete [] content_buffer; return content; } int main(void) { // backup stdio streambufs streambuf * cin_streambuf = cin.rdbuf(); streambuf * cout_streambuf = cout.rdbuf(); streambuf * cerr_streambuf = cerr.rdbuf(); fcgx_request request; fcgx_init(); fcgx_initrequest(&request, 0, 0); while (fcgx_accept_r(&request) == 0) { fcgi_streambuf cin_fcgi_streambuf(request.in); fcgi_streambuf cout_fcgi_streambuf(request.out); fcgi_streambuf cerr_fcgi_streambuf(request.err); cin.rdbuf(&cin_fcgi_streambuf); cout.rdbuf(&cout_fcgi_streambuf); cerr.rdbuf(&cerr_fcgi_streambuf); const char * uri = fcgx_getparam("request_uri", request.envp); string content = get_request_content(request); if (content.length() == 0) { content = ", something!"; } const char * mediatype = fcgx_getparam("request_method",request.envp); string value; if(iequals(mediatype,"post")&&iequals(uri,"/postmethod")) { get_request_content(request); cout << "http/1.1 200 ok\r\ncontent-length: " << content.length() << "\r\n\r\n" << content; } if(iequals(mediatype,"get")&&iequals(uri,"/getmethod")) { string aalu = "this new lenght"; cout << "http/1.1 200 ok\r\ncontent-length: " << aalu.length() << "\r\n\r\n" << aalu; fcgx_finish_r(&request); } if(iequals(mediatype,"get")&&iequals(uri,"/redirect")) { cout << "http/1.1 301\r\nlocation: http://localhost/getmethod\r\n\r\n"; // cout << "status: 301\r\n" // << "location: http://localhost/getmethod\r\n"; // << "\r\n"; // << "<html><body>not found</body></html>\n"; } if(iequals(mediatype,"get")&&iequals(uri,"/postredirect")) { // problem here string json = "{\"topic\":\"asdf\",\"message\":\"message\"}"; cout << "http/1.1 308\r\nlocation: http://localhost/postmethod\r\n\r\n"; // cout << "status: 304\r\n" // << "location: http://localhost/postmethod\r\n" // << "\r\n" // << "<html><body>json</body></html>\n"; } if(iequals(mediatype,"post")&&iequals(uri,"/getredirect")) { string json = "{\"topic\":\"asdf\",\"message\":\"message\"}"; cout << "http/1.1 303\r\nlocation: http://localhost/getmethod\r\n\r\n"; // cout << "status: 304\r\n" // << "location: http://localhost/postmethod\r\n" // << "\r\n" // << "<html><body>json</body></html>\n"; } if(iequals(mediatype,"post")&&iequals(uri,"/posttopostredirect")) { string json = "{\"topic\":\"adf\",\"message\":\"message\"}"; cout << "status: 307\r\n" <<"location: http://localhost/postmethod\r\n" <<"\r\n\r\n" <<"\n"; // cout << "status: 305\r\n" // << "location: http://localhost/postmethod\r\n" // << "\r\n" // << "<html><body>"+json+"</body></html>\n"; } if(iequals(mediatype,"get")&&iequals(uri,"/getttogettredirect")) { string json = "{\"topic\":\"ssdf\",\"message\":\"message\"}"; cout << "http/1.x 301\r\nlocation: http://localhost/getmethod\r\n\r\n"; // cout << "status: 307\r\n" // << "location: http://localhost/postmethod\r\n" // << "\r\n"; // << "<html><body>json</body></html>\n"; } } // restore stdio streambufs cin.rdbuf(cin_streambuf); cout.rdbuf(cout_streambuf); cerr.rdbuf(cerr_streambuf); return 0; }
and below configuration of nginx:
#user nobody; worker_processes 1; #error_log logs/error.log; #error_log logs/error.log notice; #error_log logs/error.log info; #pid logs/nginx.pid; events { worker_connections 1024; } http { # include mime.types; # default_type application/octet-stream; #log_format main '$remote_addr - $remote_user [$time_local] "$request" ' # '$status $body_bytes_sent "$http_referer" ' # '"$http_user_agent" "$http_x_forwarded_for"'; #access_log logs/access.log main; #sendfile on; #tcp_nopush on; #keepalive_timeout 0; #keepalive_timeout 65; #gzip on; server { listen 8085; # listen 443 ssl; server_name localhost; ssl_certificate /home/nilav/certificates/ssl/server.crt; ssl_certificate_key /home/nilav/certificates/ssl/server.key; ssl_client_certificate /home/nilav/certificates/ssl/ca.pem; ssl_verify_client on; #charset koi8-r; #access_log logs/host.access.log main; location / { fastcgi_pass 127.0.0.1:8000; fastcgi_param gateway_interface cgi/1.1; fastcgi_param server_software nginx; fastcgi_param query_string $query_string; fastcgi_param request_method $request_method; fastcgi_param content_type $content_type; fastcgi_param content_length $content_length; fastcgi_param script_filename $document_root$fastcgi_script_name; fastcgi_param script_name $fastcgi_script_name; fastcgi_param request_uri $request_uri; fastcgi_param document_uri $document_uri; fastcgi_param document_root $document_root; fastcgi_param server_protocol $server_protocol; fastcgi_param remote_addr $remote_addr; fastcgi_param remote_port $remote_port; fastcgi_param server_addr $server_addr; fastcgi_param server_port $server_port; fastcgi_param server_name $server_name; } #error_page 404 /404.html; # redirect server error pages static page /50x.html # #error_page 500 502 503 504 /50x.html; #location = /50x.html { # root html; #} # proxy php scripts apache listening on 127.0.0.1:80 # #location ~ \.php$ { # proxy_pass http://127.0.0.1; #} # pass php scripts fastcgi server listening on 127.0.0.1:9000 # #location ~ \.php$ { # root html; # fastcgi_pass 127.0.0.1:9000; # fastcgi_index index.php; # fastcgi_param script_filename /scripts$fastcgi_script_name; # include fastcgi_params; #} # deny access .htaccess files, if apache's document root # concurs nginx's 1 # #location ~ /\.ht { # deny all; #} #} # virtual host using mix of ip-, name-, , port-based configuration # #server { # listen 8000; # listen somename:8080; # server_name somename alias another.alias; # location / { # root html; # index index.html index.htm; # } #} # https server # #server { # listen 8085; # listen 443 ssl; #server_name localhost; # ssl_certificate /home/nilav/certificates/ssl/server.crt; # ssl_certificate_key /home/nilav/certificates/ssl/server.key; # ssl_client_certificate /home/nilav/certificates/ssl/ca.pem; # ssl_verify_client on; #ssl_session_cache shared:ssl:1m; # ssl_session_timeout 5m; # ssl_ciphers high:!anull:!md5; # ssl_prefer_server_ciphers on; #location / { # proxy_pass http://127.0.0.1:8080; # proxy_http_version 1.1; # proxy_set_header upgrade $http_upgrade; #proxy_set_header connection 'upgrade'; #proxy_set_header host $host; #proxy_cache_bypass $http_upgrade; #} } }
Comments
Post a Comment