summaryrefslogtreecommitdiff
path: root/core/io
diff options
context:
space:
mode:
Diffstat (limited to 'core/io')
-rw-r--r--core/io/file_access_encrypted.cpp123
-rw-r--r--core/io/file_access_encrypted.h6
-rw-r--r--core/io/file_access_pack.cpp1
-rw-r--r--core/io/http_client.cpp40
-rw-r--r--core/io/http_client.h10
-rw-r--r--core/io/stream_peer_ssl.cpp29
-rw-r--r--core/io/stream_peer_ssl.h34
-rw-r--r--core/io/stream_peer_tcp.cpp7
-rw-r--r--core/io/stream_peer_tcp.h2
9 files changed, 219 insertions, 33 deletions
diff --git a/core/io/file_access_encrypted.cpp b/core/io/file_access_encrypted.cpp
index 49487d4f8f..bcd4197e11 100644
--- a/core/io/file_access_encrypted.cpp
+++ b/core/io/file_access_encrypted.cpp
@@ -2,22 +2,74 @@
#include "aes256.h"
#include "md5.h"
#include "os/copymem.h"
+#include "print_string.h"
#define COMP_MAGIC 0x43454447
Error FileAccessEncrypted::open_and_parse(FileAccess *p_base,const Vector<uint8_t>& p_key,Mode p_mode) {
+ print_line("open and parse!");
ERR_FAIL_COND_V(file!=NULL,ERR_ALREADY_IN_USE);
+ ERR_FAIL_COND_V(p_key.size()!=32,ERR_INVALID_PARAMETER);
+
+ pos=0;
+ eofed=false;
if (p_mode==MODE_WRITE_AES256) {
- ERR_FAIL_COND_V(p_key.size()!=32,ERR_INVALID_PARAMETER);
data.clear();
writing=true;
file=p_base;
mode=p_mode;
key=p_key;
+ } else if (p_mode==MODE_READ) {
+
+ key=p_key;
+ uint32_t magic = p_base->get_32();
+ print_line("MAGIC: "+itos(magic));
+ ERR_FAIL_COND_V(magic!=COMP_MAGIC,ERR_FILE_UNRECOGNIZED);
+ mode=Mode(p_base->get_32());
+ ERR_FAIL_INDEX_V(mode,MODE_MAX,ERR_FILE_CORRUPT);
+ ERR_FAIL_COND_V(mode==0,ERR_FILE_CORRUPT);
+ print_line("MODE: "+itos(mode));
+ unsigned char md5d[16];
+ p_base->get_buffer(md5d,16);
+ length=p_base->get_64();
+ base=p_base->get_pos();
+ ERR_FAIL_COND_V(p_base->get_len() < base+length, ERR_FILE_CORRUPT );
+ int ds = length;
+ if (ds % 16) {
+ ds+=16-(ds % 16);
+ }
+
+ data.resize(ds);
+
+ int blen = p_base->get_buffer(data.ptr(),ds);
+ ERR_FAIL_COND_V(blen!=ds,ERR_FILE_CORRUPT);
+
+ aes256_context ctx;
+ aes256_init(&ctx,key.ptr());
+
+ for(size_t i=0;i<ds;i+=16) {
+
+ aes256_decrypt_ecb(&ctx,&data[i]);
+ }
+
+ aes256_done(&ctx);
+
+ data.resize(length);
+
+ MD5_CTX md5;
+ MD5Init(&md5);
+ MD5Update(&md5,data.ptr(),data.size());
+ MD5Final(&md5);
+
+
+ ERR_FAIL_COND_V(String::md5(md5.digest)!=String::md5(md5d),ERR_FILE_CORRUPT) ;
+
+
+ file=p_base;
}
return OK;
@@ -57,6 +109,11 @@ void FileAccessEncrypted::close() {
len+=16-(len % 16);
}
+ MD5_CTX md5;
+ MD5Init(&md5);
+ MD5Update(&md5,data.ptr(),data.size());
+ MD5Final(&md5);
+
compressed.resize(len);
zeromem( compressed.ptr(), len );
for(int i=0;i<data.size();i++) {
@@ -76,10 +133,6 @@ void FileAccessEncrypted::close() {
file->store_32(COMP_MAGIC);
file->store_32(mode);
- MD5_CTX md5;
- MD5Init(&md5);
- MD5Update(&md5,compressed.ptr(),compressed.size());
- MD5Final(&md5);
file->store_buffer(md5.digest,16);
file->store_64(data.size());
@@ -88,9 +141,18 @@ void FileAccessEncrypted::close() {
file->close();
memdelete(file);
file=NULL;
+ data.clear();
+
+ } else {
+ file->close();
+ memdelete(file);
+ data.clear();
+ file=NULL;
}
+
+
}
bool FileAccessEncrypted::is_open() const{
@@ -100,12 +162,12 @@ bool FileAccessEncrypted::is_open() const{
void FileAccessEncrypted::seek(size_t p_position){
- if (writing) {
- if (p_position > (size_t)data.size())
- p_position=data.size();
+ if (p_position > (size_t)data.size())
+ p_position=data.size();
+
+ pos=p_position;
+ eofed=false;
- pos=p_position;
- }
}
@@ -116,38 +178,51 @@ void FileAccessEncrypted::seek_end(int64_t p_position){
size_t FileAccessEncrypted::get_pos() const{
return pos;
- return 0;
}
size_t FileAccessEncrypted::get_len() const{
- if (writing)
- return data.size();
- return 0;
+ return data.size();
}
bool FileAccessEncrypted::eof_reached() const{
- if (!writing) {
+ return eofed;
+}
+uint8_t FileAccessEncrypted::get_8() const{
+ ERR_FAIL_COND_V(writing,0);
+ if (pos>=data.size()) {
+ eofed=true;
+ return 0;
}
- return false;
-}
-
-uint8_t FileAccessEncrypted::get_8() const{
+ uint8_t b = data[pos];
+ pos++;
+ return b;
- return 0;
}
int FileAccessEncrypted::get_buffer(uint8_t *p_dst, int p_length) const{
+ ERR_FAIL_COND_V(writing,0);
- return 0;
+ int to_copy=MIN(p_length,data.size()-pos);
+ for(int i=0;i<to_copy;i++) {
+
+ p_dst[i]=data[pos++];
+ }
+
+ if (to_copy<p_length) {
+ eofed=true;
+ }
+
+
+ return to_copy;
}
Error FileAccessEncrypted::get_error() const{
- return OK;
+ return eofed?ERR_FILE_EOF:OK;
}
void FileAccessEncrypted::store_buffer(const uint8_t *p_src,int p_length) {
@@ -210,8 +285,4 @@ FileAccessEncrypted::~FileAccessEncrypted() {
if (file)
close();
-
- if (file) {
- memdelete(file);
- }
}
diff --git a/core/io/file_access_encrypted.h b/core/io/file_access_encrypted.h
index 90796eb2e9..3bdcc2dfd0 100644
--- a/core/io/file_access_encrypted.h
+++ b/core/io/file_access_encrypted.h
@@ -9,7 +9,8 @@ public:
enum Mode {
MODE_READ,
- MODE_WRITE_AES256
+ MODE_WRITE_AES256,
+ MODE_MAX
};
private:
@@ -22,7 +23,8 @@ private:
size_t base;
size_t length;
Vector<uint8_t> data;
- size_t pos;
+ mutable size_t pos;
+ mutable bool eofed;
public:
diff --git a/core/io/file_access_pack.cpp b/core/io/file_access_pack.cpp
index 45e6990ad2..6a28fa9dae 100644
--- a/core/io/file_access_pack.cpp
+++ b/core/io/file_access_pack.cpp
@@ -211,6 +211,7 @@ void FileAccessPack::seek(size_t p_position){
}
f->seek(pf.offset+p_position);
+ pos=p_position;
}
void FileAccessPack::seek_end(int64_t p_position){
diff --git a/core/io/http_client.cpp b/core/io/http_client.cpp
index f9da846844..59bc5802ea 100644
--- a/core/io/http_client.cpp
+++ b/core/io/http_client.cpp
@@ -27,14 +27,14 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
#include "http_client.h"
-
+#include "io/stream_peer_ssl.h"
Error HTTPClient::connect_url(const String& p_url) {
return OK;
}
-Error HTTPClient::connect(const String &p_host,int p_port){
+Error HTTPClient::connect(const String &p_host, int p_port, bool p_ssl){
close();
conn_port=p_port;
@@ -49,7 +49,11 @@ Error HTTPClient::connect(const String &p_host,int p_port){
}
+ ssl=p_ssl;
connection=tcp_connection;
+
+
+
if (conn_host.is_valid_ip_address()) {
//is ip
Error err = tcp_connection->connect(IP_Address(conn_host),p_port);
@@ -233,6 +237,17 @@ Error HTTPClient::poll(){
return OK; //do none
} break;
case StreamPeerTCP::STATUS_CONNECTED: {
+ if (ssl) {
+ Ref<StreamPeerSSL> ssl = StreamPeerSSL::create();
+ Error err = ssl->connect(tcp_connection,true,conn_host);
+ if (err!=OK) {
+ close();
+ status=STATUS_SSL_HANDSHAKE_ERROR;
+ return ERR_CANT_CONNECT;
+ }
+ print_line("SSL! TURNED ON!");
+ connection=ssl;
+ }
status=STATUS_CONNECTED;
return OK;
} break;
@@ -525,9 +540,20 @@ HTTPClient::Status HTTPClient::get_status() const {
return status;
}
+void HTTPClient::set_blocking_mode(bool p_enable) {
+
+ blocking=p_enable;
+}
+
+bool HTTPClient::is_blocking_mode_enabled() const{
+
+ return blocking;
+}
+
+
void HTTPClient::_bind_methods() {
- ObjectTypeDB::bind_method(_MD("connect:Error","host","port"),&HTTPClient::connect);
+ ObjectTypeDB::bind_method(_MD("connect:Error","host","port","use_ssl"),&HTTPClient::connect,DEFVAL(false));
ObjectTypeDB::bind_method(_MD("set_connection","connection:StreamPeer"),&HTTPClient::set_connection);
ObjectTypeDB::bind_method(_MD("request","method","url","headers","body"),&HTTPClient::request,DEFVAL(String()));
ObjectTypeDB::bind_method(_MD("send_body_text","body"),&HTTPClient::send_body_text);
@@ -542,9 +568,13 @@ void HTTPClient::_bind_methods() {
ObjectTypeDB::bind_method(_MD("get_response_body_length"),&HTTPClient::get_response_body_length);
ObjectTypeDB::bind_method(_MD("read_response_body_chunk"),&HTTPClient::read_response_body_chunk);
+ ObjectTypeDB::bind_method(_MD("set_blocking_mode","enabled"),&HTTPClient::set_blocking_mode);
+ ObjectTypeDB::bind_method(_MD("is_blocking_mode_enabled"),&HTTPClient::is_blocking_mode_enabled);
+
ObjectTypeDB::bind_method(_MD("get_status"),&HTTPClient::get_status);
ObjectTypeDB::bind_method(_MD("poll:Error"),&HTTPClient::poll);
+
BIND_CONSTANT( METHOD_GET );
BIND_CONSTANT( METHOD_HEAD );
BIND_CONSTANT( METHOD_POST );
@@ -564,6 +594,7 @@ void HTTPClient::_bind_methods() {
BIND_CONSTANT( STATUS_REQUESTING ); // request in progress
BIND_CONSTANT( STATUS_BODY ); // request resulted in body ); which must be read
BIND_CONSTANT( STATUS_CONNECTION_ERROR );
+ BIND_CONSTANT( STATUS_SSL_HANDSHAKE_ERROR );
BIND_CONSTANT( RESPONSE_CONTINUE );
@@ -637,7 +668,8 @@ HTTPClient::HTTPClient(){
body_left=0;
chunk_left=0;
response_num=0;
-
+ ssl=false;
+ blocking=false;
tmp_read.resize(4096);
}
diff --git a/core/io/http_client.h b/core/io/http_client.h
index 2f22ba1fde..7e60052319 100644
--- a/core/io/http_client.h
+++ b/core/io/http_client.h
@@ -126,6 +126,8 @@ public:
STATUS_REQUESTING, // request in progress
STATUS_BODY, // request resulted in body, which must be read
STATUS_CONNECTION_ERROR,
+ STATUS_SSL_HANDSHAKE_ERROR,
+
};
private:
@@ -134,6 +136,8 @@ private:
IP::ResolverID resolving;
int conn_port;
String conn_host;
+ bool ssl;
+ bool blocking;
Vector<uint8_t> response_str;
@@ -157,7 +161,7 @@ public:
Error connect_url(const String& p_url); //connects to a full url and perform request
- Error connect(const String &p_host,int p_port);
+ Error connect(const String &p_host,int p_port,bool p_ssl=false);
void set_connection(const Ref<StreamPeer>& p_connection);
@@ -177,6 +181,10 @@ public:
ByteArray read_response_body_chunk(); // can't get body as partial text because of most encodings UTF8, gzip, etc.
+ void set_blocking_mode(bool p_enable); //useful mostly if running in a thread
+ bool is_blocking_mode_enabled() const;
+
+
Error poll();
HTTPClient();
diff --git a/core/io/stream_peer_ssl.cpp b/core/io/stream_peer_ssl.cpp
new file mode 100644
index 0000000000..a7132d99ef
--- /dev/null
+++ b/core/io/stream_peer_ssl.cpp
@@ -0,0 +1,29 @@
+#include "stream_peer_ssl.h"
+
+
+StreamPeerSSL* (*StreamPeerSSL::_create)()=NULL;
+
+
+StreamPeerSSL *StreamPeerSSL::create() {
+
+ return _create();
+}
+
+
+void StreamPeerSSL::_bind_methods() {
+
+
+ ObjectTypeDB::bind_method(_MD("accept:Error","stream:StreamPeer"),&StreamPeerSSL::accept);
+ ObjectTypeDB::bind_method(_MD("connect:Error","stream:StreamPeer","validate_certs","for_hostname"),&StreamPeerSSL::connect,DEFVAL(false),DEFVAL(String()));
+ ObjectTypeDB::bind_method(_MD("get_status"),&StreamPeerSSL::get_status);
+ ObjectTypeDB::bind_method(_MD("disconnect"),&StreamPeerSSL::disconnect);
+ BIND_CONSTANT( STATUS_DISCONNECTED );
+ BIND_CONSTANT( STATUS_CONNECTED );
+ BIND_CONSTANT( STATUS_ERROR_NO_CERTIFICATE );
+ BIND_CONSTANT( STATUS_ERROR_HOSTNAME_MISMATCH );
+
+}
+
+StreamPeerSSL::StreamPeerSSL()
+{
+}
diff --git a/core/io/stream_peer_ssl.h b/core/io/stream_peer_ssl.h
new file mode 100644
index 0000000000..be7504cd8f
--- /dev/null
+++ b/core/io/stream_peer_ssl.h
@@ -0,0 +1,34 @@
+#ifndef STREAM_PEER_SSL_H
+#define STREAM_PEER_SSL_H
+
+#include "io/stream_peer.h"
+
+class StreamPeerSSL : public StreamPeer {
+ OBJ_TYPE(StreamPeerSSL,StreamPeer);
+protected:
+ static StreamPeerSSL* (*_create)();
+ static void _bind_methods();
+public:
+
+ enum Status {
+ STATUS_DISCONNECTED,
+ STATUS_CONNECTED,
+ STATUS_ERROR_NO_CERTIFICATE,
+ STATUS_ERROR_HOSTNAME_MISMATCH
+ };
+
+ virtual Error accept(Ref<StreamPeer> p_base)=0;
+ virtual Error connect(Ref<StreamPeer> p_base,bool p_validate_certs=false,const String& p_for_hostname=String())=0;
+ virtual Status get_status() const=0;
+
+ virtual void disconnect()=0;
+
+ static StreamPeerSSL* create();
+
+
+ StreamPeerSSL();
+};
+
+VARIANT_ENUM_CAST( StreamPeerSSL::Status );
+
+#endif // STREAM_PEER_SSL_H
diff --git a/core/io/stream_peer_tcp.cpp b/core/io/stream_peer_tcp.cpp
index 13a158ea4d..0e75e22767 100644
--- a/core/io/stream_peer_tcp.cpp
+++ b/core/io/stream_peer_tcp.cpp
@@ -34,9 +34,16 @@ void StreamPeerTCP::_bind_methods() {
ObjectTypeDB::bind_method(_MD("connect","host","ip"),&StreamPeerTCP::connect);
ObjectTypeDB::bind_method(_MD("is_connected"),&StreamPeerTCP::is_connected);
+ ObjectTypeDB::bind_method(_MD("get_status"),&StreamPeerTCP::get_status);
ObjectTypeDB::bind_method(_MD("get_connected_host"),&StreamPeerTCP::get_connected_host);
ObjectTypeDB::bind_method(_MD("get_connected_port"),&StreamPeerTCP::get_connected_port);
ObjectTypeDB::bind_method(_MD("disconnect"),&StreamPeerTCP::disconnect);
+
+ BIND_CONSTANT( STATUS_NONE );
+ BIND_CONSTANT( STATUS_CONNECTING );
+ BIND_CONSTANT( STATUS_CONNECTED );
+ BIND_CONSTANT( STATUS_ERROR );
+
}
Ref<StreamPeerTCP> StreamPeerTCP::create_ref() {
diff --git a/core/io/stream_peer_tcp.h b/core/io/stream_peer_tcp.h
index 69c9d0c592..d447ded78b 100644
--- a/core/io/stream_peer_tcp.h
+++ b/core/io/stream_peer_tcp.h
@@ -73,4 +73,6 @@ public:
~StreamPeerTCP();
};
+VARIANT_ENUM_CAST( StreamPeerTCP::Status );
+
#endif