aboutsummaryrefslogtreecommitdiffstats
path: root/lib/misc.h
blob: 5376cd22187bcd879884158034f87e1df226246e (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
  /********************************************************************\
  * BitlBee -- An IRC to other IM-networks gateway                     *
  *                                                                    *
  * Copyright 2002-2004 Wilmer van der Gaast and others                *
  \********************************************************************/

/* Misc. functions                                                      */

/*
  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
*/

#ifndef _MISC_H
#define _MISC_H

#include <gmodule.h>
#include <time.h>

struct ns_srv_reply
{
	int prio;
	int weight;
	int port;
	char name[];
};

G_MODULE_EXPORT void strip_linefeed( gchar *text );
G_MODULE_EXPORT char *add_cr( char *text );
G_MODULE_EXPORT char *strip_newlines(char *source);

G_MODULE_EXPORT time_t get_time( int year, int month, int day, int hour, int min, int sec );
double gettime( void );

G_MODULE_EXPORT void strip_html( char *msg );
G_MODULE_EXPORT char *escape_html( const char *html );
G_MODULE_EXPORT void http_decode( char *s );
G_MODULE_EXPORT void http_encode( char *s );

G_MODULE_EXPORT char *ipv6_wrap( char *src );
G_MODULE_EXPORT char *ipv6_unwrap( char *src );

G_MODULE_EXPORT signed int do_iconv( char *from_cs, char *to_cs, char *src, char *dst, size_t size, size_t maxbuf );

G_MODULE_EXPORT void random_bytes( unsigned char *buf, int count );

G_MODULE_EXPORT int is_bool( char *value );
G_MODULE_EXPORT int bool2int( char *value );

G_MODULE_EXPORT struct ns_srv_reply *srv_lookup( char *service, char *protocol, char *domain );

G_MODULE_EXPORT char *word_wrap( char *msg, int line_len );

G_MODULE_EXPORT gboolean ssl_sockerr_again( void *ssl );

G_MODULE_EXPORT int md5_verify_password( char *password, char *hash );

#endif
s="k">static void ssl_connected(gpointer, gint, GaimInputCondition); void sspi_global_init(void) { /* FIXME */ } void sspi_global_deinit(void) { /* FIXME */ } void *ssl_connect(char *host, int port, ssl_input_function func, gpointer data) { struct scd *conn = g_new0(struct scd, 1); conn->fd = proxy_connect(host, port, ssl_connected, conn); sock_make_nonblocking(conn->fd); conn->func = func; conn->data = data; conn->host = g_strdup(host); if (conn->fd < 0) { g_free(conn); return NULL; } if (!initialized) { sspi_global_init(); initialized = TRUE; atexit(sspi_global_deinit); } return conn; } static void ssl_connected(gpointer _conn, gint fd, GaimInputCondition cond) { struct scd *conn = _conn; SCHANNEL_CRED ssl_cred; TimeStamp timestamp; SecBuffer ibuf[2],obuf[1]; SecBufferDesc ibufs,obufs; ULONG req = ISC_REQ_REPLAY_DETECT | ISC_REQ_SEQUENCE_DETECT | ISC_REQ_CONFIDENTIALITY | ISC_REQ_USE_SESSION_KEY | ISC_REQ_ALLOCATE_MEMORY | ISC_REQ_STREAM | ISC_REQ_EXTENDED_ERROR | ISC_REQ_MANUAL_CRED_VALIDATION; ULONG a; gsize size = 0; gchar *data = NULL; memset(&ssl_cred, 0, sizeof(SCHANNEL_CRED)); ssl_cred.dwVersion = SCHANNEL_CRED_VERSION; ssl_cred.grbitEnabledProtocols = SP_PROT_SSL3_CLIENT; SECURITY_STATUS st = AcquireCredentialsHandle(NULL, UNISP_NAME, SECPKG_CRED_OUTBOUND, NULL, &ssl_cred, NULL, NULL, &conn->cred, &timestamp); if (st != SEC_E_OK) { conn->func(conn->data, NULL, cond); return; } do { /* initialize buffers */ ibuf[0].cbBuffer = size; ibuf[0].pvBuffer = data; ibuf[1].cbBuffer = 0; ibuf[1].pvBuffer = NULL; obuf[0].cbBuffer = 0; obuf[0].pvBuffer = NULL; ibuf[0].BufferType = obuf[0].BufferType = SECBUFFER_TOKEN; ibuf[1].BufferType = SECBUFFER_EMPTY; /* initialize buffer descriptors */ ibufs.ulVersion = obufs.ulVersion = SECBUFFER_VERSION; ibufs.cBuffers = 2; obufs.cBuffers = 1; ibufs.pBuffers = ibuf; obufs.pBuffers = obuf; st = InitializeSecurityContext(&conn->cred, size?&conn->context:NULL, conn->host, req, 0, SECURITY_NETWORK_DREP, size?&ibufs:NULL, 0, &conn->context, &obufs, &a, &timestamp); if (obuf[0].pvBuffer && obuf[0].cbBuffer) { /* FIXME: Check return value */ send(conn->fd, obuf[0].pvBuffer, obuf[0].cbBuffer, 0); } switch (st) { case SEC_I_INCOMPLETE_CREDENTIALS: break; case SEC_I_CONTINUE_NEEDED: break; case SEC_E_INCOMPLETE_MESSAGE: break; case SEC_E_OK: break; } QueryContextAttributes(&conn->context, SECPKG_ATTR_STREAM_SIZES, &conn->sizes); } while (1); conn->func(conn->data, conn, cond); } int ssl_read(void *conn, char *retdata, int len) { struct scd *scd = conn; SecBufferDesc msg; SecBuffer buf[4]; int ret = -1, i; char *data = g_malloc(scd->sizes.cbHeader + scd->sizes.cbMaximumMessage + scd->sizes.cbTrailer); /* FIXME: Try to read some data */ msg.ulVersion = SECBUFFER_VERSION; msg.cBuffers = 4; msg.pBuffers = buf; buf[0].BufferType = SECBUFFER_DATA; buf[0].cbBuffer = len; buf[0].pvBuffer = data; buf[1].BufferType = SECBUFFER_EMPTY; buf[2].BufferType = SECBUFFER_EMPTY; buf[3].BufferType = SECBUFFER_EMPTY; SECURITY_STATUS st = DecryptMessage(&scd->context, &msg, 0, NULL); if (st != SEC_E_OK) { /* FIXME */ return -1; } for (i = 0; i < 4; i++) { if (buf[i].BufferType == SECBUFFER_DATA) { memcpy(retdata, buf[i].pvBuffer, len); ret = len; } } g_free(data); return -1; } int ssl_write(void *conn, const char *userdata, int len) { struct scd *scd = conn; SecBuffer buf[4]; SecBufferDesc msg; char *data; int ret; msg.ulVersion = SECBUFFER_VERSION; msg.cBuffers = 4; msg.pBuffers = buf; data = g_malloc(scd->sizes.cbHeader + scd->sizes.cbMaximumMessage + scd->sizes.cbTrailer); memcpy(data + scd->sizes.cbHeader, userdata, len); buf[0].BufferType = SECBUFFER_STREAM_HEADER; buf[0].cbBuffer = scd->sizes.cbHeader; buf[0].pvBuffer = data; buf[1].BufferType = SECBUFFER_DATA; buf[1].cbBuffer = len; buf[1].pvBuffer = data + scd->sizes.cbHeader; buf[2].BufferType = SECBUFFER_STREAM_TRAILER; buf[2].cbBuffer = scd->sizes.cbTrailer; buf[2].pvBuffer = data + scd->sizes.cbHeader + len; buf[3].BufferType = SECBUFFER_EMPTY; SECURITY_STATUS st = EncryptMessage(&scd->context, 0, &msg, 0); ret = send(scd->fd, data, buf[0].cbBuffer + buf[1].cbBuffer + buf[2].cbBuffer, 0); g_free(data); return ret; } void ssl_disconnect(void *conn) { struct scd *scd = conn; SecBufferDesc msg; SecBuffer buf; DWORD dw; dw = SCHANNEL_SHUTDOWN; buf.cbBuffer = sizeof(dw); buf.BufferType = SECBUFFER_TOKEN; buf.pvBuffer = &dw; msg.ulVersion = SECBUFFER_VERSION; msg.cBuffers = 1; msg.pBuffers = &buf; SECURITY_STATUS st = ApplyControlToken(&scd->context, &msg); if (st != SEC_E_OK) { /* FIXME */ } /* FIXME: call InitializeSecurityContext(Schannel), passing * in empty buffers*/ DeleteSecurityContext(&scd->context); FreeCredentialsHandle(&scd->cred); closesocket(scd->fd); g_free(scd->host); g_free(scd); } int ssl_getfd(void *conn) { return ((struct scd*)conn)->fd; } GaimInputCondition ssl_getdirection( void *conn ) { return B_EV_IO_WRITE; /* FIXME: or B_EV_IO_READ */ }