2 * These are helping routines for the main module of CNTLM
4 * CNTLM is free software; you can redistribute it and/or modify it under the
5 * terms of the GNU General Public License as published by the Free Software
6 * Foundation; either version 2 of the License, or (at your option) any later
9 * CNTLM is distributed in the hope that it will be useful, but WITHOUT ANY
10 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
11 * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
14 * You should have received a copy of the GNU General Public License along with
15 * this program; if not, write to the Free Software Foundation, Inc., 51 Franklin
16 * St, Fifth Floor, Boston, MA 02110-1301, USA.
18 * Copyright (c) 2007 David Kubicek
22 #include <sys/types.h>
23 #include <sys/socket.h>
33 #include "config/config.h"
38 char hextab
[17] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F', 0};
39 int hexindex
[128] = {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
40 -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
41 -1,-1,-1,-1,-1,-1,-1,-1,-1,0,1,2,3,4,5,6,7,8,9,-1,-1,-1,-1,-1,-1,
42 -1,10,11,12,13,14,15,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
43 -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,10,11,12,13,14,15,-1,-1,-1,-1,-1,
44 -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1};
48 fprintf(stderr
, "Exitting with error. Check daemon logs or run with -v.\n");
53 void croak(const char *msg
, int console
) {
57 syslog(LOG_ERR
, "%s", msg
);
63 * Add a new item to a list. Every plist_t variable must be
64 * initialized to NULL (or pass NULL for "list" when adding
65 * the first item). This is for simplicity's sake (we don't
66 * need any plist_new).
68 * This list type allows to store an arbitrary pointer
69 * associating it with the key.
71 plist_t
plist_add(plist_t list
, unsigned long key
, void *aux
) {
72 plist_t tmp
, t
= list
;
74 tmp
= malloc(sizeof(struct plist_s
));
91 * Delete an item from the list, possibly returning NULL when
92 * the list is empty or nothing was found.
94 plist_t
plist_del(plist_t list
, unsigned long key
) {
95 plist_t ot
= NULL
, t
= list
;
105 plist_t tmp
= t
->next
;
120 * Return true if an item is present in the list.
122 int plist_in(plist_t list
, unsigned long key
) {
135 * For debugging purposes - dump the entire contents
138 void plist_dump(plist_t list
) {
143 printf("List data: %lu => 0x%8p\n", (unsigned long int)t
->key
, t
->aux
);
149 * Return the pointer associated with the key.
151 char *plist_get(plist_t list
, int key
) {
160 return (t
== NULL
? NULL
: t
->aux
);
164 * Scan the list for an open descriptor (socket), possibly
165 * discarding all closed ones on the way. Return the first
168 * Use this method only for lists of descriptors!
170 * In conjunction with plist_add, the list behaves as a FIFO.
171 * This feature is used for rotating cached connections in the
172 * list, so that none is left too long unused (proxy timeout).
174 * Returns key value (descriptor) and if aux != NULL, *aux gets
175 * aux pointer value (which caller must free if != NULL).
178 int plist_pop(plist_t
*list
, void **aux
) {
184 if (list
== NULL
|| *list
== NULL
)
216 * Return the number of items in a list.
218 int plist_count(plist_t list
) {
233 plist_t
plist_free(plist_t list
) {
248 * The same as plist_add. Here we have two other arguments.
249 * They are boolean flags - HLIST_ALLOC means to duplicate a
250 * key/value, HLIST_NOALLOC means to store the pointer directly.
252 * Caller decides this on a by-call basis. Part of the manipulation
253 * routines is a "free". That method always deallocates both the
254 * key and the value. So for static or temporary keys/values,
255 * the caller can instruct us to duplicate the necessary amount
256 * of heap. This mechanism is used to minimize memory-related
257 * bugs throughout the code and tons of free's.
259 hlist_t
hlist_add(hlist_t list
, char *key
, char *value
, hlist_add_t allockey
, hlist_add_t allocvalue
) {
260 hlist_t tmp
, t
= list
;
262 if (key
== NULL
|| value
== NULL
)
265 tmp
= malloc(sizeof(struct hlist_s
));
266 tmp
->key
= (allockey
== HLIST_ALLOC
? strdup(key
) : key
);
267 tmp
->value
= (allocvalue
== HLIST_ALLOC
? strdup(value
) : value
);
283 * Return a duplicate of the list (copy).
285 hlist_t
hlist_dup(hlist_t list
) {
286 hlist_t tmp
= NULL
, t
= list
;
289 tmp
= hlist_add(tmp
, t
->key
, t
->value
, HLIST_ALLOC
, HLIST_ALLOC
);
297 * Remove an item from the list.
299 hlist_t
hlist_del(hlist_t list
, const char *key
) {
300 hlist_t ot
= NULL
, t
= list
;
303 if (!strcasecmp(t
->key
, key
))
310 hlist_t tmp
= t
->next
;
326 * Change the value of a key. If add is true, we store it in the
327 * list if the key is not found. Unlike hlist_add, which offers
328 * pointer storage or memory duplication for both the key and the
329 * value separately, hlist_mod always duplicates.
331 * Used to add a header, which might already be present.
333 hlist_t
hlist_mod(hlist_t list
, char *key
, char *value
, int add
) {
337 if (!strcasecmp(t
->key
, key
))
344 t
->value
= strdup(value
);
346 list
= hlist_add(list
, key
, value
, HLIST_ALLOC
, HLIST_ALLOC
);
353 * Return true is the key is in the list.
355 int hlist_in(hlist_t list
, const char *key
) {
359 if (!strcasecmp(t
->key
, key
))
368 * Return the number of items in a list.
370 int hlist_count(hlist_t list
) {
383 * Return the value for the key.
385 char *hlist_get(hlist_t list
, const char *key
) {
389 if (!strcasecmp(t
->key
, key
))
394 return (t
== NULL
? NULL
: t
->value
);
398 * Test if substr is part of the header's value.
399 * Both case-insensitive.
401 int hlist_subcmp(hlist_t list
, const char *key
, const char *substr
) {
405 lowercase(low
= strdup(substr
));
406 tmp
= hlist_get(list
, key
);
408 lowercase(tmp
= strdup(tmp
));
409 if (strstr(tmp
, low
))
420 * Test if substr is part of the header's value.
421 * Both case-insensitive, checks all headers, not just first one.
423 int hlist_subcmp_all(hlist_t list
, const char *key
, const char *substr
) {
428 lowercase(low
= strdup(substr
));
430 if (!strcasecmp(t
->key
, key
)) {
431 lowercase(tmp
= strdup(t
->value
));
432 if (strstr(tmp
, low
))
445 * Free the list. For more about list memory management,
448 hlist_t
hlist_free(hlist_t list
) {
465 * This is for debugging purposes.
467 void hlist_dump(hlist_t list
) {
472 printf("%-30s => %s\n", t
->key
, t
->value
);
478 * Standard substr. To prevent modification of the source
479 * (terminating \x0), return the result in a new memory.
481 char *substr(const char *src
, int pos
, int len
) {
488 l
= MIN(len
, strlen(src
)-pos
);
493 strlcpy(tmp
, src
+pos
, l
+1);
499 * Allocate memory and initialize a new rr_data_t structure.
501 rr_data_t
new_rr_data(void) {
504 data
= malloc(sizeof(struct rr_data_s
));
511 data
->headers
= NULL
;
514 data
->rel_url
= NULL
;
515 data
->hostname
= NULL
;
519 data
->errmsg
= NULL
; /* for static strings - we don't free, dup, nor copy */
525 * Copy the req/res data.
527 rr_data_t
copy_rr_data(rr_data_t dst
, rr_data_t src
) {
528 if (src
== NULL
|| dst
== NULL
)
533 dst
->code
= src
->code
;
534 dst
->skip_http
= src
->skip_http
;
535 dst
->body_len
= src
->body_len
;
536 dst
->empty
= src
->empty
;
537 dst
->port
= src
->port
;
540 dst
->headers
= hlist_dup(src
->headers
);
542 dst
->method
= strdup(src
->method
);
544 dst
->url
= strdup(src
->url
);
546 dst
->rel_url
= strdup(src
->rel_url
);
548 dst
->hostname
= strdup(src
->hostname
);
550 dst
->http
= strdup(src
->http
);
552 dst
->msg
= strdup(src
->msg
);
553 if (src
->body
&& src
->body_len
> 0) {
554 dst
->body
= new(src
->body_len
);
555 memcpy(dst
->body
, src
->body
, src
->body_len
);
562 * Duplicate the req/res data.
564 rr_data_t
dup_rr_data(rr_data_t data
) {
571 return copy_rr_data(tmp
, data
);
575 * Reset, freeing if neccessary
577 rr_data_t
reset_rr_data(rr_data_t data
) {
588 if (data
->headers
) hlist_free(data
->headers
);
589 if (data
->method
) free(data
->method
);
590 if (data
->url
) free(data
->url
);
591 if (data
->rel_url
) free(data
->rel_url
);
592 if (data
->hostname
) free(data
->hostname
);
593 if (data
->http
) free(data
->http
);
594 if (data
->msg
) free(data
->msg
);
595 if (data
->body
) free(data
->body
);
597 data
->headers
= NULL
;
600 data
->rel_url
= NULL
;
601 data
->hostname
= NULL
;
611 * Free rr_data_t structure. We also take care of freeing
612 * the memory of its members.
614 void free_rr_data(rr_data_t data
) {
618 if (data
->headers
) hlist_free(data
->headers
);
619 if (data
->method
) free(data
->method
);
620 if (data
->url
) free(data
->url
);
621 if (data
->rel_url
) free(data
->rel_url
);
622 if (data
->hostname
) free(data
->hostname
);
623 if (data
->http
) free(data
->http
);
624 if (data
->msg
) free(data
->msg
);
625 if (data
->body
) free(data
->body
);
630 * Cut the whitespace at the end of a string.
632 char *trimr(char *buf
) {
635 for (i
= strlen(buf
)-1; i
>= 0 && isspace(buf
[i
]); --i
);
641 #if config_strdup == 0
643 * Our implementation of non-POSIX strdup()
645 char *strdup(const char *src
) {
653 tmp
= calloc(1, len
);
654 memcpy(tmp
, src
, len
-1);
661 * More intuitive version of strncpy with string termination
664 size_t strlcpy(char *dst
, const char *src
, size_t siz
) {
669 /* Copy as many bytes as will fit */
672 if ((*d
++ = *s
++) == '\0')
677 /* Not enough room in dst, add NUL and traverse rest of src */
680 *d
= '\0'; /* NUL-terminate dst */
684 return (s
- src
- 1); /* count does not include NUL */
688 * More intuitive version os strncat with string termination
691 size_t strlcat(char *dst
, const char *src
, size_t siz
) {
697 /* Find the end of dst and adjust bytes left but don't go past end */
698 while (n
-- != 0 && *d
!= '\0')
705 return(dlen
+ strlen(s
));
716 return (dlen
+ (s
- src
)); /* count does not include NUL */
720 * Shortcut for malloc/memset zero.
722 char *new(size_t size
) {
726 memset(tmp
, 0, size
);
734 char *lowercase(char *str
) {
737 for (i
= 0; i
< strlen(str
); ++i
)
738 str
[i
] = tolower(str
[i
]);
746 char *uppercase(char *str
) {
749 for (i
= 0; i
< strlen(str
); ++i
)
750 str
[i
] = toupper(str
[i
]);
755 int unicode(char **dst
, char *src
) {
764 l
= MIN(64, strlen(src
));
766 for (i
= 0; i
< l
; ++i
)
773 char *urlencode(const char *str
) {
777 tmp
= new(strlen(str
)*3 + 1);
778 for (pos
= 0, i
= 0; i
< strlen(str
); ++i
) {
779 if (isdigit(str
[i
]) || (tolower(str
[i
]) >= 'a' && tolower(str
[i
]) <= 'z') || str
[i
] == '.' || str
[i
] == '-' || str
[i
] == '_' || str
[i
] == '~') {
782 sprintf(tmp
+pos
, "%%%X", (unsigned char)str
[i
]);
790 char *printmem(char *src
, size_t len
, int bitwidth
) {
795 for (i
= 0; i
< len
; ++i
) {
796 tmp
[i
*2] = hextab
[((uint8_t)src
[i
] ^ (uint8_t)(7-bitwidth
)) >> 4];
797 tmp
[i
*2+1] = hextab
[(src
[i
] ^ (uint8_t)(7-bitwidth
)) & 0x0F];
803 char *scanmem(char *src
, int bitwidth
) {
810 bytes
= strlen(src
)/2;
812 for (i
= 0; i
< bytes
; ++i
) {
813 h
= hexindex
[(int)src
[i
*2]];
814 l
= hexindex
[(int)src
[i
*2+1]];
815 if (h
< 0 || l
< 0) {
819 tmp
[i
] = ((h
<< 4) + l
) ^ (uint8_t)(7-bitwidth
);
829 * BASE64 CODE FROM MUTT BEGIN - ORIGINAL COPYRIGHT APPLIES:
831 * Copyright (C) 1996-2001 Michael R. Elkins <me@cs.hmc.edu>
832 * Copyright (C) 1996-2001 Brandon Long <blong@fiction.net>
833 * Copyright (C) 1997-2001 Thomas Roessler <roessler@guug.de>
834 * Copyright (C) 1998-2001 Werner Koch <wk@isil.d.shuttle.de>
835 * Copyright (C) 1999-2001 Brendan Cully <brendan@kublai.com>
836 * Copyright (C) 1999-2001 Tommi Komulainen <Tommi.Komulainen@iki.fi>
837 * Copyright (C) 2000-2001 Edmund Grimley Evans <edmundo@rano.org>
842 #define base64val(c) index64[(unsigned int)(c)]
845 'A','B','C','D','E','F','G','H','I','J','K','L','M','N',
846 'O','P','Q','R','S','T','U','V','W','X','Y','Z','a','b',
847 'c','d','e','f','g','h','i','j','k','l','m','n','o','p',
848 'q','r','s','t','u','v','w','x','y','z','0','1','2','3',
849 '4','5','6','7','8','9','+','/'
853 -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
854 -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
855 -1,-1,-1,-1,-1,62,-1,-1,-1,63,52,53,54,55,56,57,58,59,60,
856 61,-1,-1,-1,-1,-1,-1,-1,0,1,2,3,4,5,6,7,8,9,10,11,12,13,
857 14,15,16,17,18,19,20,21,22,23,24,25,-1,-1,-1,-1,-1,-1,26,
858 27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,
859 46,47,48,49,50,51,-1,-1,-1,-1,-1
862 void to_base64(unsigned char *out
, const unsigned char *in
, size_t len
, size_t olen
) {
863 while (len
>= 3 && olen
> 10) {
864 *out
++ = base64
[in
[0] >> 2];
865 *out
++ = base64
[((in
[0] << 4) & 0x30) | (in
[1] >> 4)];
866 *out
++ = base64
[((in
[1] << 2) & 0x3c) | (in
[2] >> 6)];
867 *out
++ = base64
[in
[2] & 0x3f];
873 /* clean up remainder */
874 if (len
> 0 && olen
> 4) {
875 unsigned char fragment
;
877 *out
++ = base64
[in
[0] >> 2];
878 fragment
= (in
[0] << 4) & 0x30;
880 fragment
|= in
[1] >> 4;
881 *out
++ = base64
[fragment
];
882 *out
++ = (len
< 2) ? '=' : base64
[(in
[1] << 2) & 0x3c];
888 /* Convert '\0'-terminated base 64 string to raw bytes.
889 * Returns length of returned buffer, or -1 on error */
890 int from_base64(char *out
, const char *in
)
893 register unsigned char digit1
, digit2
, digit3
, digit4
;
897 if (digit1
> 127 || base64val (digit1
) == BAD
)
901 if (digit2
> 127 || base64val (digit2
) == BAD
)
905 if (digit3
> 127 || ((digit3
!= '=') && (base64val (digit3
) == BAD
)))
909 if (digit4
> 127 || ((digit4
!= '=') && (base64val (digit4
) == BAD
)))
914 /* digits are already sanity-checked */
915 *out
++ = (base64val(digit1
) << 2) | (base64val(digit2
) >> 4);
918 *out
++ = ((base64val(digit2
) << 4) & 0xf0) | (base64val(digit3
) >> 2);
921 *out
++ = ((base64val(digit3
) << 6) & 0xc0) | base64val(digit4
);
925 } while (*in
&& digit4
!= '=');