diff options
Diffstat (limited to 'protocols')
-rw-r--r-- | protocols/Makefile | 2 | ||||
-rw-r--r-- | protocols/events.h | 66 | ||||
-rw-r--r-- | protocols/events_glib.c | 137 | ||||
-rw-r--r-- | protocols/events_libevent.c | 247 | ||||
-rw-r--r-- | protocols/http_client.c | 453 | ||||
-rw-r--r-- | protocols/http_client.h | 57 | ||||
-rw-r--r-- | protocols/jabber/jabber.c | 106 | ||||
-rw-r--r-- | protocols/md5.c | 392 | ||||
-rw-r--r-- | protocols/md5.h | 85 | ||||
-rw-r--r-- | protocols/msn/msn.c | 98 | ||||
-rw-r--r-- | protocols/msn/ns.c | 16 | ||||
-rw-r--r-- | protocols/nogaim.c | 153 | ||||
-rw-r--r-- | protocols/nogaim.h | 29 | ||||
-rw-r--r-- | protocols/oscar/oscar.c | 53 | ||||
-rw-r--r-- | protocols/proxy.c | 552 | ||||
-rw-r--r-- | protocols/proxy.h | 53 | ||||
-rw-r--r-- | protocols/sha.c | 173 | ||||
-rw-r--r-- | protocols/sha.h | 21 | ||||
-rw-r--r-- | protocols/ssl_bogus.c | 57 | ||||
-rw-r--r-- | protocols/ssl_client.h | 42 | ||||
-rw-r--r-- | protocols/ssl_gnutls.c | 206 | ||||
-rw-r--r-- | protocols/ssl_nss.c | 190 | ||||
-rw-r--r-- | protocols/ssl_openssl.c | 221 | ||||
-rw-r--r-- | protocols/yahoo/libyahoo2.c | 30 | ||||
-rw-r--r-- | protocols/yahoo/yahoo.c | 11 |
25 files changed, 272 insertions, 3178 deletions
diff --git a/protocols/Makefile b/protocols/Makefile index b74212f4..cc45fb09 100644 --- a/protocols/Makefile +++ b/protocols/Makefile @@ -9,7 +9,7 @@ -include ../Makefile.settings # [SH] Program variables -objects = $(EVENT_HANDLER) http_client.o md5.o nogaim.o proxy.o sha.o $(SSL_CLIENT) +objects = nogaim.o # [SH] The next two lines should contain the directory name (in $(subdirs)) # and the name of the object file, which should be linked into diff --git a/protocols/events.h b/protocols/events.h deleted file mode 100644 index 781fca6a..00000000 --- a/protocols/events.h +++ /dev/null @@ -1,66 +0,0 @@ -/* - * nogaim - * - * Copyright (C) 2006 Wilmer van der Gaast and others - * - * 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 - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - */ - -/* - * Split off the event handling things from proxy.[ch] (and adding timer - * stuff. This to allow BitlBee to use other libs than GLib for event - * handling. - */ - - -#ifndef _EVENTS_H_ -#define _EVENTS_H_ - -#include <sys/types.h> -#ifndef _WIN32 -#include <sys/socket.h> -#include <netdb.h> -#include <netinet/in.h> -#endif -#include <glib.h> -#include <gmodule.h> - -typedef enum { - GAIM_INPUT_READ = 1 << 1, - GAIM_INPUT_WRITE = 1 << 2 -} b_input_condition; -typedef gboolean (*b_event_handler)(gpointer data, gint fd, b_input_condition cond); - -#define GAIM_READ_COND (G_IO_IN | G_IO_HUP | G_IO_ERR) -#define GAIM_WRITE_COND (G_IO_OUT | G_IO_HUP | G_IO_ERR | G_IO_NVAL) -#define GAIM_ERR_COND (G_IO_HUP | G_IO_ERR | G_IO_NVAL) - -// #define event_debug( x... ) printf( x ) -#define event_debug( x... ) - -G_MODULE_EXPORT void b_main_init(); -G_MODULE_EXPORT void b_main_run(); -G_MODULE_EXPORT void b_main_quit(); - -G_MODULE_EXPORT gint b_input_add(int fd, b_input_condition cond, b_event_handler func, gpointer data); -G_MODULE_EXPORT gint b_timeout_add(gint timeout, b_event_handler func, gpointer data); -G_MODULE_EXPORT void b_event_remove(gint id); - -#ifdef EVENTS_LIBEVENT -G_MODULE_EXPORT void closesocket(int fd); -#endif - -#endif /* _EVENTS_H_ */ diff --git a/protocols/events_glib.c b/protocols/events_glib.c deleted file mode 100644 index 620720cd..00000000 --- a/protocols/events_glib.c +++ /dev/null @@ -1,137 +0,0 @@ - /********************************************************************\ - * BitlBee -- An IRC to other IM-networks gateway * - * * - * Copyright 2002-2006 Wilmer van der Gaast and others * - \********************************************************************/ - -/* - * Event handling (using GLib) - */ - -/* - 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 -*/ - -#define BITLBEE_CORE -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <sys/types.h> -#ifndef _WIN32 -#include <sys/socket.h> -#include <netdb.h> -#include <netinet/in.h> -#include <arpa/inet.h> -#include <unistd.h> -#else -#include "sock.h" -#define ETIMEDOUT WSAETIMEDOUT -#define EINPROGRESS WSAEINPROGRESS -#endif -#include <fcntl.h> -#include <errno.h> -#include "proxy.h" - -typedef struct _GaimIOClosure { - b_event_handler function; - guint result; - gpointer data; -} GaimIOClosure; - -static GMainLoop *loop; - -void b_main_init() -{ - loop = g_main_new( FALSE ); -} - -void b_main_run() -{ - g_main_run( loop ); -} - -void b_main_quit() -{ - g_main_quit( loop ); -} - -static gboolean gaim_io_invoke(GIOChannel *source, GIOCondition condition, gpointer data) -{ - GaimIOClosure *closure = data; - b_input_condition gaim_cond = 0; - gboolean st; - - if (condition & GAIM_READ_COND) - gaim_cond |= GAIM_INPUT_READ; - if (condition & GAIM_WRITE_COND) - gaim_cond |= GAIM_INPUT_WRITE; - - event_debug( "gaim_io_invoke( %d, %d, 0x%x )\n", g_io_channel_unix_get_fd(source), condition, data ); - - st = closure->function(closure->data, g_io_channel_unix_get_fd(source), gaim_cond); - - if( !st ) - event_debug( "Returned FALSE, cancelling.\n" ); - - return st; -} - -static void gaim_io_destroy(gpointer data) -{ - event_debug( "gaim_io_destroy( 0x%x )\n", data ); - g_free(data); -} - -gint b_input_add(gint source, b_input_condition condition, b_event_handler function, gpointer data) -{ - GaimIOClosure *closure = g_new0(GaimIOClosure, 1); - GIOChannel *channel; - GIOCondition cond = 0; - - closure->function = function; - closure->data = data; - - if (condition & GAIM_INPUT_READ) - cond |= GAIM_READ_COND; - if (condition & GAIM_INPUT_WRITE) - cond |= GAIM_WRITE_COND; - - channel = g_io_channel_unix_new(source); - closure->result = g_io_add_watch_full(channel, G_PRIORITY_DEFAULT, cond, - gaim_io_invoke, closure, gaim_io_destroy); - - event_debug( "b_input_add( %d, %d, 0x%x, 0x%x ) = %d (0x%x)\n", source, condition, function, data, closure->result, closure ); - - g_io_channel_unref(channel); - return closure->result; -} - -gint b_timeout_add(gint timeout, b_event_handler func, gpointer data) -{ - gint st = g_timeout_add(timeout, func, data); - - event_debug( "b_timeout_add( %d, %d, %d ) = %d\n", timeout, func, data, st ); - - return st; -} - -void b_event_remove(gint tag) -{ - event_debug( "b_event_remove( %d )\n", tag ); - - if (tag > 0) - g_source_remove(tag); -} diff --git a/protocols/events_libevent.c b/protocols/events_libevent.c deleted file mode 100644 index 1119c2ab..00000000 --- a/protocols/events_libevent.c +++ /dev/null @@ -1,247 +0,0 @@ - /********************************************************************\ - * BitlBee -- An IRC to other IM-networks gateway * - * * - * Copyright 2002-2006 Wilmer van der Gaast and others * - \********************************************************************/ - -/* - * Event handling (using libevent) - */ - -/* - 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 -*/ - -#define BITLBEE_CORE -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <unistd.h> -#include <sys/types.h> -#include "proxy.h" - -#include <sys/time.h> -#include <event.h> - -static guint id_next; -static GHashTable *id_hash; -static int quitting = 0; - -/* Since libevent doesn't handle two event handlers for one fd-condition - very well (which happens sometimes when BitlBee changes event handlers - for a combination), let's buid some indexes so we can delete them here - already, just in time. */ -static GHashTable *read_hash; -static GHashTable *write_hash; - -struct b_event_data -{ - guint id; - struct event evinfo; - gint timeout; - b_event_handler function; - void *data; -}; - -void b_main_init() -{ - event_init(); - - id_next = 1; - id_hash = g_hash_table_new( g_int_hash, g_int_equal ); - read_hash = g_hash_table_new( g_int_hash, g_int_equal ); - write_hash = g_hash_table_new( g_int_hash, g_int_equal ); -} - -void b_main_run() -{ - event_dispatch(); -} - -void b_main_quit() -{ - struct timeval tv; - - /* libevent sometimes generates events before really quitting, - we want to stop them. */ - quitting = 1; - - memset( &tv, 0, sizeof( struct timeval ) ); - event_loopexit( &tv ); -} - -static void b_event_passthrough( int fd, short event, void *data ) -{ - struct b_event_data *b_ev = data; - b_input_condition cond = 0; - int id; - - if( fd >= 0 ) - { - if( event & EV_READ ) - cond |= GAIM_INPUT_READ; - if( event & EV_WRITE ) - cond |= GAIM_INPUT_WRITE; - } - - event_debug( "b_event_passthrough( %d, %d, 0x%x ) (%d)\n", fd, event, (int) data, b_ev->id ); - - /* Since the called function might cancel this handler already - (which free()s b_ev, we have to remember the ID here. */ - id = b_ev->id; - - if( quitting ) - { - b_event_remove( id ); - return; - } - - if( !b_ev->function( b_ev->data, fd, cond ) ) - { - event_debug( "Handler returned FALSE: " ); - b_event_remove( id ); - } - else if( fd == -1 ) - { - struct timeval tv; - - tv.tv_sec = b_ev->timeout / 1000; - tv.tv_usec = ( b_ev->timeout % 1000 ) * 1000; - - evtimer_add( &b_ev->evinfo, &tv ); - } -} - -gint b_input_add( gint fd, b_input_condition condition, b_event_handler function, gpointer data ) -{ - struct b_event_data *b_ev; - - event_debug( "b_input_add( %d, %d, 0x%x, 0x%x ) ", fd, condition, function, data ); - - if( ( condition & GAIM_INPUT_READ && ( b_ev = g_hash_table_lookup( read_hash, &fd ) ) ) || - ( condition & GAIM_INPUT_WRITE && ( b_ev = g_hash_table_lookup( write_hash, &fd ) ) ) ) - { - /* We'll stick with this libevent entry, but give it a new BitlBee id. */ - g_hash_table_remove( id_hash, &b_ev->id ); - - event_debug( "(replacing old handler (id = %d)) = %d\n", b_ev->id, id_next ); - - b_ev->id = id_next++; - b_ev->function = function; - b_ev->data = data; - } - else - { - GIOCondition out_cond; - - event_debug( "(new) = %d\n", id_next ); - - b_ev = g_new0( struct b_event_data, 1 ); - b_ev->id = id_next++; - b_ev->function = function; - b_ev->data = data; - - out_cond = EV_PERSIST; - if( condition & GAIM_INPUT_READ ) - out_cond |= EV_READ; - if( condition & GAIM_INPUT_WRITE ) - out_cond |= EV_WRITE; - - event_set( &b_ev->evinfo, fd, out_cond, b_event_passthrough, b_ev ); - event_add( &b_ev->evinfo, NULL ); - - if( out_cond & EV_READ ) - g_hash_table_insert( read_hash, &b_ev->evinfo.ev_fd, b_ev ); - if( out_cond & EV_WRITE ) - g_hash_table_insert( write_hash, &b_ev->evinfo.ev_fd, b_ev ); - } - - g_hash_table_insert( id_hash, &b_ev->id, b_ev ); - return b_ev->id; -} - -/* TODO: Persistence for timers! */ -gint b_timeout_add( gint timeout, b_event_handler function, gpointer data ) -{ - struct b_event_data *b_ev = g_new0( struct b_event_data, 1 ); - struct timeval tv; - - b_ev->id = id_next++; - b_ev->timeout = timeout; - b_ev->function = function; - b_ev->data = data; - - tv.tv_sec = timeout / 1000; - tv.tv_usec = ( timeout % 1000 ) * 1000; - - evtimer_set( &b_ev->evinfo, b_event_passthrough, b_ev ); - evtimer_add( &b_ev->evinfo, &tv ); - - event_debug( "b_timeout_add( %d, 0x%x, 0x%x ) = %d\n", timeout, function, data, b_ev->id ); - - g_hash_table_insert( id_hash, &b_ev->id, b_ev ); - - return b_ev->id; -} - -void b_event_remove( gint id ) -{ - struct b_event_data *b_ev = g_hash_table_lookup( id_hash, &id ); - - event_debug( "b_event_remove( %d )\n", id ); - if( b_ev ) - { - g_hash_table_remove( id_hash, &b_ev->id ); - if( b_ev->evinfo.ev_fd >= 0 ) - { - if( b_ev->evinfo.ev_events & EV_READ ) - g_hash_table_remove( read_hash, &b_ev->evinfo.ev_fd ); - if( b_ev->evinfo.ev_events & EV_WRITE ) - g_hash_table_remove( write_hash, &b_ev->evinfo.ev_fd ); - } - - event_del( &b_ev->evinfo ); - g_free( b_ev ); - } - else - { - event_debug( "Already removed?\n" ); - } -} - -void closesocket( int fd ) -{ - struct b_event_data *b_ev; - - /* Since epoll() (the main reason we use libevent) automatically removes sockets from - the epoll() list when a socket gets closed and some modules have a habit of - closing sockets before removing event handlers, our and libevent's administration - get a little bit messed up. So this little function will remove the handlers - properly before closing a socket. */ - - if( ( b_ev = g_hash_table_lookup( read_hash, &fd ) ) ) - { - event_debug( "Warning: fd %d still had a read event handler when shutting down.\n", fd ); - b_event_remove( b_ev->id ); - } - if( ( b_ev = g_hash_table_lookup( write_hash, &fd ) ) ) - { - event_debug( "Warning: fd %d still had a write event handler when shutting down.\n", fd ); - b_event_remove( b_ev->id ); - } - - close( fd ); -} diff --git a/protocols/http_client.c b/protocols/http_client.c deleted file mode 100644 index b00fcf98..00000000 --- a/protocols/http_client.c +++ /dev/null @@ -1,453 +0,0 @@ - /********************************************************************\ - * BitlBee -- An IRC to other IM-networks gateway * - * * - * Copyright 2002-2005 Wilmer van der Gaast and others * - \********************************************************************/ - -/* HTTP(S) module */ - -/* - 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 <string.h> -#include <stdio.h> - -#include "http_client.h" -#include "url.h" -#include "sock.h" - - -static gboolean http_connected( gpointer data, int source, b_input_condition cond ); -static gboolean http_ssl_connected( gpointer data, void *source, b_input_condition cond ); -static gboolean http_incoming_data( gpointer data, int source, b_input_condition cond ); - - -void *http_dorequest( char *host, int port, int ssl, char *request, http_input_function func, gpointer data ) -{ - struct http_request *req; - int error = 0; - - req = g_new0( struct http_request, 1 ); - - if( ssl ) - { - req->ssl = ssl_connect( host, port, http_ssl_connected, req ); - if( req->ssl == NULL ) - error = 1; - } - else - { - req->fd = proxy_connect( host, port, http_connected, req ); - if( req->fd < 0 ) - error = 1; - } - - if( error ) - { - g_free( req ); - return( NULL ); - } - - req->func = func; - req->data = data; - req->request = g_strdup( request ); - req->request_length = strlen( request ); - - return( req ); -} - -void *http_dorequest_url( char *url_string, http_input_function func, gpointer data ) -{ - url_t *url = g_new0( url_t, 1 ); - char *request; - void *ret; - - if( !url_set( url, url_string ) ) - { - g_free( url ); - return NULL; - } - - if( url->proto != PROTO_HTTP && url->proto != PROTO_HTTPS ) - { - g_free( url ); - return NULL; - } - - request = g_strdup_printf( "GET %s HTTP/1.0\r\n" - "Host: %s\r\n" - "User-Agent: BitlBee " BITLBEE_VERSION " " ARCH "/" CPU "\r\n" - "\r\n", url->file, url->host ); - - ret = http_dorequest( url->host, url->port, - url->proto == PROTO_HTTPS, request, func, data ); - - g_free( url ); - g_free( request ); - return ret; -} - -/* This one is actually pretty simple... Might get more calls if we can't write - the whole request at once. */ -static gboolean http_connected( gpointer data, int source, b_input_condition cond ) -{ - struct http_request *req = data; - int st; - - if( source < 0 ) - goto error; - - if( req->inpa > 0 ) - b_event_remove( req->inpa ); - - sock_make_nonblocking( req->fd ); - - if( req->ssl ) - { - st = ssl_write( req->ssl, req->request + req->bytes_written, - req->request_length - req->bytes_written ); - if( st < 0 ) - { - if( ssl_errno != SSL_AGAIN ) - { - ssl_disconnect( req->ssl ); - goto error; - } - } - } - else - { - st = write( source, req->request + req->bytes_written, - req->request_length - req->bytes_written ); - if( st < 0 ) - { - if( !sockerr_again() ) - { - closesocket( req->fd ); - goto error; - } - } - } - - if( st > 0 ) - req->bytes_written += st; - - if( req->bytes_written < req->request_length ) - req->inpa = b_input_add( source, - req->ssl ? ssl_getdirection( req->ssl ) : GAIM_INPUT_WRITE, - http_connected, req ); - else - req->inpa = b_input_add( source, GAIM_INPUT_READ, http_incoming_data, req ); - - return FALSE; - -error: - req->status_string = g_strdup( "Error while writing HTTP request" ); - - req->func( req ); - - g_free( req->request ); - g_free( req ); - - return FALSE; -} - -static gboolean http_ssl_connected( gpointer data, void *source, b_input_condition cond ) -{ - struct http_request *req = data; - - if( source == NULL ) - return http_connected( data, -1, cond ); - - req->fd = ssl_getfd( source ); - - return http_connected( data, req->fd, cond ); -} - -static gboolean http_incoming_data( gpointer data, int source, b_input_condition cond ) -{ - struct http_request *req = data; - int evil_server = 0; - char buffer[2048]; - char *end1, *end2; - int st; - - if( req->inpa > 0 ) - b_event_remove( req->inpa ); - - if( req->ssl ) - { - st = ssl_read( req->ssl, buffer, sizeof( buffer ) ); - if( st < 0 ) - { - if( ssl_errno != SSL_AGAIN ) - { - /* goto cleanup; */ - - /* YAY! We have to deal with crappy Microsoft - servers that LOVE to send invalid TLS - packets that abort connections! \o/ */ - - goto got_reply; - } - } - else if( st == 0 ) - { - goto got_reply; - } - } - else - { - st = read( req->fd, buffer, sizeof( buffer ) ); - if( st < 0 ) - { - if( !sockerr_again() ) - { - req->status_string = g_strdup( strerror( errno ) ); - goto cleanup; - } - } - else if( st == 0 ) - { - goto got_reply; - } - } - - if( st > 0 ) - { - req->reply_headers = g_realloc( req->reply_headers, req->bytes_read + st + 1 ); - memcpy( req->reply_headers + req->bytes_read, buffer, st ); - req->bytes_read += st; - } - - /* There will be more! */ - req->inpa = b_input_add( req->fd, - req->ssl ? ssl_getdirection( req->ssl ) : GAIM_INPUT_READ, - http_incoming_data, req ); - - return FALSE; - -got_reply: - /* Maybe if the webserver is overloaded, or when there's bad SSL - support... */ - if( req->bytes_read == 0 ) - { - req->status_string = g_strdup( "Empty HTTP reply" ); - goto cleanup; - } - - /* Zero termination is very convenient. */ - req->reply_headers[req->bytes_read] = 0; - - /* Find the separation between headers and body, and keep stupid - webservers in mind. */ - end1 = strstr( req->reply_headers, "\r\n\r\n" ); - end2 = strstr( req->reply_headers, "\n\n" ); - - if( end2 && end2 < end1 ) - { - end1 = end2 + 1; - evil_server = 1; - } - else if( end1 ) - { - end1 += 2; - } - else - { - req->status_string = g_strdup( "Malformed HTTP reply" ); - goto cleanup; - } - - *end1 = 0; - - if( evil_server ) - req->reply_body = end1 + 1; - else - req->reply_body = end1 + 2; - - req->body_size = req->reply_headers + req->bytes_read - req->reply_body; - - if( ( end1 = strchr( req->reply_headers, ' ' ) ) != NULL ) - { - if( sscanf( end1 + 1, "%d", &req->status_code ) != 1 ) - { - req->status_string = g_strdup( "Can't parse status code" ); - req->status_code = -1; - } - else - { - char *eol; - - if( evil_server ) - eol = strchr( end1, '\n' ); - else - eol = strchr( end1, '\r' ); - - req->status_string = g_strndup( end1 + 1, eol - end1 - 1 ); - - /* Just to be sure... */ - if( ( eol = strchr( req->status_string, '\r' ) ) ) - *eol = 0; - if( ( eol = strchr( req->status_string, '\n' ) ) ) - *eol = 0; - } - } - else - { - req->status_string = g_strdup( "Can't locate status code" ); - req->status_code = -1; - } - - if( req->status_code == 301 || req->status_code == 302 ) - { - char *loc, *new_request, *new_host; - int error = 0, new_port, new_proto; - - /* We might fill it again, so let's not leak any memory. */ - g_free( req->status_string ); - req->status_string = NULL; - - loc = strstr( req->reply_headers, "\nLocation: " ); - if( loc == NULL ) /* We can't handle this redirect... */ - { - req->status_string = g_strdup( "Can't locate Location: header" ); - goto cleanup; - } - - loc += 11; - while( *loc == ' ' ) - loc ++; - - /* TODO/FIXME: Possibly have to handle relative redirections, - and rewrite Host: headers. Not necessary for now, it's - enough for passport authentication like this. */ - - if( *loc == '/' ) - { - /* Just a different pathname... */ - - /* Since we don't cache the servername, and since we - don't need this yet anyway, I won't implement it. */ - - req->status_string = g_strdup( "Can't handle recursive redirects" ); - - goto cleanup; - } - else - { - /* A whole URL */ - url_t *url; - char *s; - - s = strstr( loc, "\r\n" ); - if( s == NULL ) - goto cleanup; - - url = g_new0( url_t, 1 ); - *s = 0; - - if( !url_set( url, loc ) ) - { - req->status_string = g_strdup( "Malformed redirect URL" ); - g_free( url ); - goto cleanup; - } - - /* Okay, this isn't fun! We have to rebuild the request... :-( */ - new_request = g_malloc( req->request_length + strlen( url->file ) ); - - /* So, now I just allocated enough memory, so I'm - going to use strcat(), whether you like it or not. :-) */ - - sprintf( new_request, "GET %s HTTP/1.0", url->file ); - - s = strstr( req->request, "\r\n" ); - if( s == NULL ) - { - req->status_string = g_strdup( "Error while rebuilding request string" ); - g_free( new_request ); - g_free( url ); - goto cleanup; - } - - strcat( new_request, s ); - new_host = g_strdup( url->host ); - new_port = url->port; - new_proto = url->proto; - - g_free( url ); - } - - if( req->ssl ) - ssl_disconnect( req->ssl ); - else - closesocket( req->fd ); - - req->fd = -1; - req->ssl = NULL; - - if( new_proto == PROTO_HTTPS ) - { - req->ssl = ssl_connect( new_host, new_port, http_ssl_connected, req ); - if( req->ssl == NULL ) - error = 1; - } - else - { - req->fd = proxy_connect( new_host, new_port, http_connected, req ); - if( req->fd < 0 ) - error = 1; - } - g_free( new_host ); - - if( error ) - { - req->status_string = g_strdup( "Connection problem during redirect" ); - g_free( new_request ); - goto cleanup; - } - - g_free( req->request ); - g_free( req->reply_headers ); - req->request = new_request; - req->request_length = strlen( new_request ); - req->bytes_read = req->bytes_written = req->inpa = 0; - req->reply_headers = req->reply_body = NULL; - - return FALSE; - } - - /* Assume that a closed connection means we're finished, this indeed - breaks with keep-alive connections and faulty connections. */ - req->finished = 1; - -cleanup: - if( req->ssl ) - ssl_disconnect( req->ssl ); - else - closesocket( req->fd ); - - req->func( req ); - - g_free( req->request ); - g_free( req->reply_headers ); - g_free( req->status_string ); - g_free( req ); - - return FALSE; -} diff --git a/protocols/http_client.h b/protocols/http_client.h deleted file mode 100644 index 50ee80cf..00000000 --- a/protocols/http_client.h +++ /dev/null @@ -1,57 +0,0 @@ - /********************************************************************\ - * BitlBee -- An IRC to other IM-networks gateway * - * * - * Copyright 2002-2005 Wilmer van der Gaast and others * - \********************************************************************/ - -/* HTTP(S) module */ - -/* - 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 <glib.h> - -#include "ssl_client.h" - -struct http_request; - -typedef void (*http_input_function)( struct http_request * ); - -struct http_request -{ - char *request; - int request_length; - int status_code; - char *status_string; - char *reply_headers; - char *reply_body; - int body_size; - int finished; - - void *ssl; - int fd; - - int inpa; - int bytes_written; - int bytes_read; - - http_input_function func; - gpointer data; -}; - -void *http_dorequest( char *host, int port, int ssl, char *request, http_input_function func, gpointer data ); -void *http_dorequest_url( char *url_string, http_input_function func, gpointer data ); diff --git a/protocols/jabber/jabber.c b/protocols/jabber/jabber.c index 029473fd..e765a475 100644 --- a/protocols/jabber/jabber.c +++ b/protocols/jabber/jabber.c @@ -560,37 +560,19 @@ static gboolean gjab_connected_ssl(gpointer data, void *source, b_input_conditio static void gjab_start(gjconn gjc) { - struct aim_user *user; + account_t *acc; int port = -1, ssl = 0; - char *server = NULL, *s; + char *server = NULL; if (!gjc || gjc->state != JCONN_STATE_OFF) return; - user = GJ_GC(gjc)->user; - if (*user->proto_opt[0]) { - /* If there's a dot, assume there's a hostname in the beginning */ - if (strchr(user->proto_opt[0], '.')) { - server = g_strdup(user->proto_opt[0]); - if ((s = strchr(server, ':'))) - *s = 0; - } - - /* After the hostname, there can be a port number */ - s = strchr(user->proto_opt[0], ':'); - if (s && isdigit(s[1])) - sscanf(s + 1, "%d", &port); - - /* And if there's the string ssl, the user wants an SSL-connection */ - if (strstr(user->proto_opt[0], ":ssl") || g_strcasecmp(user->proto_opt[0], "ssl") == 0) - ssl = 1; - } + acc = GJ_GC(gjc)->acc; + server = acc->server; + port = set_getint(&acc->set, "port"); + ssl = set_getbool(&acc->set, "ssl"); - if (port == -1 && !ssl) - port = DEFAULT_PORT; - else if (port == -1 && ssl) - port = DEFAULT_PORT_SSL; - else if (port < JABBER_PORT_MIN || port > JABBER_PORT_MAX) { + if (port < JABBER_PORT_MIN || port > JABBER_PORT_MAX) { serv_got_crap(GJ_GC(gjc), "For security reasons, the Jabber port number must be in the %d-%d range.", JABBER_PORT_MIN, JABBER_PORT_MAX); STATE_EVT(JCONN_STATE_OFF) return; @@ -613,9 +595,7 @@ static void gjab_start(gjconn gjc) gjc->fd = proxy_connect(server, port, gjab_connected, GJ_GC(gjc)); } - g_free(server); - - if (!user->gc || (gjc->fd < 0)) { + if (!acc->gc || (gjc->fd < 0)) { STATE_EVT(JCONN_STATE_OFF) return; } @@ -1515,18 +1495,75 @@ static void jabber_handlestate(gjconn gjc, int state) return; } -static void jabber_login(struct aim_user *user) +static void jabber_acc_init(account_t *acc) { - struct gaim_connection *gc = new_gaim_conn(user); - struct jabber_data *jd = gc->proto_data = g_new0(struct jabber_data, 1); - char *loginname = create_valid_jid(user->username, DEFAULT_SERVER, "BitlBee"); + set_t *s; + + s = set_add( &acc->set, "port", "5222", set_eval_int, acc ); + s->flags |= ACC_SET_OFFLINE_ONLY; + + s = set_add( &acc->set, "resource", "BitlBee", NULL, acc ); + s->flags |= ACC_SET_OFFLINE_ONLY; + + s = set_add( &acc->set, "server", NULL, set_eval_account, acc ); + s->flags |= ACC_SET_NOSAVE | ACC_SET_OFFLINE_ONLY; + + s = set_add( &acc->set, "ssl", "false", set_eval_bool, acc ); + s->flags |= ACC_SET_OFFLINE_ONLY; +} +static void jabber_login(account_t *acc) +{ + struct gaim_connection *gc; + struct jabber_data *jd; + char *resource, *loginname; + + /* Time to move some data/things from the old syntax to the new one: */ + if (acc->server) { + char *s, *tmp_server; + int port; + + if (g_strcasecmp(acc->server, "ssl") == 0) { + set_setstr(&acc->set, "server", ""); + set_setint(&acc->set, "port", DEFAULT_PORT_SSL); + set_setstr(&acc->set, "ssl", "true"); + + g_free(acc->server); + acc->server = NULL; + } else if ((s = strchr(acc->server, ':'))) { + if (strstr(acc->server, ":ssl")) { + set_setint(&acc->set, "port", DEFAULT_PORT_SSL); + set_setstr(&acc->set, "ssl", "true"); + } + if (isdigit(s[1])) { + if (sscanf(s + 1, "%d", &port) == 1) + set_setint(&acc->set, "port", port); + } + tmp_server = g_strndup(acc->server, s - acc->server); + set_setstr(&acc->set, "server", tmp_server); + g_free(tmp_server); + } + } + + gc = new_gaim_conn(acc); + jd = gc->proto_data = g_new0(struct jabber_data, 1); + + if( strchr( acc->user, '@' ) == NULL ) + { + hide_login_progress( gc, "Invalid account name" ); + signoff( gc ); + return; + } + + resource = set_getstr(&acc->set, "resource"); + loginname = create_valid_jid(acc->user, DEFAULT_SERVER, resource); + jd->hash = g_hash_table_new(g_str_hash, g_str_equal); jd->chats = NULL; /* we have no chats yet */ set_login_progress(gc, 1, _("Connecting")); - if (!(jd->gjc = gjab_new(loginname, user->password, gc))) { + if (!(jd->gjc = gjab_new(loginname, acc->pass, gc))) { g_free(loginname); hide_login_progress(gc, _("Unable to connect")); signoff(gc); @@ -2336,6 +2373,7 @@ void jabber_init() ret->name = "jabber"; ret->away_states = jabber_away_states; + ret->acc_init = jabber_acc_init; ret->login = jabber_login; ret->close = jabber_close; ret->send_im = jabber_send_im; @@ -2348,7 +2386,7 @@ void jabber_init() ret->keepalive = jabber_keepalive; ret->alias_buddy = jabber_roster_update; ret->group_buddy = jabber_group_change; - ret->cmp_buddynames = g_strcasecmp; + ret->handle_cmp = g_strcasecmp; register_protocol (ret); } diff --git a/protocols/md5.c b/protocols/md5.c deleted file mode 100644 index e6273585..00000000 --- a/protocols/md5.c +++ /dev/null @@ -1,392 +0,0 @@ -/* - Copyright (C) 1999 Aladdin Enterprises. All rights reserved. - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. - - L. Peter Deutsch - ghost@aladdin.com - - */ -/* - Independent implementation of MD5 (RFC 1321). - - This code implements the MD5 Algorithm defined in RFC 1321. - It is derived directly from the text of the RFC and not from the - reference implementation. - - The original and principal author of md5.c is L. Peter Deutsch - <ghost@aladdin.com>. Other authors are noted in the change history - that follows (in reverse chronological order): - - 1999-11-04 lpd Edited comments slightly for automatic TOC extraction. - 1999-10-18 lpd Fixed typo in header comment (ansi2knr rather than md5). - 1999-05-03 lpd Original version. - */ - -#include "md5.h" -#include <string.h> - -#ifdef TEST -/* - * Compile with -DTEST to create a self-contained executable test program. - * The test program should print out the same values as given in section - * A.5 of RFC 1321, reproduced below. - */ -#include <string.h> -main() -{ - static const char *const test[7] = { - "", /*d41d8cd98f00b204e9800998ecf8427e*/ - "945399884.61923487334tuvga", /*0cc175b9c0f1b6a831c399e269772661*/ - "abc", /*900150983cd24fb0d6963f7d28e17f72*/ - "message digest", /*f96b697d7cb7938d525a2f31aaf161d0*/ - "abcdefghijklmnopqrstuvwxyz", /*c3fcd3d76192e4007dfb496cca67e13b*/ - "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789", - /*d174ab98d277d9f5a5611c2c9f419d9f*/ - "12345678901234567890123456789012345678901234567890123456789012345678901234567890" /*57edf4a22be3c955ac49da2e2107b67a*/ - }; - int i; - - for (i = 0; i < 7; ++i) { - md5_state_t state; - md5_byte_t digest[16]; - int di; - - md5_init(&state); - md5_append(&state, (const md5_byte_t *)test[i], strlen(test[i])); - md5_finish(&state, digest); - printf("MD5 (\"%s\") = ", test[i]); - for (di = 0; di < 16; ++di) - printf("%02x", digest[di]); - printf("\n"); - } - return 0; -} -#endif /* TEST */ - - -/* - * For reference, here is the program that computed the T values. - */ -#if 0 -#include <math.h> -main() -{ - int i; - for (i = 1; i <= 64; ++i) { - unsigned long v = (unsigned long)(4294967296.0 * fabs(sin((double)i))); - printf("#define T%d 0x%08lx\n", i, v); - } - return 0; -} -#endif -/* - * End of T computation program. - */ -#define T1 0xd76aa478 -#define T2 0xe8c7b756 -#define T3 0x242070db -#define T4 0xc1bdceee -#define T5 0xf57c0faf -#define T6 0x4787c62a -#define T7 0xa8304613 -#define T8 0xfd469501 -#define T9 0x698098d8 -#define T10 0x8b44f7af -#define T11 0xffff5bb1 -#define T12 0x895cd7be -#define T13 0x6b901122 -#define T14 0xfd987193 -#define T15 0xa679438e -#define T16 0x49b40821 -#define T17 0xf61e2562 -#define T18 0xc040b340 -#define T19 0x265e5a51 -#define T20 0xe9b6c7aa -#define T21 0xd62f105d -#define T22 0x02441453 -#define T23 0xd8a1e681 -#define T24 0xe7d3fbc8 -#define T25 0x21e1cde6 -#define T26 0xc33707d6 -#define T27 0xf4d50d87 -#define T28 0x455a14ed -#define T29 0xa9e3e905 -#define T30 0xfcefa3f8 -#define T31 0x676f02d9 -#define T32 0x8d2a4c8a -#define T33 0xfffa3942 -#define T34 0x8771f681 -#define T35 0x6d9d6122 -#define T36 0xfde5380c -#define T37 0xa4beea44 -#define T38 0x4bdecfa9 -#define T39 0xf6bb4b60 -#define T40 0xbebfbc70 -#define T41 0x289b7ec6 -#define T42 0xeaa127fa -#define T43 0xd4ef3085 -#define T44 0x04881d05 -#define T45 0xd9d4d039 -#define T46 0xe6db99e5 -#define T47 0x1fa27cf8 -#define T48 0xc4ac5665 -#define T49 0xf4292244 -#define T50 0x432aff97 -#define T51 0xab9423a7 -#define T52 0xfc93a039 -#define T53 0x655b59c3 -#define T54 0x8f0ccc92 -#define T55 0xffeff47d -#define T56 0x85845dd1 -#define T57 0x6fa87e4f -#define T58 0xfe2ce6e0 -#define T59 0xa3014314 -#define T60 0x4e0811a1 -#define T61 0xf7537e82 -#define T62 0xbd3af235 -#define T63 0x2ad7d2bb -#define T64 0xeb86d391 - -static void -md5_process(md5_state_t *pms, const md5_byte_t *data /*[64]*/) -{ - md5_word_t - a = pms->abcd[0], b = pms->abcd[1], - c = pms->abcd[2], d = pms->abcd[3]; - md5_word_t t; - -#ifndef ARCH_IS_BIG_ENDIAN -# define ARCH_IS_BIG_ENDIAN 1 /* slower, default implementation */ -#endif -#if ARCH_IS_BIG_ENDIAN - - /* - * On big-endian machines, we must arrange the bytes in the right - * order. (This also works on machines of unknown byte order.) - */ - md5_word_t X[16]; - const md5_byte_t *xp = data; - int i; - - for (i = 0; i < 16; ++i, xp += 4) - X[i] = xp[0] + (xp[1] << 8) + (xp[2] << 16) + (xp[3] << 24); - -#else /* !ARCH_IS_BIG_ENDIAN */ - - /* - * On little-endian machines, we can process properly aligned data - * without copying it. - */ - md5_word_t xbuf[16]; - const md5_word_t *X; - - if (!((data - (const md5_byte_t *)0) & 3)) { - /* data are properly aligned */ - X = (const md5_word_t *)data; - } else { - /* not aligned */ - memcpy(xbuf, data, 64); - X = xbuf; - } -#endif - -#define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32 - (n)))) - - /* Round 1. */ - /* Let [abcd k s i] denote the operation - a = b + ((a + F(b,c,d) + X[k] + T[i]) <<< s). */ -#define F(x, y, z) (((x) & (y)) | (~(x) & (z))) -#define SET(a, b, c, d, k, s, Ti)\ - t = a + F(b,c,d) + X[k] + Ti;\ - a = ROTATE_LEFT(t, s) + b - /* Do the following 16 operations. */ - SET(a, b, c, d, 0, 7, T1); - SET(d, a, b, c, 1, 12, T2); - SET(c, d, a, b, 2, 17, T3); - SET(b, c, d, a, 3, 22, T4); - SET(a, b, c, d, 4, 7, T5); - SET(d, a, b, c, 5, 12, T6); - SET(c, d, a, b, 6, 17, T7); - SET(b, c, d, a, 7, 22, T8); - SET(a, b, c, d, 8, 7, T9); - SET(d, a, b, c, 9, 12, T10); - SET(c, d, a, b, 10, 17, T11); - SET(b, c, d, a, 11, 22, T12); - SET(a, b, c, d, 12, 7, T13); - SET(d, a, b, c, 13, 12, T14); - SET(c, d, a, b, 14, 17, T15); - SET(b, c, d, a, 15, 22, T16); -#undef SET - - /* Round 2. */ - /* Let [abcd k s i] denote the operation - a = b + ((a + G(b,c,d) + X[k] + T[i]) <<< s). */ -#define G(x, y, z) (((x) & (z)) | ((y) & ~(z))) -#define SET(a, b, c, d, k, s, Ti)\ - t = a + G(b,c,d) + X[k] + Ti;\ - a = ROTATE_LEFT(t, s) + b - /* Do the following 16 operations. */ - SET(a, b, c, d, 1, 5, T17); - SET(d, a, b, c, 6, 9, T18); - SET(c, d, a, b, 11, 14, T19); - SET(b, c, d, a, 0, 20, T20); - SET(a, b, c, d, 5, 5, T21); - SET(d, a, b, c, 10, 9, T22); - SET(c, d, a, b, 15, 14, T23); - SET(b, c, d, a, 4, 20, T24); - SET(a, b, c, d, 9, 5, T25); - SET(d, a, b, c, 14, 9, T26); - SET(c, d, a, b, 3, 14, T27); - SET(b, c, d, a, 8, 20, T28); - SET(a, b, c, d, 13, 5, T29); - SET(d, a, b, c, 2, 9, T30); - SET(c, d, a, b, 7, 14, T31); - SET(b, c, d, a, 12, 20, T32); -#undef SET - - /* Round 3. */ - /* Let [abcd k s t] denote the operation - a = b + ((a + H(b,c,d) + X[k] + T[i]) <<< s). */ -#define H(x, y, z) ((x) ^ (y) ^ (z)) -#define SET(a, b, c, d, k, s, Ti)\ - t = a + H(b,c,d) + X[k] + Ti;\ - a = ROTATE_LEFT(t, s) + b - /* Do the following 16 operations. */ - SET(a, b, c, d, 5, 4, T33); - SET(d, a, b, c, 8, 11, T34); - SET(c, d, a, b, 11, 16, T35); - SET(b, c, d, a, 14, 23, T36); - SET(a, b, c, d, 1, 4, T37); - SET(d, a, b, c, 4, 11, T38); - SET(c, d, a, b, 7, 16, T39); - SET(b, c, d, a, 10, 23, T40); - SET(a, b, c, d, 13, 4, T41); - SET(d, a, b, c, 0, 11, T42); - SET(c, d, a, b, 3, 16, T43); - SET(b, c, d, a, 6, 23, T44); - SET(a, b, c, d, 9, 4, T45); - SET(d, a, b, c, 12, 11, T46); - SET(c, d, a, b, 15, 16, T47); - SET(b, c, d, a, 2, 23, T48); -#undef SET - - /* Round 4. */ - /* Let [abcd k s t] denote the operation - a = b + ((a + I(b,c,d) + X[k] + T[i]) <<< s). */ -#define I(x, y, z) ((y) ^ ((x) | ~(z))) -#define SET(a, b, c, d, k, s, Ti)\ - t = a + I(b,c,d) + X[k] + Ti;\ - a = ROTATE_LEFT(t, s) + b - /* Do the following 16 operations. */ - SET(a, b, c, d, 0, 6, T49); - SET(d, a, b, c, 7, 10, T50); - SET(c, d, a, b, 14, 15, T51); - SET(b, c, d, a, 5, 21, T52); - SET(a, b, c, d, 12, 6, T53); - SET(d, a, b, c, 3, 10, T54); - SET(c, d, a, b, 10, 15, T55); - SET(b, c, d, a, 1, 21, T56); - SET(a, b, c, d, 8, 6, T57); - SET(d, a, b, c, 15, 10, T58); - SET(c, d, a, b, 6, 15, T59); - SET(b, c, d, a, 13, 21, T60); - SET(a, b, c, d, 4, 6, T61); - SET(d, a, b, c, 11, 10, T62); - SET(c, d, a, b, 2, 15, T63); - SET(b, c, d, a, 9, 21, T64); -#undef SET - - /* Then perform the following additions. (That is increment each - of the four registers by the value it had before this block - was started.) */ - pms->abcd[0] += a; - pms->abcd[1] += b; - pms->abcd[2] += c; - pms->abcd[3] += d; -} - -void -md5_init(md5_state_t *pms) -{ - pms->count[0] = pms->count[1] = 0; - pms->abcd[0] = 0x67452301; - pms->abcd[1] = 0xefcdab89; - pms->abcd[2] = 0x98badcfe; - pms->abcd[3] = 0x10325476; -} - -void -md5_append(md5_state_t *pms, const md5_byte_t *data, int nbytes) -{ - const md5_byte_t *p = data; - int left = nbytes; - int offset = (pms->count[0] >> 3) & 63; - md5_word_t nbits = (md5_word_t)(nbytes << 3); - - if (nbytes <= 0) - return; - - /* Update the message length. */ - pms->count[1] += nbytes >> 29; - pms->count[0] += nbits; - if (pms->count[0] < nbits) - pms->count[1]++; - - /* Process an initial partial block. */ - if (offset) { - int copy = (offset + nbytes > 64 ? 64 - offset : nbytes); - - memcpy(pms->buf + offset, p, copy); - if (offset + copy < 64) - return; - p += copy; - left -= copy; - md5_process(pms, pms->buf); - } - - /* Process full blocks. */ - for (; left >= 64; p += 64, left -= 64) - md5_process(pms, p); - - /* Process a final partial block. */ - if (left) - memcpy(pms->buf, p, left); -} - -void -md5_finish(md5_state_t *pms, md5_byte_t digest[16]) -{ - static const md5_byte_t pad[64] = { - 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 - }; - md5_byte_t data[8]; - int i; - - /* Save the length before padding. */ - for (i = 0; i < 8; ++i) - data[i] = (md5_byte_t)(pms->count[i >> 2] >> ((i & 3) << 3)); - /* Pad to 56 bytes mod 64. */ - md5_append(pms, pad, ((55 - (pms->count[0] >> 3)) & 63) + 1); - /* Append the length. */ - md5_append(pms, data, 8); - for (i = 0; i < 16; ++i) - digest[i] = (md5_byte_t)(pms->abcd[i >> 2] >> ((i & 3) << 3)); -} diff --git a/protocols/md5.h b/protocols/md5.h deleted file mode 100644 index f24f2ff1..00000000 --- a/protocols/md5.h +++ /dev/null @@ -1,85 +0,0 @@ -/* - Copyright (C) 1999 Aladdin Enterprises. All rights reserved. - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. - - L. Peter Deutsch - ghost@aladdin.com - - */ -/* - Independent implementation of MD5 (RFC 1321). - - This code implements the MD5 Algorithm defined in RFC 1321. - It is derived directly from the text of the RFC and not from the - reference implementation. - - The original and principal author of md5.h is L. Peter Deutsch - <ghost@aladdin.com>. Other authors are noted in the change history - that follows (in reverse chronological order): - - 2004-03-09 Jelmer Vernooij add G_MODULE_EXPORT for Bitlbee - 1999-11-04 lpd Edited comments slightly for automatic TOC extraction. - 1999-10-18 lpd Fixed typo in header comment (ansi2knr rather than md5); - added conditionalization for C++ compilation from Martin - Purschke <purschke@bnl.gov>. - 1999-05-03 lpd Original version. - */ - -#ifndef md5_INCLUDED -# define md5_INCLUDED - -#include <glib.h> -#include <gmodule.h> - -/* - * This code has some adaptations for the Ghostscript environment, but it - * will compile and run correctly in any environment with 8-bit chars and - * 32-bit ints. Specifically, it assumes that if the following are - * defined, they have the same meaning as in Ghostscript: P1, P2, P3, - * ARCH_IS_BIG_ENDIAN. - */ - -typedef unsigned char md5_byte_t; /* 8-bit byte */ -typedef unsigned int md5_word_t; /* 32-bit word */ - -/* Define the state of the MD5 Algorithm. */ -typedef struct md5_state_s { - md5_word_t count[2]; /* message length in bits, lsw first */ - md5_word_t abcd[4]; /* digest buffer */ - md5_byte_t buf[64]; /* accumulate block */ -} md5_state_t; - -#ifdef __cplusplus -extern "C" -{ -#endif - -/* Initialize the algorithm. */ -G_MODULE_EXPORT void md5_init(md5_state_t *pms); - -/* Append a string to the message. */ -G_MODULE_EXPORT void md5_append(md5_state_t *pms, const md5_byte_t *data, int nbytes); - -/* Finish the message and return the digest. */ -G_MODULE_EXPORT void md5_finish(md5_state_t *pms, md5_byte_t digest[16]); - -#ifdef __cplusplus -} /* end extern "C" */ -#endif - -#endif /* md5_INCLUDED */ diff --git a/protocols/msn/msn.c b/protocols/msn/msn.c index a8d85a66..01b011c7 100644 --- a/protocols/msn/msn.c +++ b/protocols/msn/msn.c @@ -26,9 +26,19 @@ #include "nogaim.h" #include "msn.h" -static void msn_login( struct aim_user *acct ) +static char *msn_set_display_name( set_t *set, char *value ); + +static void msn_acc_init( account_t *acc ) { - struct gaim_connection *gc = new_gaim_conn( acct ); + set_t *s; + + s = set_add( &acc->set, "display_name", NULL, msn_set_display_name, acc ); + s->flags |= ACC_SET_NOSAVE | ACC_SET_ONLINE_ONLY; +} + +static void msn_login( account_t *acc ) +{ + struct gaim_connection *gc = new_gaim_conn( acc ); struct msn_data *md = g_new0( struct msn_data, 1 ); set_login_progress( gc, 1, "Connecting" ); @@ -36,7 +46,7 @@ static void msn_login( struct aim_user *acct ) gc->proto_data = md; md->fd = -1; - if( strchr( acct->username, '@' ) == NULL ) + if( strchr( acc->user, '@' ) == NULL ) { hide_login_progress( gc, "Invalid account name" ); signoff( gc ); @@ -211,36 +221,7 @@ static void msn_set_away( struct gaim_connection *gc, char *state, char *message static void msn_set_info( struct gaim_connection *gc, char *info ) { - int i; - char buf[1024], *fn, *s; - struct msn_data *md = gc->proto_data; - - if( strlen( info ) > 129 ) - { - do_error_dialog( gc, "Maximum name length exceeded", "MSN" ); - return; - } - - /* Of course we could use http_encode() here, but when we encode - every character, the server is less likely to complain about the - chosen name. However, the MSN server doesn't seem to like escaped - non-ASCII chars, so we keep those unescaped. */ - s = fn = g_new0( char, strlen( info ) * 3 + 1 ); - for( i = 0; info[i]; i ++ ) - if( info[i] & 128 ) - { - *s = info[i]; - s ++; - } - else - { - g_snprintf( s, 4, "%%%02X", info[i] ); - s += 3; - } - - g_snprintf( buf, sizeof( buf ), "REA %d %s %s\r\n", ++md->trId, gc->username, fn ); - msn_write( gc, buf, strlen( buf ) ); - g_free( fn ); + msn_set_display_name( set_find( &gc->acc->set, "display_name" ), info ); } static void msn_get_info(struct gaim_connection *gc, char *who) @@ -379,11 +360,60 @@ static int msn_send_typing( struct gaim_connection *gc, char *who, int typing ) return( 1 ); } +static char *msn_set_display_name( set_t *set, char *value ) +{ + account_t *acc = set->data; + struct gaim_connection *gc = acc->gc; + struct msn_data *md; + char buf[1024], *fn, *s; + int i; + + /* Double-check. */ + if( gc == NULL ) + return NULL; + + md = gc->proto_data; + + if( strlen( value ) > 129 ) + { + serv_got_crap( gc, "Maximum name length exceeded" ); + return NULL; + } + + /* Of course we could use http_encode() here, but when we encode + every character, the server is less likely to complain about the + chosen name. However, the MSN server doesn't seem to like escaped + non-ASCII chars, so we keep those unescaped. */ + s = fn = g_new0( char, strlen( value ) * 3 + 1 ); + for( i = 0; value[i]; i ++ ) + if( value[i] & 128 ) + { + *s = value[i]; + s ++; + } + else + { + g_snprintf( s, 4, "%%%02X", value[i] ); + s += 3; + } + + g_snprintf( buf, sizeof( buf ), "REA %d %s %s\r\n", ++md->trId, gc->username, fn ); + msn_write( gc, buf, strlen( buf ) ); + g_free( fn ); + + /* Returning NULL would be better, because the server still has to + confirm the name change. However, it looks a bit confusing to the + user. */ + return value; +} + void msn_init() { struct prpl *ret = g_new0(struct prpl, 1); + ret->name = "msn"; ret->login = msn_login; + ret->acc_init = msn_acc_init; ret->close = msn_close; ret->send_im = msn_send_im; ret->away_states = msn_away_states; @@ -403,7 +433,7 @@ void msn_init() ret->add_deny = msn_add_deny; ret->rem_deny = msn_rem_deny; ret->send_typing = msn_send_typing; - ret->cmp_buddynames = g_strcasecmp; + ret->handle_cmp = g_strcasecmp; register_protocol(ret); } diff --git a/protocols/msn/ns.c b/protocols/msn/ns.c index e4c2b68c..9774f3e2 100644 --- a/protocols/msn/ns.c +++ b/protocols/msn/ns.c @@ -222,11 +222,19 @@ static int msn_ns_command( gpointer data, char **cmd, int num_parts ) } else if( num_parts == 7 && strcmp( cmd[2], "OK" ) == 0 ) { + set_t *s; + http_decode( cmd[4] ); strncpy( gc->displayname, cmd[4], sizeof( gc->displayname ) ); gc->displayname[sizeof(gc->displayname)-1] = 0; + if( ( s = set_find( &gc->acc->set, "display_name" ) ) ) + { + g_free( s->value ); + s->value = g_strdup( cmd[4] ); + } + set_login_progress( gc, 1, "Authenticated, getting buddy list" ); g_snprintf( buf, sizeof( buf ), "SYN %d 0\r\n", ++md->trId ); @@ -516,9 +524,17 @@ static int msn_ns_command( gpointer data, char **cmd, int num_parts ) if( g_strcasecmp( cmd[3], gc->username ) == 0 ) { + set_t *s; + http_decode( cmd[4] ); strncpy( gc->displayname, cmd[4], sizeof( gc->displayname ) ); gc->displayname[sizeof(gc->displayname)-1] = 0; + + if( ( s = set_find( &gc->acc->set, "display_name" ) ) ) + { + g_free( s->value ); + s->value = g_strdup( cmd[4] ); + } } else { diff --git a/protocols/nogaim.c b/protocols/nogaim.c index 78b51b53..54965b84 100644 --- a/protocols/nogaim.c +++ b/protocols/nogaim.c @@ -144,33 +144,21 @@ GSList *get_connections() { return connections; } /* multi.c */ -struct gaim_connection *new_gaim_conn( struct aim_user *user ) +struct gaim_connection *new_gaim_conn( account_t *acc ) { struct gaim_connection *gc; - account_t *a; gc = g_new0( struct gaim_connection, 1 ); - gc->prpl = user->prpl; - g_snprintf( gc->username, sizeof( gc->username ), "%s", user->username ); - g_snprintf( gc->password, sizeof( gc->password ), "%s", user->password ); - /* [MD] BUGFIX: don't set gc->irc to the global IRC, but use the one from the struct aim_user. - * This fixes daemon mode breakage where IRC doesn't point to the currently active connection. - */ - gc->irc = user->irc; - - connections = g_slist_append( connections, gc ); + /* Maybe we should get rid of this memory waste later. ;-) */ + g_snprintf( gc->username, sizeof( gc->username ), "%s", acc->user ); + g_snprintf( gc->password, sizeof( gc->password ), "%s", acc->pass ); - user->gc = gc; - gc->user = user; + gc->irc = acc->irc; + gc->acc = acc; + acc->gc = gc; - // Find the account_t so we can set its gc pointer - for( a = gc->irc->accounts; a; a = a->next ) - if( ( struct aim_user * ) a->gc == user ) - { - a->gc = gc; - break; - } + connections = g_slist_append( connections, gc ); return( gc ); } @@ -188,7 +176,6 @@ void destroy_gaim_conn( struct gaim_connection *gc ) } connections = g_slist_remove( connections, gc ); - g_free( gc->user ); g_free( gc ); } @@ -219,20 +206,20 @@ void serv_got_crap( struct gaim_connection *gc, char *format, ... ) text = g_strdup_vprintf( format, params ); va_end( params ); - if( ( g_strcasecmp( set_getstr( gc->irc, "strip_html" ), "always" ) == 0 ) || - ( ( gc->flags & OPT_CONN_HTML ) && set_getint( gc->irc, "strip_html" ) ) ) + if( ( g_strcasecmp( set_getstr( &gc->irc->set, "strip_html" ), "always" ) == 0 ) || + ( ( gc->flags & OPT_CONN_HTML ) && set_getint( &gc->irc->set, "strip_html" ) ) ) strip_html( text ); /* Try to find a different connection on the same protocol. */ for( a = gc->irc->accounts; a; a = a->next ) - if( a->prpl == gc->prpl && a->gc != gc ) + if( a->prpl == gc->acc->prpl && a->gc != gc ) break; /* If we found one, include the screenname in the message. */ if( a ) - irc_usermsg( gc->irc, "%s(%s) - %s", gc->prpl->name, gc->username, text ); + irc_usermsg( gc->irc, "%s(%s) - %s", gc->acc->prpl->name, gc->username, text ); else - irc_usermsg( gc->irc, "%s - %s", gc->prpl->name, text ); + irc_usermsg( gc->irc, "%s - %s", gc->acc->prpl->name, text ); g_free( text ); } @@ -241,8 +228,8 @@ static gboolean send_keepalive( gpointer d, gint fd, b_input_condition cond ) { struct gaim_connection *gc = d; - if( gc->prpl && gc->prpl->keepalive ) - gc->prpl->keepalive( gc ); + if( gc->acc->prpl->keepalive ) + gc->acc->prpl->keepalive( gc ); return TRUE; } @@ -296,8 +283,9 @@ void signoff( struct gaim_connection *gc ) b_event_remove( gc->keepalive ); gc->flags |= OPT_LOGGING_OUT; + gc->keepalive = 0; - gc->prpl->close( gc ); + gc->acc->prpl->close( gc ); b_event_remove( gc->inpa ); while( u ) @@ -322,9 +310,9 @@ void signoff( struct gaim_connection *gc ) { /* Uhm... This is very sick. */ } - else if( !gc->wants_to_die && set_getint( irc, "auto_reconnect" ) ) + else if( !gc->wants_to_die && set_getint( &irc->set, "auto_reconnect" ) ) { - int delay = set_getint( irc, "auto_reconnect_delay" ); + int delay = set_getint( &irc->set, "auto_reconnect_delay" ); serv_got_crap( gc, "Reconnecting in %d seconds..", delay ); a->reconnect = b_timeout_add( delay * 1000, auto_reconnect, a ); @@ -363,12 +351,12 @@ void add_buddy( struct gaim_connection *gc, char *group, char *handle, char *rea char *s; irc_t *irc = gc->irc; - if( set_getint( irc, "debug" ) && 0 ) /* This message is too useless */ + if( set_getint( &irc->set, "debug" ) && 0 ) /* This message is too useless */ serv_got_crap( gc, "Receiving user add from handle: %s", handle ); if( user_findhandle( gc, handle ) ) { - if( set_getint( irc, "debug" ) ) + if( set_getint( &irc->set, "debug" ) ) serv_got_crap( gc, "User already exists, ignoring add request: %s", handle ); return; @@ -377,7 +365,7 @@ void add_buddy( struct gaim_connection *gc, char *group, char *handle, char *rea } memset( nick, 0, MAX_NICK_LENGTH + 1 ); - strcpy( nick, nick_get( gc->irc, handle, gc->prpl, realname ) ); + strcpy( nick, nick_get( gc->acc, handle, realname ) ); u = user_add( gc->irc, nick ); @@ -389,15 +377,15 @@ void add_buddy( struct gaim_connection *gc, char *group, char *handle, char *rea u->host = g_strdup( s + 1 ); u->user = g_strndup( handle, s - handle ); } - else if( gc->user->proto_opt[0] && *gc->user->proto_opt[0] ) + else if( gc->acc->server ) { char *colon; - if( ( colon = strchr( gc->user->proto_opt[0], ':' ) ) ) - u->host = g_strndup( gc->user->proto_opt[0], - colon - gc->user->proto_opt[0] ); + if( ( colon = strchr( gc->acc->server, ':' ) ) ) + u->host = g_strndup( gc->acc->server, + colon - gc->acc->server ); else - u->host = g_strdup( gc->user->proto_opt[0] ); + u->host = g_strdup( gc->acc->server ); u->user = g_strdup( handle ); @@ -408,7 +396,7 @@ void add_buddy( struct gaim_connection *gc, char *group, char *handle, char *rea } else { - u->host = g_strdup( gc->user->prpl->name ); + u->host = g_strdup( gc->acc->prpl->name ); u->user = g_strdup( handle ); } @@ -456,7 +444,7 @@ void serv_buddy_rename( struct gaim_connection *gc, char *handle, char *realname u->realname = g_strdup( realname ); - if( ( gc->flags & OPT_LOGGED_IN ) && set_getint( gc->irc, "display_namechanges" ) ) + if( ( gc->flags & OPT_LOGGED_IN ) && set_getint( &gc->irc->set, "display_namechanges" ) ) serv_got_crap( gc, "User `%s' changed name to `%s'", u->nick, u->realname ); } } @@ -478,7 +466,7 @@ void show_got_added_no( gpointer w, struct show_got_added_data *data ) void show_got_added_yes( gpointer w, struct show_got_added_data *data ) { - data->gc->prpl->add_buddy( data->gc, data->handle ); + data->gc->acc->prpl->add_buddy( data->gc, data->handle ); add_buddy( data->gc, NULL, data->handle, data->handle ); return show_got_added_no( w, data ); @@ -512,14 +500,14 @@ void serv_got_update( struct gaim_connection *gc, char *handle, int loggedin, in if( !u ) { - if( g_strcasecmp( set_getstr( gc->irc, "handle_unknown" ), "add" ) == 0 ) + if( g_strcasecmp( set_getstr( &gc->irc->set, "handle_unknown" ), "add" ) == 0 ) { add_buddy( gc, NULL, handle, NULL ); u = user_findhandle( gc, handle ); } else { - if( set_getint( gc->irc, "debug" ) || g_strcasecmp( set_getstr( gc->irc, "handle_unknown" ), "ignore" ) != 0 ) + if( set_getint( &gc->irc->set, "debug" ) || g_strcasecmp( set_getstr( &gc->irc->set, "handle_unknown" ), "ignore" ) != 0 ) { serv_got_crap( gc, "serv_got_update() for handle %s:", handle ); serv_got_crap( gc, "loggedin = %d, type = %d", loggedin, type ); @@ -557,11 +545,11 @@ void serv_got_update( struct gaim_connection *gc, char *handle, int loggedin, in remove_chat_buddy_silent( c, handle ); } - if( ( type & UC_UNAVAILABLE ) && ( !strcmp(gc->prpl->name, "oscar") || !strcmp(gc->prpl->name, "icq")) ) + if( ( type & UC_UNAVAILABLE ) && ( strcmp( gc->acc->prpl->name, "oscar" ) == 0 || strcmp( gc->acc->prpl->name, "icq" ) == 0 ) ) { u->away = g_strdup( "Away" ); } - else if( ( type & UC_UNAVAILABLE ) && ( !strcmp(gc->prpl->name, "jabber") ) ) + else if( ( type & UC_UNAVAILABLE ) && ( strcmp( gc->acc->prpl->name, "jabber" ) == 0 ) ) { if( type & UC_DND ) u->away = g_strdup( "Do Not Disturb" ); @@ -570,15 +558,15 @@ void serv_got_update( struct gaim_connection *gc, char *handle, int loggedin, in else // if( type & UC_AWAY ) u->away = g_strdup( "Away" ); } - else if( ( type & UC_UNAVAILABLE ) && gc->prpl->get_status_string ) + else if( ( type & UC_UNAVAILABLE ) && gc->acc->prpl->get_status_string ) { - u->away = g_strdup( gc->prpl->get_status_string( gc, type ) ); + u->away = g_strdup( gc->acc->prpl->get_status_string( gc, type ) ); } else u->away = NULL; /* LISPy... */ - if( ( set_getint( gc->irc, "away_devoice" ) ) && /* Don't do a thing when user doesn't want it */ + if( ( set_getint( &gc->irc->set, "away_devoice" ) ) && /* Don't do a thing when user doesn't want it */ ( u->online ) && /* Don't touch offline people */ ( ( ( u->online != oo ) && !u->away ) || /* Voice joining people */ ( ( u->online == oo ) && ( oa == !u->away ) ) ) ) /* (De)voice people changing state */ @@ -597,18 +585,18 @@ void serv_got_im( struct gaim_connection *gc, char *handle, char *msg, guint32 f if( !u ) { - char *h = set_getstr( irc, "handle_unknown" ); + char *h = set_getstr( &irc->set, "handle_unknown" ); if( g_strcasecmp( h, "ignore" ) == 0 ) { - if( set_getint( irc, "debug" ) ) + if( set_getint( &irc->set, "debug" ) ) serv_got_crap( gc, "Ignoring message from unknown handle %s", handle ); return; } else if( g_strncasecmp( h, "add", 3 ) == 0 ) { - int private = set_getint( irc, "private" ); + int private = set_getint( &irc->set, "private" ); if( h[3] ) { @@ -629,8 +617,8 @@ void serv_got_im( struct gaim_connection *gc, char *handle, char *msg, guint32 f } } - if( ( g_strcasecmp( set_getstr( gc->irc, "strip_html" ), "always" ) == 0 ) || - ( ( gc->flags & OPT_CONN_HTML ) && set_getint( gc->irc, "strip_html" ) ) ) + if( ( g_strcasecmp( set_getstr( &gc->irc->set, "strip_html" ), "always" ) == 0 ) || + ( ( gc->flags & OPT_CONN_HTML ) && set_getint( &gc->irc->set, "strip_html" ) ) ) strip_html( msg ); while( strlen( msg ) > 425 ) @@ -670,7 +658,7 @@ void serv_got_typing( struct gaim_connection *gc, char *handle, int timeout, int { user_t *u; - if( !set_getint( gc->irc, "typing_notice" ) ) + if( !set_getint( &gc->irc->set, "typing_notice" ) ) return; if( ( u = user_findhandle( gc, handle ) ) ) { @@ -692,7 +680,7 @@ void serv_got_chat_left( struct gaim_connection *gc, int id ) struct conversation *c, *l = NULL; GList *ir; - if( set_getint( gc->irc, "debug" ) ) + if( set_getint( &gc->irc->set, "debug" ) ) serv_got_crap( gc, "You were removed from conversation %d", (int) id ); for( c = gc->conversations; c && c->id != id; c = (l=c)->next ); @@ -731,14 +719,14 @@ void serv_got_chat_in( struct gaim_connection *gc, int id, char *who, int whispe user_t *u; /* Gaim sends own messages through this too. IRC doesn't want this, so kill them */ - if( g_strcasecmp( who, gc->user->username ) == 0 ) + if( g_strcasecmp( who, gc->username ) == 0 ) return; u = user_findhandle( gc, who ); for( c = gc->conversations; c && c->id != id; c = c->next ); - if( ( g_strcasecmp( set_getstr( gc->irc, "strip_html" ), "always" ) == 0 ) || - ( ( gc->flags & OPT_CONN_HTML ) && set_getint( gc->irc, "strip_html" ) ) ) + if( ( g_strcasecmp( set_getstr( &gc->irc->set, "strip_html" ), "always" ) == 0 ) || + ( ( gc->flags & OPT_CONN_HTML ) && set_getint( &gc->irc->set, "strip_html" ) ) ) strip_html( msg ); if( c && u ) @@ -771,7 +759,7 @@ struct conversation *serv_got_joined_chat( struct gaim_connection *gc, int id, c c->channel = g_strdup( s ); g_free( s ); - if( set_getint( gc->irc, "debug" ) ) + if( set_getint( &gc->irc->set, "debug" ) ) serv_got_crap( gc, "Creating new conversation: (id=%d,handle=%s)", id, handle ); return( c ); @@ -785,11 +773,11 @@ void add_chat_buddy( struct conversation *b, char *handle ) user_t *u = user_findhandle( b->gc, handle ); int me = 0; - if( set_getint( b->gc->irc, "debug" ) ) + if( set_getint( &b->gc->irc->set, "debug" ) ) serv_got_crap( b->gc, "User %s added to conversation %d", handle, b->id ); /* It might be yourself! */ - if( b->gc->prpl->cmp_buddynames( handle, b->gc->user->username ) == 0 ) + if( b->gc->acc->prpl->handle_cmp( handle, b->gc->username ) == 0 ) { u = user_find( b->gc->irc, b->gc->irc->nick ); if( !b->joined ) @@ -819,11 +807,11 @@ void remove_chat_buddy( struct conversation *b, char *handle, char *reason ) user_t *u; int me = 0; - if( set_getint( b->gc->irc, "debug" ) ) + if( set_getint( &b->gc->irc->set, "debug" ) ) serv_got_crap( b->gc, "User %s removed from conversation %d (%s)", handle, b->id, reason ? reason : "" ); /* It might be yourself! */ - if( g_strcasecmp( handle, b->gc->user->username ) == 0 ) + if( g_strcasecmp( handle, b->gc->username ) == 0 ) { u = user_find( b->gc->irc, b->gc->irc->nick ); b->joined = 0; @@ -881,8 +869,9 @@ struct conversation *conv_findchannel( char *channel ) return( NULL ); } -char *set_eval_away_devoice( irc_t *irc, set_t *set, char *value ) +char *set_eval_away_devoice( set_t *set, char *value ) { + irc_t *irc = set->data; int st; if( ( g_strcasecmp( value, "true" ) == 0 ) || ( g_strcasecmp( value, "yes" ) == 0 ) || ( g_strcasecmp( value, "on" ) == 0 ) ) @@ -896,7 +885,7 @@ char *set_eval_away_devoice( irc_t *irc, set_t *set, char *value ) /* Horror.... */ - if( st != set_getint( irc, "away_devoice" ) ) + if( st != set_getint( &irc->set, "away_devoice" ) ) { char list[80] = ""; user_t *u = irc->users; @@ -936,7 +925,7 @@ char *set_eval_away_devoice( irc_t *irc, set_t *set, char *value ) irc->channel, pm, v, list ); } - return( set_eval_bool( irc, set, value ) ); + return( set_eval_bool( set, value ) ); } @@ -956,7 +945,7 @@ int bim_buddy_msg( struct gaim_connection *gc, char *handle, char *msg, int flag msg = buf; } - st = gc->prpl->send_im( gc, handle, msg, strlen( msg ), flags ); + st = gc->acc->prpl->send_im( gc, handle, msg, strlen( msg ), flags ); g_free( buf ); return st; @@ -973,7 +962,7 @@ int bim_chat_msg( struct gaim_connection *gc, int id, char *msg ) msg = buf; } - st = gc->prpl->chat_send( gc, id, msg ); + st = gc->acc->prpl->chat_send( gc, id, msg ); g_free( buf ); return st; @@ -987,7 +976,7 @@ int bim_set_away( struct gaim_connection *gc, char *away ) char *s; if( !away ) away = ""; - ms = m = gc->prpl->away_states( gc ); + ms = m = gc->acc->prpl->away_states( gc ); while( m ) { @@ -1008,19 +997,19 @@ int bim_set_away( struct gaim_connection *gc, char *away ) if( m ) { - gc->prpl->set_away( gc, m->data, *away ? away : NULL ); + gc->acc->prpl->set_away( gc, m->data, *away ? away : NULL ); } else { s = bim_away_alias_find( ms, away ); if( s ) { - gc->prpl->set_away( gc, s, away ); - if( set_getint( gc->irc, "debug" ) ) + gc->acc->prpl->set_away( gc, s, away ); + if( set_getint( &gc->irc->set, "debug" ) ) serv_got_crap( gc, "Setting away state to %s", s ); } else - gc->prpl->set_away( gc, GAIM_AWAY_CUSTOM, away ); + gc->acc->prpl->set_away( gc, GAIM_AWAY_CUSTOM, away ); } g_list_free( ms ); @@ -1072,46 +1061,46 @@ static char *bim_away_alias_find( GList *gcm, char *away ) void bim_add_allow( struct gaim_connection *gc, char *handle ) { - if( g_slist_find_custom( gc->permit, handle, (GCompareFunc) gc->prpl->cmp_buddynames ) == NULL ) + if( g_slist_find_custom( gc->permit, handle, (GCompareFunc) gc->acc->prpl->handle_cmp ) == NULL ) { gc->permit = g_slist_prepend( gc->permit, g_strdup( handle ) ); } - gc->prpl->add_permit( gc, handle ); + gc->acc->prpl->add_permit( gc, handle ); } void bim_rem_allow( struct gaim_connection *gc, char *handle ) { GSList *l; - if( ( l = g_slist_find_custom( gc->permit, handle, (GCompareFunc) gc->prpl->cmp_buddynames ) ) ) + if( ( l = g_slist_find_custom( gc->permit, handle, (GCompareFunc) gc->acc->prpl->handle_cmp ) ) ) { g_free( l->data ); gc->permit = g_slist_delete_link( gc->permit, l ); } - gc->prpl->rem_permit( gc, handle ); + gc->acc->prpl->rem_permit( gc, handle ); } void bim_add_block( struct gaim_connection *gc, char *handle ) { - if( g_slist_find_custom( gc->deny, handle, (GCompareFunc) gc->prpl->cmp_buddynames ) == NULL ) + if( g_slist_find_custom( gc->deny, handle, (GCompareFunc) gc->acc->prpl->handle_cmp ) == NULL ) { gc->deny = g_slist_prepend( gc->deny, g_strdup( handle ) ); } - gc->prpl->add_deny( gc, handle ); + gc->acc->prpl->add_deny( gc, handle ); } void bim_rem_block( struct gaim_connection *gc, char *handle ) { GSList *l; - if( ( l = g_slist_find_custom( gc->deny, handle, (GCompareFunc) gc->prpl->cmp_buddynames ) ) ) + if( ( l = g_slist_find_custom( gc->deny, handle, (GCompareFunc) gc->acc->prpl->handle_cmp ) ) ) { g_free( l->data ); gc->deny = g_slist_delete_link( gc->deny, l ); } - gc->prpl->rem_deny( gc, handle ); + gc->acc->prpl->rem_deny( gc, handle ); } diff --git a/protocols/nogaim.h b/protocols/nogaim.h index 2080465c..bae4489f 100644 --- a/protocols/nogaim.h +++ b/protocols/nogaim.h @@ -38,6 +38,7 @@ #define _NOGAIM_H #include "bitlbee.h" +#include "account.h" #include "proxy.h" #include "md5.h" #include "sha.h" @@ -62,7 +63,7 @@ /* ok. now the fun begins. first we create a connection structure */ struct gaim_connection { - struct prpl *prpl; + account_t *acc; guint32 flags; /* each connection then can have its own protocol-specific data */ @@ -78,8 +79,6 @@ struct gaim_connection GSList *deny; int permdeny; - struct aim_user *user; - char username[64]; char displayname[128]; char password[32]; @@ -125,26 +124,12 @@ struct buddy { struct gaim_connection *gc; /* the connection it belongs to */ }; -struct aim_user { - char username[64]; - char alias[SELF_ALIAS_LEN]; - char password[32]; - char user_info[2048]; - int options; - struct prpl *prpl; - /* prpls can use this to save information about the user, - * like which server to connect to, etc */ - char proto_opt[7][256]; - - struct gaim_connection *gc; - irc_t *irc; -}; - struct prpl { int options; const char *name; - void (* login) (struct aim_user *); + void (* acc_init) (account_t *); + void (* login) (account_t *); void (* keepalive) (struct gaim_connection *); void (* close) (struct gaim_connection *); @@ -179,7 +164,7 @@ struct prpl { GList *(* away_states)(struct gaim_connection *gc); /* Mainly for AOL, since they think "Bung hole" == "Bu ngho le". *sigh* */ - int (* cmp_buddynames) (const char *who1, const char *who2); + int (* handle_cmp) (const char *who1, const char *who2); }; #define UC_UNAVAILABLE 1 @@ -205,13 +190,13 @@ void bim_add_block( struct gaim_connection *gc, char *handle ); void bim_rem_block( struct gaim_connection *gc, char *handle ); void nogaim_init(); -char *set_eval_away_devoice( irc_t *irc, set_t *set, char *value ); +char *set_eval_away_devoice( set_t *set, char *value ); gboolean auto_reconnect( gpointer data, gint fd, b_input_condition cond ); void cancel_auto_reconnect( struct account *a ); /* multi.c */ -G_MODULE_EXPORT struct gaim_connection *new_gaim_conn( struct aim_user *user ); +G_MODULE_EXPORT struct gaim_connection *new_gaim_conn( account_t *acc ); G_MODULE_EXPORT void destroy_gaim_conn( struct gaim_connection *gc ); G_MODULE_EXPORT void set_login_progress( struct gaim_connection *gc, int step, char *msg ); G_MODULE_EXPORT void hide_login_progress( struct gaim_connection *gc, char *msg ); diff --git a/protocols/oscar/oscar.c b/protocols/oscar/oscar.c index 7c76533a..f65332dc 100644 --- a/protocols/oscar/oscar.c +++ b/protocols/oscar/oscar.c @@ -355,18 +355,26 @@ static gboolean oscar_login_connect(gpointer data, gint source, b_input_conditio return FALSE; } -static void oscar_login(struct aim_user *user) { +static void oscar_acc_init(account_t *acc) +{ + set_t *s; + + s = set_add( &acc->set, "server", NULL, set_eval_account, acc ); + s->flags |= ACC_SET_NOSAVE | ACC_SET_OFFLINE_ONLY; +} + +static void oscar_login(account_t *acc) { aim_session_t *sess; aim_conn_t *conn; char buf[256]; - struct gaim_connection *gc = new_gaim_conn(user); + struct gaim_connection *gc = new_gaim_conn(acc); struct oscar_data *odata = gc->proto_data = g_new0(struct oscar_data, 1); - if (isdigit(*user->username)) { + if (isdigit(acc->user[0])) { odata->icq = TRUE; /* This is odd but it's necessary for a proper do_import and do_export. We don't do those anymore, but let's stick with it, just in case - it accidentally fixes something else too... */ + it accidentally fixes something else too... </bitlbee> */ gc->password[8] = 0; } else { gc->flags |= OPT_CONN_HTML; @@ -389,9 +397,15 @@ static void oscar_login(struct aim_user *user) { return; } - if (g_strcasecmp(user->proto_opt[USEROPT_AUTH], "login.icq.com") != 0 && - g_strcasecmp(user->proto_opt[USEROPT_AUTH], "login.oscar.aol.com") != 0) { - serv_got_crap(gc, "Warning: Unknown OSCAR server: `%s'. Please review your configuration if the connection fails.",user->proto_opt[USEROPT_AUTH]); + if (acc->server == NULL) { + hide_login_progress(gc, "No servername specified"); + signoff(gc); + return; + } + + if (g_strcasecmp(acc->server, "login.icq.com") != 0 && + g_strcasecmp(acc->server, "login.oscar.aol.com") != 0) { + serv_got_crap(gc, "Warning: Unknown OSCAR server: `%s'. Please review your configuration if the connection fails.",acc->server); } g_snprintf(buf, sizeof(buf), _("Signon: %s"), gc->username); @@ -401,11 +415,7 @@ static void oscar_login(struct aim_user *user) { aim_conn_addhandler(sess, conn, 0x0017, 0x0003, gaim_parse_auth_resp, 0); conn->status |= AIM_CONN_STATUS_INPROGRESS; - conn->fd = proxy_connect(user->proto_opt[USEROPT_AUTH][0] ? - user->proto_opt[USEROPT_AUTH] : AIM_DEFAULT_LOGIN_SERVER, - user->proto_opt[USEROPT_AUTHPORT][0] ? - atoi(user->proto_opt[USEROPT_AUTHPORT]) : AIM_LOGIN_PORT, - oscar_login_connect, gc); + conn->fd = proxy_connect(acc->server, AIM_LOGIN_PORT, oscar_login_connect, gc); if (conn->fd < 0) { hide_login_progress(gc, _("Couldn't connect to host")); signoff(gc); @@ -484,14 +494,11 @@ static int gaim_parse_auth_resp(aim_session_t *sess, aim_frame_t *fr, ...) { va_list ap; struct aim_authresp_info *info; int i; char *host; int port; - struct aim_user *user; aim_conn_t *bosconn; struct gaim_connection *gc = sess->aux_data; struct oscar_data *od = gc->proto_data; - user = gc->user; - port = user->proto_opt[USEROPT_AUTHPORT][0] ? - atoi(user->proto_opt[USEROPT_AUTHPORT]) : AIM_LOGIN_PORT, + port = AIM_LOGIN_PORT; va_start(ap, fr); info = va_arg(ap, struct aim_authresp_info *); @@ -870,19 +877,16 @@ static int gaim_handle_redirect(aim_session_t *sess, aim_frame_t *fr, ...) { va_list ap; struct aim_redirect_data *redir; struct gaim_connection *gc = sess->aux_data; - struct aim_user *user = gc->user; aim_conn_t *tstconn; int i; char *host; int port; - port = user->proto_opt[USEROPT_AUTHPORT][0] ? - atoi(user->proto_opt[USEROPT_AUTHPORT]) : AIM_LOGIN_PORT, - va_start(ap, fr); redir = va_arg(ap, struct aim_redirect_data *); va_end(ap); + port = AIM_LOGIN_PORT; for (i = 0; i < (int)strlen(redir->ip); i++) { if (redir->ip[i] == ':') { port = atoi(&(redir->ip[i+1])); @@ -1722,8 +1726,11 @@ static int gaim_parse_locaterights(aim_session_t *sess, aim_frame_t *fr, ...) odata->rights.maxsiglen = odata->rights.maxawaymsglen = (guint)maxsiglen; + /* FIXME: It seems we're not really using this, and it broke now that + struct aim_user is dead. aim_bos_setprofile(sess, fr->conn, gc->user->user_info, NULL, gaim_caps); - + */ + return 1; } @@ -2655,6 +2662,7 @@ void oscar_init() ret->name = "oscar"; ret->away_states = oscar_away_states; ret->login = oscar_login; + ret->acc_init = oscar_acc_init; ret->close = oscar_close; ret->send_im = oscar_send_im; ret->get_info = oscar_get_info; @@ -2672,9 +2680,10 @@ void oscar_init() ret->rem_deny = oscar_rem_deny; ret->set_permit_deny = oscar_set_permit_deny; ret->keepalive = oscar_keepalive; - ret->cmp_buddynames = aim_sncmp; ret->get_status_string = oscar_get_status_string; ret->send_typing = oscar_send_typing; + + ret->handle_cmp = aim_sncmp; register_protocol(ret); } diff --git a/protocols/proxy.c b/protocols/proxy.c deleted file mode 100644 index 70a2158d..00000000 --- a/protocols/proxy.c +++ /dev/null @@ -1,552 +0,0 @@ -/* - * gaim - * - * Copyright (C) 1998-1999, Mark Spencer <markster@marko.net> - * Copyright (C) 2002-2004, Wilmer van der Gaast, 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 - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - */ - -#define BITLBEE_CORE -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <sys/types.h> -#ifndef _WIN32 -#include <sys/socket.h> -#include <netdb.h> -#include <netinet/in.h> -#include <arpa/inet.h> -#include <unistd.h> -#else -#include "sock.h" -#define ETIMEDOUT WSAETIMEDOUT -#define EINPROGRESS WSAEINPROGRESS -#endif -#include <fcntl.h> -#include <errno.h> -#include "nogaim.h" -#include "proxy.h" - -char proxyhost[128] = ""; -int proxyport = 0; -int proxytype = PROXY_NONE; -char proxyuser[128] = ""; -char proxypass[128] = ""; - -struct PHB { - b_event_handler func, proxy_func; - gpointer data, proxy_data; - char *host; - int port; - int fd; - gint inpa; -}; - - - -static struct sockaddr_in *gaim_gethostbyname(const char *host, int port) -{ - static struct sockaddr_in sin; - - if (!inet_aton(host, &sin.sin_addr)) { - struct hostent *hp; - if (!(hp = gethostbyname(host))) { - return NULL; - } - memset(&sin, 0, sizeof(struct sockaddr_in)); - memcpy(&sin.sin_addr.s_addr, hp->h_addr, hp->h_length); - sin.sin_family = hp->h_addrtype; - } else - sin.sin_family = AF_INET; - sin.sin_port = htons(port); - - return &sin; -} - -static gboolean gaim_io_connected(gpointer data, gint source, b_input_condition cond) -{ - struct PHB *phb = data; - unsigned int len; - int error = ETIMEDOUT; - len = sizeof(error); - -#ifndef _WIN32 - if (getsockopt(source, SOL_SOCKET, SO_ERROR, &error, &len) < 0) { - closesocket(source); - b_event_remove(phb->inpa); - if( phb->proxy_func ) - phb->proxy_func(phb->proxy_data, -1, GAIM_INPUT_READ); - else { - phb->func(phb->data, -1, GAIM_INPUT_READ); - g_free(phb); - } - return FALSE; - } -#endif - sock_make_blocking(source); - b_event_remove(phb->inpa); - if( phb->proxy_func ) - phb->proxy_func(phb->proxy_data, source, GAIM_INPUT_READ); - else { - phb->func(phb->data, source, GAIM_INPUT_READ); - g_free(phb); - } - - return FALSE; -} - -static int proxy_connect_none(const char *host, unsigned short port, struct PHB *phb) -{ - struct sockaddr_in *sin; - int fd = -1; - - if (!(sin = gaim_gethostbyname(host, port))) { - g_free(phb); - return -1; - } - - if ((fd = socket(sin->sin_family, SOCK_STREAM, 0)) < 0) { - g_free(phb); - return -1; - } - - sock_make_nonblocking(fd); - - event_debug("proxy_connect_none( \"%s\", %d ) = %d\n", host, port, fd); - - if (connect(fd, (struct sockaddr *)sin, sizeof(*sin)) < 0) { - if (sockerr_again()) { - phb->inpa = b_input_add(fd, GAIM_INPUT_WRITE, gaim_io_connected, phb); - phb->fd = fd; - } else { - closesocket(fd); - g_free(phb); - return -1; - } - } - - return fd; -} - - -/* Connecting to HTTP proxies */ - -#define HTTP_GOODSTRING "HTTP/1.0 200 Connection established" -#define HTTP_GOODSTRING2 "HTTP/1.1 200 Connection established" - -static gboolean http_canread(gpointer data, gint source, b_input_condition cond) -{ - int nlc = 0; - int pos = 0; - struct PHB *phb = data; - char inputline[8192]; - - b_event_remove(phb->inpa); - - while ((pos < sizeof(inputline)-1) && (nlc != 2) && (read(source, &inputline[pos++], 1) == 1)) { - if (inputline[pos - 1] == '\n') - nlc++; - else if (inputline[pos - 1] != '\r') - nlc = 0; - } - inputline[pos] = '\0'; - - if ((memcmp(HTTP_GOODSTRING, inputline, strlen(HTTP_GOODSTRING)) == 0) || - (memcmp(HTTP_GOODSTRING2, inputline, strlen(HTTP_GOODSTRING2)) == 0)) { - phb->func(phb->data, source, GAIM_INPUT_READ); - g_free(phb->host); - g_free(phb); - return FALSE; - } - - close(source); - phb->func(phb->data, -1, GAIM_INPUT_READ); - g_free(phb->host); - g_free(phb); - - return FALSE; -} - -static gboolean http_canwrite(gpointer data, gint source, b_input_condition cond) -{ - char cmd[384]; - struct PHB *phb = data; - unsigned int len; - int error = ETIMEDOUT; - if (phb->inpa > 0) - b_event_remove(phb->inpa); - len = sizeof(error); - if (getsockopt(source, SOL_SOCKET, SO_ERROR, &error, &len) < 0) { - close(source); - phb->func(phb->data, -1, GAIM_INPUT_READ); - g_free(phb->host); - g_free(phb); - return FALSE; - } - sock_make_blocking(source); - - g_snprintf(cmd, sizeof(cmd), "CONNECT %s:%d HTTP/1.1\r\nHost: %s:%d\r\n", phb->host, phb->port, - phb->host, phb->port); - if (send(source, cmd, strlen(cmd), 0) < 0) { - close(source); - phb->func(phb->data, -1, GAIM_INPUT_READ); - g_free(phb->host); - g_free(phb); - return FALSE; - } - - if (proxyuser && *proxyuser) { - char *t1, *t2; - t1 = g_strdup_printf("%s:%s", proxyuser, proxypass); - t2 = tobase64(t1); - g_free(t1); - g_snprintf(cmd, sizeof(cmd), "Proxy-Authorization: Basic %s\r\n", t2); - g_free(t2); - if (send(source, cmd, strlen(cmd), 0) < 0) { - close(source); - phb->func(phb->data, -1, GAIM_INPUT_READ); - g_free(phb->host); - g_free(phb); - return FALSE; - } - } - - g_snprintf(cmd, sizeof(cmd), "\r\n"); - if (send(source, cmd, strlen(cmd), 0) < 0) { - close(source); - phb->func(phb->data, -1, GAIM_INPUT_READ); - g_free(phb->host); - g_free(phb); - return FALSE; - } - - phb->inpa = b_input_add(source, GAIM_INPUT_READ, http_canread, phb); - - return FALSE; -} - -static int proxy_connect_http(const char *host, unsigned short port, struct PHB *phb) -{ - phb->host = g_strdup(host); - phb->port = port; - phb->proxy_func = http_canwrite; - phb->proxy_data = phb; - - return( proxy_connect_none( proxyhost, proxyport, phb ) ); -} - - -/* Connecting to SOCKS4 proxies */ - -static gboolean s4_canread(gpointer data, gint source, b_input_condition cond) -{ - unsigned char packet[12]; - struct PHB *phb = data; - - b_event_remove(phb->inpa); - - memset(packet, 0, sizeof(packet)); - if (read(source, packet, 9) >= 4 && packet[1] == 90) { - phb->func(phb->data, source, GAIM_INPUT_READ); - g_free(phb->host); - g_free(phb); - return FALSE; - } - - close(source); - phb->func(phb->data, -1, GAIM_INPUT_READ); - g_free(phb->host); - g_free(phb); - - return FALSE; -} - -static gboolean s4_canwrite(gpointer data, gint source, b_input_condition cond) -{ - unsigned char packet[12]; - struct hostent *hp; - struct PHB *phb = data; - unsigned int len; - int error = ETIMEDOUT; - if (phb->inpa > 0) - b_event_remove(phb->inpa); - len = sizeof(error); - if (getsockopt(source, SOL_SOCKET, SO_ERROR, &error, &len) < 0) { - close(source); - phb->func(phb->data, -1, GAIM_INPUT_READ); - g_free(phb->host); - g_free(phb); - return FALSE; - } - sock_make_blocking(source); - - /* XXX does socks4 not support host name lookups by the proxy? */ - if (!(hp = gethostbyname(phb->host))) { - close(source); - phb->func(phb->data, -1, GAIM_INPUT_READ); - g_free(phb->host); - g_free(phb); - return FALSE; - } - - packet[0] = 4; - packet[1] = 1; - packet[2] = phb->port >> 8; - packet[3] = phb->port & 0xff; - packet[4] = (unsigned char)(hp->h_addr_list[0])[0]; - packet[5] = (unsigned char)(hp->h_addr_list[0])[1]; - packet[6] = (unsigned char)(hp->h_addr_list[0])[2]; - packet[7] = (unsigned char)(hp->h_addr_list[0])[3]; - packet[8] = 0; - if (write(source, packet, 9) != 9) { - close(source); - phb->func(phb->data, -1, GAIM_INPUT_READ); - g_free(phb->host); - g_free(phb); - return FALSE; - } - - phb->inpa = b_input_add(source, GAIM_INPUT_READ, s4_canread, phb); - - return FALSE; -} - -static int proxy_connect_socks4(const char *host, unsigned short port, struct PHB *phb) -{ - phb->host = g_strdup(host); - phb->port = port; - phb->proxy_func = s4_canwrite; - phb->proxy_data = phb; - - return( proxy_connect_none( proxyhost, proxyport, phb ) ); -} - - -/* Connecting to SOCKS5 proxies */ - -static gboolean s5_canread_again(gpointer data, gint source, b_input_condition cond) -{ - unsigned char buf[512]; - struct PHB *phb = data; - - b_event_remove(phb->inpa); - - if (read(source, buf, 10) < 10) { - close(source); - phb->func(phb->data, -1, GAIM_INPUT_READ); - g_free(phb->host); - g_free(phb); - return FALSE; - } - if ((buf[0] != 0x05) || (buf[1] != 0x00)) { - close(source); - phb->func(phb->data, -1, GAIM_INPUT_READ); - g_free(phb->host); - g_free(phb); - return FALSE; - } - - phb->func(phb->data, source, GAIM_INPUT_READ); - g_free(phb->host); - g_free(phb); - - return FALSE; -} - -static void s5_sendconnect(gpointer data, gint source) -{ - unsigned char buf[512]; - struct PHB *phb = data; - int hlen = strlen(phb->host); - - buf[0] = 0x05; - buf[1] = 0x01; /* CONNECT */ - buf[2] = 0x00; /* reserved */ - buf[3] = 0x03; /* address type -- host name */ - buf[4] = hlen; - memcpy(buf + 5, phb->host, hlen); - buf[5 + strlen(phb->host)] = phb->port >> 8; - buf[5 + strlen(phb->host) + 1] = phb->port & 0xff; - - if (write(source, buf, (5 + strlen(phb->host) + 2)) < (5 + strlen(phb->host) + 2)) { - close(source); - phb->func(phb->data, -1, GAIM_INPUT_READ); - g_free(phb->host); - g_free(phb); - return; - } - - phb->inpa = b_input_add(source, GAIM_INPUT_READ, s5_canread_again, phb); -} - -static gboolean s5_readauth(gpointer data, gint source, b_input_condition cond) -{ - unsigned char buf[512]; - struct PHB *phb = data; - - b_event_remove(phb->inpa); - - if (read(source, buf, 2) < 2) { - close(source); - phb->func(phb->data, -1, GAIM_INPUT_READ); - g_free(phb->host); - g_free(phb); - return FALSE; - } - - if ((buf[0] != 0x01) || (buf[1] != 0x00)) { - close(source); - phb->func(phb->data, -1, GAIM_INPUT_READ); - g_free(phb->host); - g_free(phb); - return FALSE; - } - - s5_sendconnect(phb, source); - - return FALSE; -} - -static gboolean s5_canread(gpointer data, gint source, b_input_condition cond) -{ - unsigned char buf[512]; - struct PHB *phb = data; - - b_event_remove(phb->inpa); - - if (read(source, buf, 2) < 2) { - close(source); - phb->func(phb->data, -1, GAIM_INPUT_READ); - g_free(phb->host); - g_free(phb); - return FALSE; - } - - if ((buf[0] != 0x05) || (buf[1] == 0xff)) { - close(source); - phb->func(phb->data, -1, GAIM_INPUT_READ); - g_free(phb->host); - g_free(phb); - return FALSE; - } - - if (buf[1] == 0x02) { - unsigned int i = strlen(proxyuser), j = strlen(proxypass); - buf[0] = 0x01; /* version 1 */ - buf[1] = i; - memcpy(buf + 2, proxyuser, i); - buf[2 + i] = j; - memcpy(buf + 2 + i + 1, proxypass, j); - if (write(source, buf, 3 + i + j) < 3 + i + j) { - close(source); - phb->func(phb->data, -1, GAIM_INPUT_READ); - g_free(phb->host); - g_free(phb); - return FALSE; - } - - phb->inpa = b_input_add(source, GAIM_INPUT_READ, s5_readauth, phb); - } else { - s5_sendconnect(phb, source); - } - - return FALSE; -} - -static gboolean s5_canwrite(gpointer data, gint source, b_input_condition cond) -{ - unsigned char buf[512]; - int i; - struct PHB *phb = data; - unsigned int len; - int error = ETIMEDOUT; - if (phb->inpa > 0) - b_event_remove(phb->inpa); - len = sizeof(error); - if (getsockopt(source, SOL_SOCKET, SO_ERROR, &error, &len) < 0) { - close(source); - phb->func(phb->data, -1, GAIM_INPUT_READ); - g_free(phb->host); - g_free(phb); - return FALSE; - } - sock_make_blocking(source); - - i = 0; - buf[0] = 0x05; /* SOCKS version 5 */ - if (proxyuser[0]) { - buf[1] = 0x02; /* two methods */ - buf[2] = 0x00; /* no authentication */ - buf[3] = 0x02; /* username/password authentication */ - i = 4; - } else { - buf[1] = 0x01; - buf[2] = 0x00; - i = 3; - } - - if (write(source, buf, i) < i) { - close(source); - phb->func(phb->data, -1, GAIM_INPUT_READ); - g_free(phb->host); - g_free(phb); - return FALSE; - } - - phb->inpa = b_input_add(source, GAIM_INPUT_READ, s5_canread, phb); - - return FALSE; -} - -static int proxy_connect_socks5(const char *host, unsigned short port, struct PHB *phb) -{ - phb->host = g_strdup(host); - phb->port = port; - phb->proxy_func = s5_canwrite; - phb->proxy_data = phb; - - return( proxy_connect_none( proxyhost, proxyport, phb ) ); -} - - -/* Export functions */ - -int proxy_connect(const char *host, int port, b_event_handler func, gpointer data) -{ - struct PHB *phb; - - if (!host || !port || (port == -1) || !func || strlen(host) > 128) { - return -1; - } - - phb = g_new0(struct PHB, 1); - phb->func = func; - phb->data = data; - - if ((proxytype == PROXY_NONE) || !proxyhost || !proxyhost[0] || !proxyport || (proxyport == -1)) - return proxy_connect_none(host, port, phb); - else if (proxytype == PROXY_HTTP) - return proxy_connect_http(host, port, phb); - else if (proxytype == PROXY_SOCKS4) - return proxy_connect_socks4(host, port, phb); - else if (proxytype == PROXY_SOCKS5) - return proxy_connect_socks5(host, port, phb); - - if (phb->host) g_free(phb); - g_free(phb); - return -1; -} diff --git a/protocols/proxy.h b/protocols/proxy.h deleted file mode 100644 index 680790a5..00000000 --- a/protocols/proxy.h +++ /dev/null @@ -1,53 +0,0 @@ -/* - * nogaim - * - * Copyright (C) 1998-1999, Mark Spencer <markster@marko.net> - * - * 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 - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - */ - -/* this is the export part of the proxy.c file. it does a little - prototype-ing stuff and redefine some net function to mask them - with some kind of transparent layer */ - -#ifndef _PROXY_H_ -#define _PROXY_H_ - -#include <sys/types.h> -#ifndef _WIN32 -#include <sys/socket.h> -#include <netdb.h> -#include <netinet/in.h> -#endif -#include <glib.h> -#include <gmodule.h> - -#include "events.h" - -#define PROXY_NONE 0 -#define PROXY_HTTP 1 -#define PROXY_SOCKS4 2 -#define PROXY_SOCKS5 3 - -extern char proxyhost[128]; -extern int proxyport; -extern int proxytype; -extern char proxyuser[128]; -extern char proxypass[128]; - -G_MODULE_EXPORT int proxy_connect(const char *host, int port, b_event_handler func, gpointer data); - -#endif /* _PROXY_H_ */ diff --git a/protocols/sha.c b/protocols/sha.c deleted file mode 100644 index 895505a1..00000000 --- a/protocols/sha.c +++ /dev/null @@ -1,173 +0,0 @@ -/* - * The contents of this file are subject to the Mozilla Public - * License Version 1.1 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy of - * the License at http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS - * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or - * implied. See the License for the specific language governing - * rights and limitations under the License. - * - * The Original Code is SHA 180-1 Reference Implementation (Compact version) - * - * The Initial Developer of the Original Code is Paul Kocher of - * Cryptography Research. Portions created by Paul Kocher are - * Copyright (C) 1995-9 by Cryptography Research, Inc. All - * Rights Reserved. - * - * Contributor(s): - * - */ - -#define BITLBEE_CORE -#include "nogaim.h" - -static void shaHashBlock(SHA_CTX *ctx); - -void shaInit(SHA_CTX *ctx) { - int i; - - ctx->lenW = 0; - ctx->sizeHi = ctx->sizeLo = 0; - - /* Initialize H with the magic constants (see FIPS180 for constants) - */ - ctx->H[0] = 0x67452301L; - ctx->H[1] = 0xefcdab89L; - ctx->H[2] = 0x98badcfeL; - ctx->H[3] = 0x10325476L; - ctx->H[4] = 0xc3d2e1f0L; - - for (i = 0; i < 80; i++) - ctx->W[i] = 0; -} - - -void shaUpdate(SHA_CTX *ctx, unsigned char *dataIn, int len) { - int i; - - /* Read the data into W and process blocks as they get full - */ - for (i = 0; i < len; i++) { - ctx->W[ctx->lenW / 4] <<= 8; - ctx->W[ctx->lenW / 4] |= (guint32)dataIn[i]; - if ((++ctx->lenW) % 64 == 0) { - shaHashBlock(ctx); - ctx->lenW = 0; - } - ctx->sizeLo += 8; - ctx->sizeHi += (ctx->sizeLo < 8); - } -} - - -void shaFinal(SHA_CTX *ctx, unsigned char hashout[20]) { - unsigned char pad0x80 = 0x80; - unsigned char pad0x00 = 0x00; - unsigned char padlen[8]; - int i; - - /* Pad with a binary 1 (e.g. 0x80), then zeroes, then length - */ - padlen[0] = (unsigned char)((ctx->sizeHi >> 24) & 255); - padlen[1] = (unsigned char)((ctx->sizeHi >> 16) & 255); - padlen[2] = (unsigned char)((ctx->sizeHi >> 8) & 255); - padlen[3] = (unsigned char)((ctx->sizeHi >> 0) & 255); - padlen[4] = (unsigned char)((ctx->sizeLo >> 24) & 255); - padlen[5] = (unsigned char)((ctx->sizeLo >> 16) & 255); - padlen[6] = (unsigned char)((ctx->sizeLo >> 8) & 255); - padlen[7] = (unsigned char)((ctx->sizeLo >> 0) & 255); - shaUpdate(ctx, &pad0x80, 1); - while (ctx->lenW != 56) - shaUpdate(ctx, &pad0x00, 1); - shaUpdate(ctx, padlen, 8); - - /* Output hash - */ - for (i = 0; i < 20; i++) { - hashout[i] = (unsigned char)(ctx->H[i / 4] >> 24); - ctx->H[i / 4] <<= 8; - } - - /* - * Re-initialize the context (also zeroizes contents) - */ - shaInit(ctx); -} - - -void shaBlock(unsigned char *dataIn, int len, unsigned char hashout[20]) { - SHA_CTX ctx; - - shaInit(&ctx); - shaUpdate(&ctx, dataIn, len); - shaFinal(&ctx, hashout); -} - - -#define SHA_ROTL(X,n) ((((X) << (n)) | ((X) >> (32-(n)))) & 0xffffffffL) - -static void shaHashBlock(SHA_CTX *ctx) { - int t; - guint32 A,B,C,D,E,TEMP; - - for (t = 16; t <= 79; t++) - ctx->W[t] = - SHA_ROTL(ctx->W[t-3] ^ ctx->W[t-8] ^ ctx->W[t-14] ^ ctx->W[t-16], 1); - - A = ctx->H[0]; - B = ctx->H[1]; - C = ctx->H[2]; - D = ctx->H[3]; - E = ctx->H[4]; - - for (t = 0; t <= 19; t++) { - TEMP = (SHA_ROTL(A,5) + (((C^D)&B)^D) + E + ctx->W[t] + 0x5a827999L) & 0xffffffffL; - E = D; D = C; C = SHA_ROTL(B, 30); B = A; A = TEMP; - } - for (t = 20; t <= 39; t++) { - TEMP = (SHA_ROTL(A,5) + (B^C^D) + E + ctx->W[t] + 0x6ed9eba1L) & 0xffffffffL; - E = D; D = C; C = SHA_ROTL(B, 30); B = A; A = TEMP; - } - for (t = 40; t <= 59; t++) { - TEMP = (SHA_ROTL(A,5) + ((B&C)|(D&(B|C))) + E + ctx->W[t] + 0x8f1bbcdcL) & 0xffffffffL; - E = D; D = C; C = SHA_ROTL(B, 30); B = A; A = TEMP; - } - for (t = 60; t <= 79; t++) { - TEMP = (SHA_ROTL(A,5) + (B^C^D) + E + ctx->W[t] + 0xca62c1d6L) & 0xffffffffL; - E = D; D = C; C = SHA_ROTL(B, 30); B = A; A = TEMP; - } - - ctx->H[0] += A; - ctx->H[1] += B; - ctx->H[2] += C; - ctx->H[3] += D; - ctx->H[4] += E; -} - -/*---------------------------------------------------------------------------- - * - * This code added by Thomas "temas" Muldowney for Jabber compatability - * - *---------------------------------------------------------------------------*/ -char *shahash(char *str) -{ - static char final[41]; - char *pos; - unsigned char hashval[20]; - int x; - - if(!str || strlen(str) == 0) - return NULL; - - shaBlock((unsigned char *)str, strlen(str), hashval); - - pos = final; - for(x=0;x<20;x++) - { - g_snprintf(pos, 3, "%02x", hashval[x]); - pos += 2; - } - return (char *)final; -} diff --git a/protocols/sha.h b/protocols/sha.h deleted file mode 100644 index e8152b1b..00000000 --- a/protocols/sha.h +++ /dev/null @@ -1,21 +0,0 @@ -#ifndef __SHA_H__ -#define __SHA_H__ - -#include <gmodule.h> - -G_MODULE_EXPORT int strprintsha(char *dest, int *hashval); - -typedef struct { - guint32 H[5]; - guint32 W[80]; - int lenW; - guint32 sizeHi,sizeLo; -} SHA_CTX; - -G_MODULE_EXPORT void shaInit(SHA_CTX *ctx); -G_MODULE_EXPORT void shaUpdate(SHA_CTX *ctx, unsigned char *dataIn, int len); -G_MODULE_EXPORT void shaFinal(SHA_CTX *ctx, unsigned char hashout[20]); -G_MODULE_EXPORT void shaBlock(unsigned char *dataIn, int len, unsigned char hashout[20]); -G_MODULE_EXPORT char *shahash(char *str); - -#endif diff --git a/protocols/ssl_bogus.c b/protocols/ssl_bogus.c deleted file mode 100644 index 00aaa7c4..00000000 --- a/protocols/ssl_bogus.c +++ /dev/null @@ -1,57 +0,0 @@ - /********************************************************************\ - * BitlBee -- An IRC to other IM-networks gateway * - * * - * Copyright 2002-2004 Wilmer van der Gaast and others * - \********************************************************************/ - -/* SSL module - dummy version */ - -/* - 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" - -int ssl_errno; - -void *ssl_connect( char *host, int port, ssl_input_function func, gpointer data ) -{ - return( NULL ); -} - -int ssl_read( void *conn, char *buf, int len ) -{ - return( -1 ); -} - -int ssl_write( void *conn, const char *buf, int len ) -{ - return( -1 ); -} - -void ssl_disconnect( void *conn_ ) -{ -} - -int ssl_getfd( void *conn ) -{ - return( -1 ); -} - -b_input_condition ssl_getdirection( void *conn ) -{ - return GAIM_INPUT_READ; -} diff --git a/protocols/ssl_client.h b/protocols/ssl_client.h deleted file mode 100644 index 1a9c79e9..00000000 --- a/protocols/ssl_client.h +++ /dev/null @@ -1,42 +0,0 @@ - /********************************************************************\ - * BitlBee -- An IRC to other IM-networks gateway * - * * - * Copyright 2002-2004 Wilmer van der Gaast and others * - \********************************************************************/ - -/* SSL module */ - -/* - 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 <glib.h> -#include "proxy.h" - -#define SSL_OK 0 -#define SSL_NOHANDSHAKE 1 -#define SSL_AGAIN 2 - -extern int ssl_errno; - -typedef gboolean (*ssl_input_function)(gpointer, void*, b_input_condition); - -G_MODULE_EXPORT void *ssl_connect( char *host, int port, ssl_input_function func, gpointer data ); -G_MODULE_EXPORT int ssl_read( void *conn, char *buf, int len ); -G_MODULE_EXPORT int ssl_write( void *conn, const char *buf, int len ); -G_MODULE_EXPORT void ssl_disconnect( void *conn_ ); -G_MODULE_EXPORT int ssl_getfd( void *conn ); -G_MODULE_EXPORT b_input_condition ssl_getdirection( void *conn ); diff --git a/protocols/ssl_gnutls.c b/protocols/ssl_gnutls.c deleted file mode 100644 index 3ebe1756..00000000 --- a/protocols/ssl_gnutls.c +++ /dev/null @@ -1,206 +0,0 @@ - /********************************************************************\ - * BitlBee -- An IRC to other IM-networks gateway * - * * - * Copyright 2002-2004 Wilmer van der Gaast and others * - \********************************************************************/ - -/* SSL module - GnuTLS version */ - -/* - 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 <gnutls/gnutls.h> -#include <fcntl.h> -#include <unistd.h> -#include "proxy.h" -#include "ssl_client.h" -#include "sock.h" -#include "stdlib.h" - -int ssl_errno = 0; - -static gboolean initialized = FALSE; - -struct scd -{ - ssl_input_function func; - gpointer data; - int fd; - gboolean established; - int inpa; - - gnutls_session session; - gnutls_certificate_credentials xcred; -}; - -static gboolean ssl_connected( gpointer data, gint source, b_input_condition cond ); - - -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 ); - conn->func = func; - conn->data = data; - conn->inpa = -1; - - if( conn->fd < 0 ) - { - g_free( conn ); - return( NULL ); - } - - if( !initialized ) - { - gnutls_global_init(); - initialized = TRUE; - atexit( gnutls_global_deinit ); - } - - gnutls_certificate_allocate_credentials( &conn->xcred ); - gnutls_init( &conn->session, GNUTLS_CLIENT ); - gnutls_set_default_priority( conn->session ); - gnutls_credentials_set( conn->session, GNUTLS_CRD_CERTIFICATE, conn->xcred ); - - return( conn ); -} - -static gboolean ssl_handshake( gpointer data, gint source, b_input_condition cond ); - -static gboolean ssl_connected( gpointer data, gint source, b_input_condition cond ) -{ - struct scd *conn = data; - - if( source == -1 ) - { - conn->func( conn->data, NULL, cond ); - - gnutls_deinit( conn->session ); - gnutls_certificate_free_credentials( conn->xcred ); - - g_free( conn ); - - return FALSE; - } - - sock_make_nonblocking( conn->fd ); - gnutls_transport_set_ptr( conn->session, (gnutls_transport_ptr) conn->fd ); - - return ssl_handshake( data, source, cond ); -} - -static gboolean ssl_handshake( gpointer data, gint source, b_input_condition cond ) -{ - struct scd *conn = data; - int st; - - if( ( st = gnutls_handshake( conn->session ) ) < 0 ) - { - if( st == GNUTLS_E_AGAIN || st == GNUTLS_E_INTERRUPTED ) - { - conn->inpa = b_input_add( conn->fd, ssl_getdirection( conn ), - ssl_handshake, data ); - } - else - { - conn->func( conn->data, NULL, cond ); - - gnutls_deinit( conn->session ); - gnutls_certificate_free_credentials( conn->xcred ); - closesocket( conn->fd ); - - g_free( conn ); - } - } - else - { - /* For now we can't handle non-blocking perfectly everywhere... */ - sock_make_blocking( conn->fd ); - - conn->established = TRUE; - conn->func( conn->data, conn, cond ); - } - - return FALSE; -} - -int ssl_read( void *conn, char *buf, int len ) -{ - int st; - - if( !((struct scd*)conn)->established ) - { - ssl_errno = SSL_NOHANDSHAKE; - return( -1 ); - } - - st = gnutls_record_recv( ((struct scd*)conn)->session, buf, len ); - - ssl_errno = SSL_OK; - if( st == GNUTLS_E_AGAIN || st == GNUTLS_E_INTERRUPTED ) - ssl_errno = SSL_AGAIN; - - return st; -} - -int ssl_write( void *conn, const char *buf, int len ) -{ - int st; - - if( !((struct scd*)conn)->established ) - { - ssl_errno = SSL_NOHANDSHAKE; - return( -1 ); - } - - st = gnutls_record_send( ((struct scd*)conn)->session, buf, len ); - - ssl_errno = SSL_OK; - if( st == GNUTLS_E_AGAIN || st == GNUTLS_E_INTERRUPTED ) - ssl_errno = SSL_AGAIN; - - return st; -} - -void ssl_disconnect( void *conn_ ) -{ - struct scd *conn = conn_; - - if( conn->inpa != -1 ) - b_event_remove( conn->inpa ); - - if( conn->established ) - gnutls_bye( conn->session, GNUTLS_SHUT_WR ); - - closesocket( conn->fd ); - - gnutls_deinit( conn->session ); - gnutls_certificate_free_credentials( conn->xcred ); - g_free( conn ); -} - -int ssl_getfd( void *conn ) -{ - return( ((struct scd*)conn)->fd ); -} - -b_input_condition ssl_getdirection( void *conn ) -{ - return( gnutls_record_get_direction( ((struct scd*)conn)->session ) ? - GAIM_INPUT_WRITE : GAIM_INPUT_READ ); -} diff --git a/protocols/ssl_nss.c b/protocols/ssl_nss.c deleted file mode 100644 index 218b3a80..00000000 --- a/protocols/ssl_nss.c +++ /dev/null @@ -1,190 +0,0 @@ - /********************************************************************\ - * BitlBee -- An IRC to other IM-networks gateway * - * * - * Copyright 2002-2005 Wilmer van der Gaast and others * - \********************************************************************/ - -/* SSL module - NSS version */ - -/* Copyright 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 "bitlbee.h" -#include "proxy.h" -#include "ssl_client.h" -#include "sock.h" -#include <nspr.h> -#include <prio.h> -#include <sslproto.h> -#include <nss.h> -#include <private/pprio.h> -#include <ssl.h> -#include <secerr.h> -#include <sslerr.h> - -int ssl_errno = 0; - -static gboolean initialized = FALSE; - -struct scd -{ - ssl_input_function func; - gpointer data; - int fd; - PRFileDesc *prfd; - gboolean established; -}; - -static gboolean ssl_connected( gpointer data, gint source, b_input_condition cond ); - - -static SECStatus nss_auth_cert (void *arg, PRFileDesc *socket, PRBool checksig, PRBool isserver) -{ - return SECSuccess; -} - -static SECStatus nss_bad_cert (void *arg, PRFileDesc *socket) -{ - PRErrorCode err; - - if(!arg) return SECFailure; - - *(PRErrorCode *)arg = err = PORT_GetError(); - - switch(err) { - case SEC_ERROR_INVALID_AVA: - case SEC_ERROR_INVALID_TIME: - case SEC_ERROR_BAD_SIGNATURE: - case SEC_ERROR_EXPIRED_CERTIFICATE: - case SEC_ERROR_UNKNOWN_ISSUER: - case SEC_ERROR_UNTRUSTED_CERT: - case SEC_ERROR_CERT_VALID: - case SEC_ERROR_EXPIRED_ISSUER_CERTIFICATE: - case SEC_ERROR_CRL_EXPIRED: - case SEC_ERROR_CRL_BAD_SIGNATURE: - case SEC_ERROR_EXTENSION_VALUE_INVALID: - case SEC_ERROR_CA_CERT_INVALID: - case SEC_ERROR_CERT_USAGES_INVALID: - case SEC_ERROR_UNKNOWN_CRITICAL_EXTENSION: - return SECSuccess; - - default: - return SECFailure; - } -} - - -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 ); - conn->func = func; - conn->data = data; - - if( conn->fd < 0 ) - { - g_free( conn ); - return( NULL ); - } - - if( !initialized ) - { - PR_Init( PR_SYSTEM_THREAD, PR_PRIORITY_NORMAL, 1); - NSS_NoDB_Init(NULL); - NSS_SetDomesticPolicy(); - } - - - return( conn ); -} - -static gboolean ssl_connected( gpointer data, gint source, b_input_condition cond ) -{ - struct scd *conn = data; - - if( source == -1 ) - goto ssl_connected_failure; - - /* Until we find out how to handle non-blocking I/O with NSS... */ - sock_make_blocking( conn->fd ); - - conn->prfd = SSL_ImportFD(NULL, PR_ImportTCPSocket(source)); - SSL_OptionSet(conn->prfd, SSL_SECURITY, PR_TRUE); - SSL_OptionSet(conn->prfd, SSL_HANDSHAKE_AS_CLIENT, PR_TRUE); - SSL_BadCertHook(conn->prfd, (SSLBadCertHandler)nss_bad_cert, NULL); - SSL_AuthCertificateHook(conn->prfd, (SSLAuthCertificate)nss_auth_cert, (void *)CERT_GetDefaultCertDB()); - SSL_ResetHandshake(conn->prfd, PR_FALSE); - - if (SSL_ForceHandshake(conn->prfd)) { - goto ssl_connected_failure; - } - - - conn->established = TRUE; - conn->func( conn->data, conn, cond ); - return FALSE; - - ssl_connected_failure: - - conn->func( conn->data, NULL, cond ); - - PR_Close( conn -> prfd ); - if( source >= 0 ) closesocket( source ); - g_free( conn ); - - return FALSE; -} - -int ssl_read( void *conn, char *buf, int len ) -{ - if( !((struct scd*)conn)->established ) - return( 0 ); - - return( PR_Read( ((struct scd*)conn)->prfd, buf, len ) ); -} - -int ssl_write( void *conn, const char *buf, int len ) -{ - if( !((struct scd*)conn)->established ) - return( 0 ); - - return( PR_Write ( ((struct scd*)conn)->prfd, buf, len ) ); -} - -void ssl_disconnect( void *conn_ ) -{ - struct scd *conn = conn_; - - PR_Close( conn->prfd ); - closesocket( conn->fd ); - - g_free( conn ); -} - -int ssl_getfd( void *conn ) -{ - return( ((struct scd*)conn)->fd ); -} - -b_input_condition ssl_getdirection( void *conn ) -{ - /* Just in case someone calls us, let's return the most likely case: */ - return GAIM_INPUT_READ; -} diff --git a/protocols/ssl_openssl.c b/protocols/ssl_openssl.c deleted file mode 100644 index b6f6c520..00000000 --- a/protocols/ssl_openssl.c +++ /dev/null @@ -1,221 +0,0 @@ - /********************************************************************\ - * BitlBee -- An IRC to other IM-networks gateway * - * * - * Copyright 2002-2004 Wilmer van der Gaast and others * - \********************************************************************/ - -/* SSL module - OpenSSL version */ - -/* - 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 <openssl/crypto.h> -#include <openssl/rand.h> -#include <openssl/x509.h> -#include <openssl/pem.h> -#include <openssl/ssl.h> -#include <openssl/err.h> - -#include "proxy.h" -#include "ssl_client.h" -#include "sock.h" - -int ssl_errno = 0; - -static gboolean initialized = FALSE; - -struct scd -{ - ssl_input_function func; - gpointer data; - int fd; - gboolean established; - - int inpa; - int lasterr; /* Necessary for SSL_get_error */ - SSL *ssl; - SSL_CTX *ssl_ctx; -}; - -static gboolean ssl_connected( gpointer data, gint source, b_input_condition cond ); - - -void *ssl_connect( char *host, int port, ssl_input_function func, gpointer data ) -{ - struct scd *conn = g_new0( struct scd, 1 ); - SSL_METHOD *meth; - - conn->fd = proxy_connect( host, port, ssl_connected, conn ); - conn->func = func; - conn->data = data; - - if( conn->fd < 0 ) - { - g_free( conn ); - return( NULL ); - } - - if( !initialized ) - { - initialized = TRUE; - SSLeay_add_ssl_algorithms(); - } - - meth = TLSv1_client_method(); - conn->ssl_ctx = SSL_CTX_new( meth ); - if( conn->ssl_ctx == NULL ) - { - conn->fd = -1; - return( NULL ); - } - - conn->ssl = SSL_new( conn->ssl_ctx ); - if( conn->ssl == NULL ) - { - conn->fd = -1; - return( NULL ); - } - - return( conn ); -} - -static gboolean ssl_handshake( gpointer data, gint source, b_input_condition cond ); - -static gboolean ssl_connected( gpointer data, gint source, b_input_condition cond ) -{ - struct scd *conn = data; - - if( source == -1 ) - return ssl_handshake( data, -1, cond ); - - /* We can do at least the handshake with non-blocking I/O */ - sock_make_nonblocking( conn->fd ); - SSL_set_fd( conn->ssl, conn->fd ); - - return ssl_handshake( data, source, cond ); -} - -static gboolean ssl_handshake( gpointer data, gint source, b_input_condition cond ) -{ - struct scd *conn = data; - int st; - - if( ( st = SSL_connect( conn->ssl ) ) < 0 ) - { - conn->lasterr = SSL_get_error( conn->ssl, st ); - if( conn->lasterr != SSL_ERROR_WANT_READ && conn->lasterr != SSL_ERROR_WANT_WRITE ) - goto ssl_connected_failure; - - conn->inpa = b_input_add( conn->fd, ssl_getdirection( conn ), ssl_handshake, data ); - return FALSE; - } - - conn->established = TRUE; - sock_make_blocking( conn->fd ); /* For now... */ - conn->func( conn->data, conn, cond ); - return FALSE; - -ssl_connected_failure: - conn->func( conn->data, NULL, cond ); - - if( conn->ssl ) - { - SSL_shutdown( conn->ssl ); - SSL_free( conn->ssl ); - } - if( conn->ssl_ctx ) - { - SSL_CTX_free( conn->ssl_ctx ); - } - if( source >= 0 ) closesocket( source ); - g_free( conn ); - - return FALSE; -} - -int ssl_read( void *conn, char *buf, int len ) -{ - int st; - - if( !((struct scd*)conn)->established ) - { - ssl_errno = SSL_NOHANDSHAKE; - return -1; - } - - st = SSL_read( ((struct scd*)conn)->ssl, buf, len ); - - ssl_errno = SSL_OK; - if( st <= 0 ) - { - ((struct scd*)conn)->lasterr = SSL_get_error( ((struct scd*)conn)->ssl, st ); - if( ((struct scd*)conn)->lasterr == SSL_ERROR_WANT_READ || ((struct scd*)conn)->lasterr == SSL_ERROR_WANT_WRITE ) - ssl_errno = SSL_AGAIN; - } - - return st; -} - -int ssl_write( void *conn, const char *buf, int len ) -{ - int st; - - if( !((struct scd*)conn)->established ) - { - ssl_errno = SSL_NOHANDSHAKE; - return -1; - } - - st = SSL_write( ((struct scd*)conn)->ssl, buf, len ); - - ssl_errno = SSL_OK; - if( st <= 0 ) - { - ((struct scd*)conn)->lasterr = SSL_get_error( ((struct scd*)conn)->ssl, st ); - if( ((struct scd*)conn)->lasterr == SSL_ERROR_WANT_READ || ((struct scd*)conn)->lasterr == SSL_ERROR_WANT_WRITE ) - ssl_errno = SSL_AGAIN; - } - - return st; -} - -void ssl_disconnect( void *conn_ ) -{ - struct scd *conn = conn_; - - if( conn->inpa != -1 ) - b_event_remove( conn->inpa ); - - if( conn->established ) - SSL_shutdown( conn->ssl ); - - closesocket( conn->fd ); - - SSL_free( conn->ssl ); - SSL_CTX_free( conn->ssl_ctx ); - g_free( conn ); -} - -int ssl_getfd( void *conn ) -{ - return( ((struct scd*)conn)->fd ); -} - -b_input_condition ssl_getdirection( void *conn ) -{ - return( ((struct scd*)conn)->lasterr == SSL_ERROR_WANT_WRITE ? GAIM_INPUT_WRITE : GAIM_INPUT_READ ); -} diff --git a/protocols/yahoo/libyahoo2.c b/protocols/yahoo/libyahoo2.c index c691f18b..69b63baa 100644 --- a/protocols/yahoo/libyahoo2.c +++ b/protocols/yahoo/libyahoo2.c @@ -89,6 +89,8 @@ char *strchr (), *strrchr (); #define vsnprintf _vsnprintf #endif +#include "base64.h" + #ifdef USE_STRUCT_CALLBACKS struct yahoo_callbacks *yc=NULL; @@ -694,34 +696,10 @@ static void yahoo_packet_dump(unsigned char *data, int len) } } -static char base64digits[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" - "abcdefghijklmnopqrstuvwxyz" - "0123456789._"; -static void to_y64(unsigned char *out, const unsigned char *in, int inlen) /* raw bytes in quasi-big-endian order to base 64 string (NUL-terminated) */ +static void to_y64(unsigned char *out, const unsigned char *in, int inlen) { - for (; inlen >= 3; inlen -= 3) - { - *out++ = base64digits[in[0] >> 2]; - *out++ = base64digits[((in[0]<<4) & 0x30) | (in[1]>>4)]; - *out++ = base64digits[((in[1]<<2) & 0x3c) | (in[2]>>6)]; - *out++ = base64digits[in[2] & 0x3f]; - in += 3; - } - if (inlen > 0) - { - unsigned char fragment; - - *out++ = base64digits[in[0] >> 2]; - fragment = (in[0] << 4) & 0x30; - if (inlen > 1) - fragment |= in[1] >> 4; - *out++ = base64digits[fragment]; - *out++ = (inlen < 2) ? '-' - : base64digits[(in[1] << 2) & 0x3c]; - *out++ = '-'; - } - *out = '\0'; + base64_encode_real(in, inlen, out, "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789._-"); } static void yahoo_add_to_send_queue(struct yahoo_input_data *yid, void *data, int length) diff --git a/protocols/yahoo/yahoo.c b/protocols/yahoo/yahoo.c index 79c0febb..23c6f813 100644 --- a/protocols/yahoo/yahoo.c +++ b/protocols/yahoo/yahoo.c @@ -120,16 +120,16 @@ static char *byahoo_strip( char *in ) return( g_strndup( in, len ) ); } -static void byahoo_login( struct aim_user *user ) +static void byahoo_login( account_t *acc ) { - struct gaim_connection *gc = new_gaim_conn( user ); + struct gaim_connection *gc = new_gaim_conn( acc ); struct byahoo_data *yd = gc->proto_data = g_new0( struct byahoo_data, 1 ); yd->logged_in = FALSE; yd->current_status = YAHOO_STATUS_AVAILABLE; set_login_progress( gc, 1, "Connecting" ); - yd->y2_id = yahoo_init( user->username, user->password ); + yd->y2_id = yahoo_init( acc->user, acc->pass ); yahoo_login( yd->y2_id, yd->current_status ); } @@ -408,7 +408,8 @@ void byahoo_init( ) ret->chat_invite = byahoo_chat_invite; ret->chat_leave = byahoo_chat_leave; ret->chat_open = byahoo_chat_open; - ret->cmp_buddynames = g_strcasecmp; + + ret->handle_cmp = g_strcasecmp; register_protocol(ret); } @@ -424,7 +425,7 @@ static struct gaim_connection *byahoo_get_gc_by_id( int id ) gc = l->data; yd = gc->proto_data; - if( !strcmp(gc->prpl->name, "yahoo") && yd->y2_id == id ) + if( strcmp( gc->acc->prpl->name, "yahoo" ) == 0 && yd->y2_id == id ) return( gc ); } |