aboutsummaryrefslogtreecommitdiffstats
path: root/lib/url.c
blob: 9e330f8c0a2bedef4061f8af20f89064f3945955 (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
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
  /********************************************************************\
  * BitlBee -- An IRC to other IM-networks gateway                     *
  *                                                                    *
  * Copyright 2001-2005 Wilmer van der Gaast and others                *
  \********************************************************************/

/* URL/mirror stuff - Stolen from Axel                                  */

/*
  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 "url.h"

/* Convert an URL to a url_t structure */
int url_set( url_t *url, const char *set_url )
{
	char s[MAX_STRING+1];
	char *i;
	
	memset( url, 0, sizeof( url_t ) );
	memset( s, 0, sizeof( s ) );
	
	/* protocol:// */
	if( ( i = strstr( set_url, "://" ) ) == NULL )
	{
		url->proto = PROTO_DEFAULT;
		strncpy( s, set_url, MAX_STRING );
	}
	else
	{
		if( g_strncasecmp( set_url, "http", i - set_url ) == 0 )
			url->proto = PROTO_HTTP;
		else if( g_strncasecmp( set_url, "https", i - set_url ) == 0 )
			url->proto = PROTO_HTTPS;
		else if( g_strncasecmp( set_url, "socks4", i - set_url ) == 0 )
			url->proto = PROTO_SOCKS4;
		else if( g_strncasecmp( set_url, "socks5", i - set_url ) == 0 )
			url->proto = PROTO_SOCKS5;
		else
			return 0;
		
		strncpy( s, i + 3, MAX_STRING );
	}
	
	/* Split */
	if( ( i = strchr( s, '/' ) ) == NULL )
	{
		strcpy( url->file, "/" );
	}
	else
	{
		strncpy( url->file, i, MAX_STRING );
		*i = 0;
	}
	strncpy( url->host, s, MAX_STRING );
	
	/* Check for username in host field */
	if( strrchr( url->host, '@' ) != NULL )
	{
		strncpy( url->user, url->host, MAX_STRING );
		i = strrchr( url->user, '@' );
		*i = 0;
		strcpy( url->host, i + 1 );
		*url->pass = 0;
	}
	/* If not: Fill in defaults */
	else
	{
		*url->user = *url->pass = 0;
	}
	
	/* Password? */
	if( ( i = strchr( url->user, ':' ) ) != NULL )
	{
		*i = 0;
		strcpy( url->pass, i + 1 );
	}
	/* Port number? */
	if( ( i = strchr( url->host, ':' ) ) != NULL )
	{
		*i = 0;
		sscanf( i + 1, "%d", &url->port );
	}
	else
	{
		if( url->proto == PROTO_HTTP )
			url->port = 80;
		else if( url->proto == PROTO_HTTPS )
			url->port = 443;
		else if( url->proto == PROTO_SOCKS4 || url->proto == PROTO_SOCKS5 )
			url->port = 1080;
	}
	
	return( url->port > 0 );
}
s a char**. Since the encode/decode functions allocate memory for the string, make sure the char** points at a NULL-pointer (or at least to something you already free()d), or you'll leak memory. And of course, don't forget to free() the result when you don't need it anymore. Both functions return the number of bytes in the result string. Note that if you use the pad_to argument, you will need zero-termi- nation to find back the original string length after decryption. So it shouldn't be used if your string contains \0s by itself! */ int arc_encode(char *clear, int clear_len, unsigned char **crypt, char *password, int pad_to) { struct arc_state *st; unsigned char *key; char *padded = NULL; int key_len, i, padded_len; key_len = strlen(password) + ARC_IV_LEN; if (clear_len <= 0) { clear_len = strlen(clear); } /* Pad the string to the closest multiple of pad_to. This makes it impossible to see the exact length of the password. */ if (pad_to > 0 && (clear_len % pad_to) > 0) { padded_len = clear_len + pad_to - (clear_len % pad_to); padded = g_malloc(padded_len); memcpy(padded, clear, clear_len); /* First a \0 and then random data, so we don't have to do anything special when decrypting. */ padded[clear_len] = 0; random_bytes((unsigned char *) padded + clear_len + 1, padded_len - clear_len - 1); clear = padded; clear_len = padded_len; } /* Prepare buffers and the key + IV */ *crypt = g_malloc(clear_len + ARC_IV_LEN); key = g_malloc(key_len); strcpy((char *) key, password); /* Add the salt. Save it for later (when decrypting) and, of course, add it to the encryption key. */ random_bytes(crypt[0], ARC_IV_LEN); memcpy(key + key_len - ARC_IV_LEN, crypt[0], ARC_IV_LEN); /* Generate the initial S[] from the IVed key. */ st = arc_keymaker(key, key_len, ARC_CYCLES); g_free(key); for (i = 0; i < clear_len; i++) { crypt[0][i + ARC_IV_LEN] = clear[i] ^ arc_getbyte(st); } g_free(st); g_free(padded); return clear_len + ARC_IV_LEN; } int arc_decode(unsigned char *crypt, int crypt_len, char **clear, const char *password) { struct arc_state *st; unsigned char *key; int key_len, clear_len, i; key_len = strlen(password) + ARC_IV_LEN; clear_len = crypt_len - ARC_IV_LEN; if (clear_len < 0) { *clear = g_strdup(""); return -1; } /* Prepare buffers and the key + IV */ *clear = g_malloc(clear_len + 1); key = g_malloc(key_len); strcpy((char *) key, password); for (i = 0; i < ARC_IV_LEN; i++) { key[key_len - ARC_IV_LEN + i] = crypt[i]; } /* Generate the initial S[] from the IVed key. */ st = arc_keymaker(key, key_len, ARC_CYCLES); g_free(key); for (i = 0; i < clear_len; i++) { clear[0][i] = crypt[i + ARC_IV_LEN] ^ arc_getbyte(st); } clear[0][i] = 0; /* Nice to have for plaintexts. */ g_free(st); return clear_len; }