1 // ssl.cpp:  HyperText Transport Protocol handler for Cygnal, for Gnash.
2 //
3 //   Copyright (C) 2009, 2010, 2011, 2012 Free Software Foundation, Inc.
4 //
5 // This program is free software; you can redistribute it and/or modify
6 // it under the terms of the GNU General Public License as published by
7 // the Free Software Foundation; either version 3 of the License, or
8 // (at your option) any later version.
9 //
10 // This program is distributed in the hope that it will be useful,
11 // but WITHOUT ANY WARRANTY; without even the implied warranty of
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13 // GNU General Public License for more details.
14 //
15 // You should have received a copy of the GNU General Public License
16 // along with this program; if not, write to the Free Software
17 // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
18 //
19 
20 #ifdef HAVE_CONFIG_H
21 #include "gnashconfig.h"
22 #endif
23 
24 #include <mutex>
25 #include <cstdint>
26 #include <sys/types.h>
27 #include <sys/stat.h>
28 #include <fcntl.h>
29 #include <string>
30 #include <vector>
31 #include <iostream>
32 #include <cstring>
33 #include <sstream>
34 #include <sys/types.h>
35 #include <sys/stat.h>
36 #include <algorithm>
37 #include <cstdlib> // getenv
38 
39 #include "GnashSystemIOHeaders.h" // read()
40 #include "sslserver.h"
41 #include "amf.h"
42 #include "element.h"
43 #include "cque.h"
44 #include "log.h"
45 #include "network.h"
46 #include "utility.h"
47 #include "buffer.h"
48 #include "diskstream.h"
49 #include "cache.h"
50 #include "sslclient.h"
51 #include "sslserver.h"
52 
53 #ifdef HAVE_OPENSSL_SSL_H
54 #include <openssl/ssl.h>
55 #include <openssl/err.h>
56 #endif
57 
58 
59 #if defined(_WIN32) || defined(WIN32)
60 # define __PRETTY_FUNCTION__ __FUNCDNAME__
61 # include <winsock2.h>
62 # include <direct.h>
63 #else
64 # include <unistd.h>
65 # include <sys/param.h>
66 #endif
67 
68 using namespace gnash;
69 using namespace std;
70 
71 static std::mutex stl_mutex;
72 
73 namespace gnash
74 {
75 
76 const char *SERVER_KEYFILE  = "server.pem";
77 
78 static unsigned char dh512_p[]={
79         0xA6,0xBB,0x71,0x4A,0xE2,0x37,0x18,0x30,0xD9,0x0C,0x21,0x94,
80         0x6C,0x0E,0xC7,0xBB,0x0A,0xA5,0x5B,0x28,0x9D,0x9F,0x85,0x4A,
81         0x69,0x7F,0x3E,0x4E,0x28,0x2F,0x43,0x1D,0xE5,0x84,0x94,0x41,
82         0xC3,0x09,0xFA,0xC3,0x32,0xDE,0x9A,0xF1,0x92,0x4D,0xAA,0x30,
83         0x1E,0x39,0x98,0x0A,0xD3,0x87,0xC1,0xC8,0xE5,0xEC,0x9E,0x45,
84         0x37,0x7B,0xB8,0xAB,
85         };
86 static unsigned char dh512_g[]={
87         0x02,
88         };
89 
90 const char *SERVER_PASSWORD  = "none";
91 const char *DHFILE  = "dh1024.pem";
92 
SSLServer()93 SSLServer::SSLServer()
94 {
95 //     GNASH_REPORT_FUNCTION;
96 }
97 
~SSLServer()98 SSLServer::~SSLServer()
99 {
100 //    GNASH_REPORT_FUNCTION;
101 
102     sslShutdown();
103 }
104 
105 bool
loadDhParams(char * file)106 SSLServer::loadDhParams(char *file)
107 {
108 //    GNASH_REPORT_FUNCTION;
109     return loadDhParams(_ctx.get(), file);
110 }
111 
112 bool
loadDhParams(SSL_CTX * ctx,char * file)113 SSLServer::loadDhParams(SSL_CTX *ctx, char *file)
114 {
115 //    GNASH_REPORT_FUNCTION;
116     DH *dh = 0;
117 
118 //    ret = get_dh512();
119     if ((dh = DH_new()) == NULL) {
120 	return false;
121     } else {
122 	dh->p = BN_bin2bn(dh512_p, sizeof(dh512_p), NULL);
123 	dh->g = BN_bin2bn(dh512_g, sizeof(dh512_g), NULL);
124 	if ((dh->p == NULL) || (dh->g == NULL)) {
125 	    free(dh);
126 	    dh = NULL;
127 	}
128     }
129 
130     if (dh && ctx) {
131 	if (SSL_CTX_set_tmp_dh(ctx, dh) < 0) {
132 	    log_error(_("Couldn't set DH parameters: %s "),
133 		      ERR_reason_error_string(ERR_get_error()));
134 	    return false;
135 	}
136     }
137     return true;
138 }
139 
140 // sslAccept() is how the server waits for connections for clients
141 size_t
sslAccept(int fd)142 SSLServer::sslAccept(int fd)
143 {
144     GNASH_REPORT_FUNCTION;
145 
146     setKeyfile(SERVER_KEYFILE);
147     if (!_ctx) {
148 	if (!sslSetupCTX()) {
149 	    return false;
150 	}
151     }
152 
153     loadDhParams(_ctx.get(), const_cast<char *>(DHFILE));
154 
155     log_debug(_("Got an incoming SSL connection request"));
156 
157     _bio.reset(BIO_new_socket(fd, BIO_NOCLOSE));
158 
159     _ssl.reset(SSL_new(_ctx.get()));
160     SSL_set_accept_state(_ssl.get());
161     SSL_set_bio(_ssl.get(), _bio.get(), _bio.get());
162 
163     int ret = 0;
164     if((ret = SSL_accept(_ssl.get()) <= 0)) {
165  	log_error(_("Error was: \"%s\"!"),
166 		  ERR_reason_error_string(ERR_get_error()));
167     }
168 
169     return 0;
170 }
171 
172 void
dump()173 SSLServer::dump() {
174 //    GNASH_REPORT_FUNCTION;
175 
176     std::lock_guard<std::mutex> lock(stl_mutex);
177 
178     log_debug (_("==== The SSL header breaks down as follows: ===="));
179 }
180 
181 } // end of gnash namespace
182 
183 
184 // local Variables:
185 // mode: C++
186 // indent-tabs-mode: nil
187 // End:
188