From e3fb6789b0004c7162efde679632bf094b7b0eec Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sun, 18 Dec 2005 17:10:24 +0100 Subject: Initial work on a SSPI SSL backend --- protocols/ssl_sspi.c | 210 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 210 insertions(+) create mode 100644 protocols/ssl_sspi.c (limited to 'protocols') diff --git a/protocols/ssl_sspi.c b/protocols/ssl_sspi.c new file mode 100644 index 00000000..2129f07b --- /dev/null +++ b/protocols/ssl_sspi.c @@ -0,0 +1,210 @@ + /********************************************************************\ + * BitlBee -- An IRC to other IM-networks gateway * + * * + * Copyright 2002-2004 Wilmer van der Gaast and others * + \********************************************************************/ + +/* SSL module - SSPI backend */ + +/* Copyright (C) 2005 Jelmer Vernooij */ + +/* + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License with + the Debian GNU/Linux distribution in /usr/share/common-licenses/GPL; + if not, write to the Free Software Foundation, Inc., 59 Temple Place, + Suite 330, Boston, MA 02111-1307 USA +*/ + +#include "ssl_client.h" +#include +#define SECURITY_WIN32 +#include +#include +#include + +static gboolean initialized = FALSE; +int ssl_errno; + +struct scd +{ + int fd; + SslInputFunction func; + gpointer data; + gboolean established; + int inpa; + CredHandle cred; /* SSL credentials */ + CtxtHandle context; /* SSL context */ + SecPkgContext_StreamSizes sizes; +}; + +static void ssl_connected( gpointer data, gint source, GaimInputCondition cond ); + +void sspi_global_init( void ) +{ + /* FIXME */ +} + +void sspi_global_deinit( void ) +{ + /* FIXME */ +} + +void *ssl_connect( char *host, int port, SslInputFunction func, gpointer data ) +{ + struct scd *conn = g_new0( struct scd, 1 ); + SCHANNEL_CRED ssl_cred; + TimeStamp timestamp; + + conn->fd = proxy_connect( host, port, ssl_connected, conn ); + conn->func = func; + conn->data = data; + conn->inpa = -1; + + if( conn->fd < 0 ) + { + g_free( conn ); + return( NULL ); + } + + if( !initialized ) + { + sspi_global_init(); + initialized = TRUE; + atexit( sspi_global_deinit ); + } + + conn->context = NULL; + + memset(&ssl_cred, 0, sizeof(SCHANNEL_CRED)); + ssl_cred.dwVersion = SCHANNEL_CRED_VERSION; + ssl_cred.grbitEnabledProtocols = SP_PROT_SSL3_CLIENT; + + SECURITY_STATUS st = AcquireCredentialsHandle(NULL, UNISP_NAME, SECPKG_CRED_OUTBOUND, NULL, &ssl_cred, NULL, NULL, &conn->cred, ×tamp); + + InitializeSecurityContext(&conn->cred, &conn->context, host, FIXME, 1, FIXME); + + QueryContextAttributes(&conn->context, SECPKG_ATTR_STREAM_SIZES, &conn->sizes); + + + return( conn ); +} + +int ssl_read( void *conn, char *retdata, int len ) +{ + struct scd *scd = conn; + SecBufferDesc msg; + SecBuffer buf[4]; + int ret = -1, i; + char *data = g_malloc(scd->sizes.cbHeader + scd->sizes.cbMaximumMessage + scd->sizes.cbTrailer); + + /* FIXME: Try to read some data */ + + msg.ulVersion = SECBUFFER_VERSION; + msg.cBuffers = 4; + msg.pBuffers = buf; + + buf[0].BufferType = SECBUFFER_DATA; + buf[0].cbBuffer = len; + buf[0].pvBuffer = data; + + buf[1].BufferType = SECBUFFER_EMPTY; + buf[2].BufferType = SECBUFFER_EMPTY; + buf[3].BufferType = SECBUFFER_EMPTY; + + SECURITY_STATUS st = DecryptMessage(&scd->context, &msg, 0, NULL); + + for (i = 0; i < 4; i++) { + if (buf[i].BufferType == SECBUFFER_DATA) { + memcpy(retdata, buf[i].pvBuffer, len); + ret = len; + } + } + + g_free(data); + return( -1 ); +} + +int ssl_write( void *conn, const char *userdata, int len ) +{ + struct scd *scd = conn; + SecBuffer buf[4]; + SecBufferDesc msg; + char *data; + int ret; + + msg.ulVersion = SECBUFFER_VERSION; + msg.cBuffers = 4; + msg.pBuffers = buf; + + data = g_malloc(scd->sizes.cbHeader + scd->sizes.cbMaximumMessage + scd->sizes.cbTrailer); + memcpy(data + scd->sizes.cbHeader, userdata, len); + + buf[0].BufferType = SECBUFFER_STREAM_HEADER; + buf[0].cbBuffer = scd->sizes.cbHeader; + buf[0].pvBuffer = data; + + buf[1].BufferType = SECBUFFER_DATA; + buf[1].cbBuffer = len; + buf[1].pvBuffer = data + scd->sizes.cbHeader; + + buf[2].BufferType = SECBUFFER_STREAM_TRAILER; + buf[2].cbBuffer = scd->sizes.cbTrailer; + buf[2].pvBuffer = data + scd->sizes.cbHeader + len; + buf[3].BufferType = SECBUFFER_EMPTY; + + SECURITY_STATUS st = EncryptMessage(&scd->context, 0, &msg, 0); + + ret = send(scd->fd, data, + buf[0].cbBuffer + buf[1].cbBuffer + buf[2].cbBuffer, 0); + + g_free(data); + + return ret; +} + +void ssl_disconnect( void *conn ) +{ + struct scd *scd = conn; + + SecBufferDesc msg; + SecBuffer buf; + DWORD dw; + + dw = SCHANNEL_SHUTDOWN; + buf.cbBuffer = sizeof(dw); + buf.BufferType = SECBUFFER_TOKEN; + buf.pvBuffer = &dw; + + msg.ulVersion = SECBUFFER_VERSION; + msg.cBuffers = 1; + msg.pBuffers = &buf; + + SECURITY_STATUS st = ApplyControlToken(&scd->context, &msg); + + if (st != SEC_E_OK) { + /* FIXME */ + } + + /* FIXME: call InitializeSecurityContext(Schannel), passing + * in empty buffers*/ + + DeleteSecurityContext(&scd->context); + + closesocket( scd->fd ); + g_free(scd); +} + +int ssl_getfd( void *conn ) +{ + return( ((struct scd*)conn)->fd ); +} -- cgit v1.2.3 From 80c1e4d9e8c82a83499d6b66cdf3a95d15bf0fa1 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Thu, 25 May 2006 01:31:20 +0200 Subject: #ifdef out some Win32-incompatible code blocks --- protocols/ssl_sspi.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'protocols') diff --git a/protocols/ssl_sspi.c b/protocols/ssl_sspi.c index 2129f07b..0529b4ec 100644 --- a/protocols/ssl_sspi.c +++ b/protocols/ssl_sspi.c @@ -38,7 +38,7 @@ int ssl_errno; struct scd { int fd; - SslInputFunction func; + ssl_input_function func; gpointer data; gboolean established; int inpa; @@ -59,7 +59,7 @@ void sspi_global_deinit( void ) /* FIXME */ } -void *ssl_connect( char *host, int port, SslInputFunction func, gpointer data ) +void *ssl_connect( char *host, int port, ssl_input_function func, gpointer data ) { struct scd *conn = g_new0( struct scd, 1 ); SCHANNEL_CRED ssl_cred; -- cgit v1.2.3 From 51a4ffb83d6fbe23f1c2b8499cc78584e7213812 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Thu, 25 May 2006 11:55:00 +0200 Subject: Some more work on SSL on Windows --- protocols/ssl_sspi.c | 42 ++++++++++++++++++++++++++++++++++++++---- 1 file changed, 38 insertions(+), 4 deletions(-) (limited to 'protocols') diff --git a/protocols/ssl_sspi.c b/protocols/ssl_sspi.c index 0529b4ec..c6d7def9 100644 --- a/protocols/ssl_sspi.c +++ b/protocols/ssl_sspi.c @@ -64,6 +64,13 @@ void *ssl_connect( char *host, int port, ssl_input_function func, gpointer data struct scd *conn = g_new0( struct scd, 1 ); SCHANNEL_CRED ssl_cred; TimeStamp timestamp; + SecBuffer ibuf[2],obuf[1]; + SecBufferDesc ibufs,obufs; + ULONG req = ISC_REQ_REPLAY_DETECT | ISC_REQ_SEQUENCE_DETECT | + ISC_REQ_CONFIDENTIALITY | ISC_REQ_USE_SESSION_KEY | + ISC_REQ_ALLOCATE_MEMORY | ISC_REQ_STREAM | ISC_REQ_EXTENDED_ERROR | + ISC_REQ_MANUAL_CRED_VALIDATION; + ULONG a; conn->fd = proxy_connect( host, port, ssl_connected, conn ); conn->func = func; @@ -83,17 +90,42 @@ void *ssl_connect( char *host, int port, ssl_input_function func, gpointer data atexit( sspi_global_deinit ); } - conn->context = NULL; - memset(&ssl_cred, 0, sizeof(SCHANNEL_CRED)); ssl_cred.dwVersion = SCHANNEL_CRED_VERSION; ssl_cred.grbitEnabledProtocols = SP_PROT_SSL3_CLIENT; SECURITY_STATUS st = AcquireCredentialsHandle(NULL, UNISP_NAME, SECPKG_CRED_OUTBOUND, NULL, &ssl_cred, NULL, NULL, &conn->cred, ×tamp); + + if (st != SEC_E_OK) + return NULL; + + do { + /* initialize buffers */ + ibuf[0].cbBuffer = size; ibuf[0].pvBuffer = buf; + ibuf[1].cbBuffer = 0; ibuf[1].pvBuffer = NIL; + obuf[0].cbBuffer = 0; obuf[0].pvBuffer = NIL; + ibuf[0].BufferType = obuf[0].BufferType = SECBUFFER_TOKEN; + ibuf[1].BufferType = SECBUFFER_EMPTY; + + /* initialize buffer descriptors */ + ibufs.ulVersion = obufs.ulVersion = SECBUFFER_VERSION; + ibufs.cBuffers = 2; obufs.cBuffers = 1; + ibufs.pBuffers = ibuf; obufs.pBuffers = obuf; + + st = InitializeSecurityContext(&conn->cred, size?&conn->context:NULL, host, req, 0, SECURITY_NETWORK_DREP, size?&ibufs:NULL, 0, &conn->context, &obufs, &a, ×tamp); + if (obuf[0].pvBuffer && obuf[0].cbBuffer) { + send(conn->fd, obuf[0].pvBuffer, obuf[0].cbBuffer, 0); + } + + switch (st) { + case SEC_I_INCOMPLETE_CREDENTIALS: + break; + case SEC_I_CONTINUE_NEEDED: + + } - InitializeSecurityContext(&conn->cred, &conn->context, host, FIXME, 1, FIXME); - QueryContextAttributes(&conn->context, SECPKG_ATTR_STREAM_SIZES, &conn->sizes); + QueryContextAttributes(&conn->context, SECPKG_ATTR_STREAM_SIZES, &conn->sizes); return( conn ); @@ -200,6 +232,8 @@ void ssl_disconnect( void *conn ) DeleteSecurityContext(&scd->context); + FreeCredentialHandle(&scd->cred); + closesocket( scd->fd ); g_free(scd); } -- cgit v1.2.3 From 1cda4f348372a755d99b291e6f4f9973a949f441 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Fri, 26 May 2006 17:02:09 +0200 Subject: Fix some unresolved symbols. --- protocols/oscar/AUTHORS | 2 -- protocols/ssl_sspi.c | 81 ++++++++++++++++++++++++++++++++----------------- 2 files changed, 53 insertions(+), 30 deletions(-) (limited to 'protocols') diff --git a/protocols/oscar/AUTHORS b/protocols/oscar/AUTHORS index 5ca13988..51e8768d 100644 --- a/protocols/oscar/AUTHORS +++ b/protocols/oscar/AUTHORS @@ -27,5 +27,3 @@ N: Brock Wilcox H: awwaiid E: awwaiid@auk.cx D: Figured out original password roasting - - diff --git a/protocols/ssl_sspi.c b/protocols/ssl_sspi.c index 110f0af2..a16423b1 100644 --- a/protocols/ssl_sspi.c +++ b/protocols/ssl_sspi.c @@ -31,6 +31,7 @@ #include #include #include +#include "sock.h" static gboolean initialized = FALSE; int ssl_errno; @@ -41,52 +42,59 @@ struct scd ssl_input_function func; gpointer data; gboolean established; - int inpa; CredHandle cred; /* SSL credentials */ CtxtHandle context; /* SSL context */ SecPkgContext_StreamSizes sizes; + + char *host; + + char *pending_raw_data; + gsize pending_raw_data_len; + char *pending_data; + gsize pending_data_len; }; static void ssl_connected(gpointer, gint, GaimInputCondition); -void sspi_global_init( void ) +void sspi_global_init(void) { /* FIXME */ } -void sspi_global_deinit( void ) +void sspi_global_deinit(void) { /* FIXME */ } -void *ssl_connect( char *host, int port, ssl_input_function func, gpointer data ) +void *ssl_connect(char *host, int port, ssl_input_function func, gpointer data) { - struct scd *conn = g_new0( struct scd, 1 ); + struct scd *conn = g_new0(struct scd, 1); - conn->fd = proxy_connect( host, port, ssl_connected, conn ); + conn->fd = proxy_connect(host, port, ssl_connected, conn); + sock_make_nonblocking(conn->fd); conn->func = func; conn->data = data; - conn->inpa = -1; + conn->host = g_strdup(host); - if( conn->fd < 0 ) + if (conn->fd < 0) { - g_free( conn ); - return( NULL ); + g_free(conn); + return NULL; } - if( !initialized ) + if (!initialized) { sspi_global_init(); initialized = TRUE; - atexit( sspi_global_deinit ); + atexit(sspi_global_deinit); } return conn; } -static void ssl_connected(gpointer data, gint fd, GaimInputCondition cond) +static void ssl_connected(gpointer _conn, gint fd, GaimInputCondition cond) { - struct scd *conn = data; + struct scd *conn = _conn; SCHANNEL_CRED ssl_cred; TimeStamp timestamp; SecBuffer ibuf[2],obuf[1]; @@ -96,6 +104,8 @@ static void ssl_connected(gpointer data, gint fd, GaimInputCondition cond) ISC_REQ_ALLOCATE_MEMORY | ISC_REQ_STREAM | ISC_REQ_EXTENDED_ERROR | ISC_REQ_MANUAL_CRED_VALIDATION; ULONG a; + gsize size = 0; + gchar *data = NULL; memset(&ssl_cred, 0, sizeof(SCHANNEL_CRED)); ssl_cred.dwVersion = SCHANNEL_CRED_VERSION; @@ -104,13 +114,13 @@ static void ssl_connected(gpointer data, gint fd, GaimInputCondition cond) SECURITY_STATUS st = AcquireCredentialsHandle(NULL, UNISP_NAME, SECPKG_CRED_OUTBOUND, NULL, &ssl_cred, NULL, NULL, &conn->cred, ×tamp); if (st != SEC_E_OK) { - conn->func( conn->data, NULL, cond ); + conn->func(conn->data, NULL, cond); return; - + } do { /* initialize buffers */ - ibuf[0].cbBuffer = size; ibuf[0].pvBuffer = buf; + ibuf[0].cbBuffer = size; ibuf[0].pvBuffer = data; ibuf[1].cbBuffer = 0; ibuf[1].pvBuffer = NULL; obuf[0].cbBuffer = 0; obuf[0].pvBuffer = NULL; ibuf[0].BufferType = obuf[0].BufferType = SECBUFFER_TOKEN; @@ -121,8 +131,9 @@ static void ssl_connected(gpointer data, gint fd, GaimInputCondition cond) ibufs.cBuffers = 2; obufs.cBuffers = 1; ibufs.pBuffers = ibuf; obufs.pBuffers = obuf; - st = InitializeSecurityContext(&conn->cred, size?&conn->context:NULL, host, req, 0, SECURITY_NETWORK_DREP, size?&ibufs:NULL, 0, &conn->context, &obufs, &a, ×tamp); + st = InitializeSecurityContext(&conn->cred, size?&conn->context:NULL, conn->host, req, 0, SECURITY_NETWORK_DREP, size?&ibufs:NULL, 0, &conn->context, &obufs, &a, ×tamp); if (obuf[0].pvBuffer && obuf[0].cbBuffer) { + /* FIXME: Check return value */ send(conn->fd, obuf[0].pvBuffer, obuf[0].cbBuffer, 0); } @@ -130,17 +141,20 @@ static void ssl_connected(gpointer data, gint fd, GaimInputCondition cond) case SEC_I_INCOMPLETE_CREDENTIALS: break; case SEC_I_CONTINUE_NEEDED: - + break; + case SEC_E_INCOMPLETE_MESSAGE: + break; + case SEC_E_OK: + break; } - QueryContextAttributes(&conn->context, SECPKG_ATTR_STREAM_SIZES, &conn->sizes); } while (1); - conn->func( conn->data, conn, cond ); + conn->func(conn->data, conn, cond); } -int ssl_read( void *conn, char *retdata, int len ) +int ssl_read(void *conn, char *retdata, int len) { struct scd *scd = conn; SecBufferDesc msg; @@ -164,6 +178,11 @@ int ssl_read( void *conn, char *retdata, int len ) SECURITY_STATUS st = DecryptMessage(&scd->context, &msg, 0, NULL); + if (st != SEC_E_OK) { + /* FIXME */ + return -1; + } + for (i = 0; i < 4; i++) { if (buf[i].BufferType == SECBUFFER_DATA) { memcpy(retdata, buf[i].pvBuffer, len); @@ -172,10 +191,10 @@ int ssl_read( void *conn, char *retdata, int len ) } g_free(data); - return( -1 ); + return -1; } -int ssl_write( void *conn, const char *userdata, int len ) +int ssl_write(void *conn, const char *userdata, int len) { struct scd *scd = conn; SecBuffer buf[4]; @@ -213,7 +232,7 @@ int ssl_write( void *conn, const char *userdata, int len ) return ret; } -void ssl_disconnect( void *conn ) +void ssl_disconnect(void *conn) { struct scd *scd = conn; @@ -243,11 +262,17 @@ void ssl_disconnect( void *conn ) FreeCredentialsHandle(&scd->cred); - closesocket( scd->fd ); + closesocket(scd->fd); + g_free(scd->host); g_free(scd); } -int ssl_getfd( void *conn ) +int ssl_getfd(void *conn) +{ + return ((struct scd*)conn)->fd; +} + +GaimInputCondition ssl_getdirection( void *conn ) { - return( ((struct scd*)conn)->fd ); + return GAIM_INPUT_WRITE; /* FIXME: or GAIM_INPUT_READ */ } -- cgit v1.2.3 From fcc2da97bcfa5e0d704179fae9c4ed59cbaf79c5 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Fri, 26 May 2006 17:46:51 +0200 Subject: Remove unnecessary Windows-specific code. --- protocols/yahoo/libyahoo2.c | 2 -- protocols/yahoo/yahoo_httplib.c | 2 -- 2 files changed, 4 deletions(-) (limited to 'protocols') diff --git a/protocols/yahoo/libyahoo2.c b/protocols/yahoo/libyahoo2.c index c691f18b..967ba681 100644 --- a/protocols/yahoo/libyahoo2.c +++ b/protocols/yahoo/libyahoo2.c @@ -68,8 +68,6 @@ char *strchr (), *strrchr (); #ifdef __MINGW32__ # include -# define write(a,b,c) send(a,b,c,0) -# define read(a,b,c) recv(a,b,c,0) #endif #include diff --git a/protocols/yahoo/yahoo_httplib.c b/protocols/yahoo/yahoo_httplib.c index dbbe2a84..1b084992 100644 --- a/protocols/yahoo/yahoo_httplib.c +++ b/protocols/yahoo/yahoo_httplib.c @@ -50,8 +50,6 @@ char *strchr (), *strrchr (); #include "yahoo_debug.h" #ifdef __MINGW32__ # include -# define write(a,b,c) send(a,b,c,0) -# define read(a,b,c) recv(a,b,c,0) # define snprintf _snprintf #endif -- cgit v1.2.3 From 21e5d4981de057bae5261720021757d893061652 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Tue, 10 Jun 2008 05:16:15 +0200 Subject: Move SSPI SSL implementation to same directory as other SSL backends. --- protocols/ssl_sspi.c | 278 --------------------------------------------------- 1 file changed, 278 deletions(-) delete mode 100644 protocols/ssl_sspi.c (limited to 'protocols') diff --git a/protocols/ssl_sspi.c b/protocols/ssl_sspi.c deleted file mode 100644 index a16423b1..00000000 --- a/protocols/ssl_sspi.c +++ /dev/null @@ -1,278 +0,0 @@ - /********************************************************************\ - * BitlBee -- An IRC to other IM-networks gateway * - * * - * Copyright 2002-2004 Wilmer van der Gaast and others * - \********************************************************************/ - -/* SSL module - SSPI backend */ - -/* Copyright (C) 2005 Jelmer Vernooij */ - -/* - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License with - the Debian GNU/Linux distribution in /usr/share/common-licenses/GPL; - if not, write to the Free Software Foundation, Inc., 59 Temple Place, - Suite 330, Boston, MA 02111-1307 USA -*/ - -#include "ssl_client.h" -#include -#define SECURITY_WIN32 -#include -#include -#include -#include "sock.h" - -static gboolean initialized = FALSE; -int ssl_errno; - -struct scd -{ - int fd; - ssl_input_function func; - gpointer data; - gboolean established; - CredHandle cred; /* SSL credentials */ - CtxtHandle context; /* SSL context */ - SecPkgContext_StreamSizes sizes; - - char *host; - - char *pending_raw_data; - gsize pending_raw_data_len; - char *pending_data; - gsize pending_data_len; -}; - -static void ssl_connected(gpointer, gint, GaimInputCondition); - -void sspi_global_init(void) -{ - /* FIXME */ -} - -void sspi_global_deinit(void) -{ - /* FIXME */ -} - -void *ssl_connect(char *host, int port, ssl_input_function func, gpointer data) -{ - struct scd *conn = g_new0(struct scd, 1); - - conn->fd = proxy_connect(host, port, ssl_connected, conn); - sock_make_nonblocking(conn->fd); - conn->func = func; - conn->data = data; - conn->host = g_strdup(host); - - if (conn->fd < 0) - { - g_free(conn); - return NULL; - } - - if (!initialized) - { - sspi_global_init(); - initialized = TRUE; - atexit(sspi_global_deinit); - } - - return conn; -} - -static void ssl_connected(gpointer _conn, gint fd, GaimInputCondition cond) -{ - struct scd *conn = _conn; - SCHANNEL_CRED ssl_cred; - TimeStamp timestamp; - SecBuffer ibuf[2],obuf[1]; - SecBufferDesc ibufs,obufs; - ULONG req = ISC_REQ_REPLAY_DETECT | ISC_REQ_SEQUENCE_DETECT | - ISC_REQ_CONFIDENTIALITY | ISC_REQ_USE_SESSION_KEY | - ISC_REQ_ALLOCATE_MEMORY | ISC_REQ_STREAM | ISC_REQ_EXTENDED_ERROR | - ISC_REQ_MANUAL_CRED_VALIDATION; - ULONG a; - gsize size = 0; - gchar *data = NULL; - - memset(&ssl_cred, 0, sizeof(SCHANNEL_CRED)); - ssl_cred.dwVersion = SCHANNEL_CRED_VERSION; - ssl_cred.grbitEnabledProtocols = SP_PROT_SSL3_CLIENT; - - SECURITY_STATUS st = AcquireCredentialsHandle(NULL, UNISP_NAME, SECPKG_CRED_OUTBOUND, NULL, &ssl_cred, NULL, NULL, &conn->cred, ×tamp); - - if (st != SEC_E_OK) { - conn->func(conn->data, NULL, cond); - return; - } - - do { - /* initialize buffers */ - ibuf[0].cbBuffer = size; ibuf[0].pvBuffer = data; - ibuf[1].cbBuffer = 0; ibuf[1].pvBuffer = NULL; - obuf[0].cbBuffer = 0; obuf[0].pvBuffer = NULL; - ibuf[0].BufferType = obuf[0].BufferType = SECBUFFER_TOKEN; - ibuf[1].BufferType = SECBUFFER_EMPTY; - - /* initialize buffer descriptors */ - ibufs.ulVersion = obufs.ulVersion = SECBUFFER_VERSION; - ibufs.cBuffers = 2; obufs.cBuffers = 1; - ibufs.pBuffers = ibuf; obufs.pBuffers = obuf; - - st = InitializeSecurityContext(&conn->cred, size?&conn->context:NULL, conn->host, req, 0, SECURITY_NETWORK_DREP, size?&ibufs:NULL, 0, &conn->context, &obufs, &a, ×tamp); - if (obuf[0].pvBuffer && obuf[0].cbBuffer) { - /* FIXME: Check return value */ - send(conn->fd, obuf[0].pvBuffer, obuf[0].cbBuffer, 0); - } - - switch (st) { - case SEC_I_INCOMPLETE_CREDENTIALS: - break; - case SEC_I_CONTINUE_NEEDED: - break; - case SEC_E_INCOMPLETE_MESSAGE: - break; - case SEC_E_OK: - break; - } - - QueryContextAttributes(&conn->context, SECPKG_ATTR_STREAM_SIZES, &conn->sizes); - } while (1); - - conn->func(conn->data, conn, cond); -} - -int ssl_read(void *conn, char *retdata, int len) -{ - struct scd *scd = conn; - SecBufferDesc msg; - SecBuffer buf[4]; - int ret = -1, i; - char *data = g_malloc(scd->sizes.cbHeader + scd->sizes.cbMaximumMessage + scd->sizes.cbTrailer); - - /* FIXME: Try to read some data */ - - msg.ulVersion = SECBUFFER_VERSION; - msg.cBuffers = 4; - msg.pBuffers = buf; - - buf[0].BufferType = SECBUFFER_DATA; - buf[0].cbBuffer = len; - buf[0].pvBuffer = data; - - buf[1].BufferType = SECBUFFER_EMPTY; - buf[2].BufferType = SECBUFFER_EMPTY; - buf[3].BufferType = SECBUFFER_EMPTY; - - SECURITY_STATUS st = DecryptMessage(&scd->context, &msg, 0, NULL); - - if (st != SEC_E_OK) { - /* FIXME */ - return -1; - } - - for (i = 0; i < 4; i++) { - if (buf[i].BufferType == SECBUFFER_DATA) { - memcpy(retdata, buf[i].pvBuffer, len); - ret = len; - } - } - - g_free(data); - return -1; -} - -int ssl_write(void *conn, const char *userdata, int len) -{ - struct scd *scd = conn; - SecBuffer buf[4]; - SecBufferDesc msg; - char *data; - int ret; - - msg.ulVersion = SECBUFFER_VERSION; - msg.cBuffers = 4; - msg.pBuffers = buf; - - data = g_malloc(scd->sizes.cbHeader + scd->sizes.cbMaximumMessage + scd->sizes.cbTrailer); - memcpy(data + scd->sizes.cbHeader, userdata, len); - - buf[0].BufferType = SECBUFFER_STREAM_HEADER; - buf[0].cbBuffer = scd->sizes.cbHeader; - buf[0].pvBuffer = data; - - buf[1].BufferType = SECBUFFER_DATA; - buf[1].cbBuffer = len; - buf[1].pvBuffer = data + scd->sizes.cbHeader; - - buf[2].BufferType = SECBUFFER_STREAM_TRAILER; - buf[2].cbBuffer = scd->sizes.cbTrailer; - buf[2].pvBuffer = data + scd->sizes.cbHeader + len; - buf[3].BufferType = SECBUFFER_EMPTY; - - SECURITY_STATUS st = EncryptMessage(&scd->context, 0, &msg, 0); - - ret = send(scd->fd, data, - buf[0].cbBuffer + buf[1].cbBuffer + buf[2].cbBuffer, 0); - - g_free(data); - - return ret; -} - -void ssl_disconnect(void *conn) -{ - struct scd *scd = conn; - - SecBufferDesc msg; - SecBuffer buf; - DWORD dw; - - dw = SCHANNEL_SHUTDOWN; - buf.cbBuffer = sizeof(dw); - buf.BufferType = SECBUFFER_TOKEN; - buf.pvBuffer = &dw; - - msg.ulVersion = SECBUFFER_VERSION; - msg.cBuffers = 1; - msg.pBuffers = &buf; - - SECURITY_STATUS st = ApplyControlToken(&scd->context, &msg); - - if (st != SEC_E_OK) { - /* FIXME */ - } - - /* FIXME: call InitializeSecurityContext(Schannel), passing - * in empty buffers*/ - - DeleteSecurityContext(&scd->context); - - FreeCredentialsHandle(&scd->cred); - - closesocket(scd->fd); - g_free(scd->host); - g_free(scd); -} - -int ssl_getfd(void *conn) -{ - return ((struct scd*)conn)->fd; -} - -GaimInputCondition ssl_getdirection( void *conn ) -{ - return GAIM_INPUT_WRITE; /* FIXME: or GAIM_INPUT_READ */ -} -- cgit v1.2.3