2 * Copyright (c) 2005-2008 Zmanda Inc. All Rights Reserved.
4 * This library is free software; you can redistribute it and/or modify it
5 * under the terms of the GNU Lesser General Public License version 2.1 as
6 * published by the Free Software Foundation.
8 * This library is distributed in the hope that it will be useful, but
9 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
10 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
11 * License for more details.
13 * You should have received a copy of the GNU Lesser General Public License
14 * along with this library; if not, write to the Free Software Foundation,
15 * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
17 * Contact information: Zmanda Inc., 465 S Mathlida Ave, Suite 300
18 * Sunnyvale, CA 94086, USA, or: http://www.zmanda.com
23 /* use a relative path here to avoid conflicting with Perl's config.h. */
24 #include "../config/config.h"
27 #include <sys/types.h>
35 #include <openssl/md5.h>
36 #include <openssl/bio.h>
37 #include <openssl/evp.h>
38 #include <openssl/bn.h>
43 s3_regexec_wrap(regex_t *regex,
53 reg_result = regexec(regex, str, nmatch, pmatch, eflags);
54 if (reg_result != 0 && reg_result != REG_NOMATCH) {
55 size = regerror(reg_result, regex, NULL, 0);
56 message = g_malloc(size);
57 regerror(reg_result, regex, message, size);
59 /* this is programmer error (bad regexp), so just log
60 * and abort(). There's no good way to signal a
61 * permanaent error from interpret_response. */
62 g_critical(_("Regex error: %s"), message);
70 s3_regexec_wrap(regex_t *regex,
76 GMatchInfo *match_info;
77 int ret = REG_NOERROR;
80 g_assert(regex && *regex);
81 g_regex_match(*regex, str, eflags, &match_info);
82 if (g_match_info_matches(match_info)) {
83 g_assert(g_match_info_get_match_count(match_info) <= (glong) nmatch);
84 for (i = 0; i < nmatch; i++) {
85 pmatch[i].rm_eo = pmatch[i].rm_so = -1;
86 g_match_info_fetch_pos(match_info, i, &pmatch[i].rm_so, &pmatch[i].rm_eo);
91 g_match_info_free(match_info);
98 find_regex_substring(const char* base_string, const regmatch_t match)
100 g_assert(match.rm_eo >= match.rm_so);
101 return g_strndup(base_string+match.rm_so, match.rm_eo - match.rm_so);
106 s3_base64_encode(const GByteArray *to_enc) {
107 BIO *bio_b64 = NULL, *bio_buff = NULL;
109 char *bio_b64_data = NULL, *ret = NULL;
110 if (!to_enc) return NULL;
112 /* Initialize base64 encoding filter */
113 bio_b64 = BIO_new(BIO_f_base64());
115 BIO_set_flags(bio_b64, BIO_FLAGS_BASE64_NO_NL);
117 /* Initialize memory buffer for the base64 encoding */
118 bio_buff = BIO_new(BIO_s_mem());
120 bio_buff = BIO_push(bio_b64, bio_buff);
122 /* Write the MD5 hash into the buffer to encode it in base64 */
123 BIO_write(bio_buff, to_enc->data, to_enc->len);
124 /* BIO_flush is a macro and GCC 4.1.2 complains without this cast*/
125 (void) BIO_flush(bio_buff);
127 /* Pull out the base64 encoding of the MD5 hash */
128 bio_b64_len = BIO_get_mem_data(bio_buff, &bio_b64_data);
129 g_assert(bio_b64_data);
130 ret = g_strndup(bio_b64_data, bio_b64_len);
132 /* If bio_b64 is freed separately, freeing bio_buff will
133 * invalidly free memory and potentially segfault.
135 BIO_free_all(bio_buff);
140 s3_hex_encode(const GByteArray *to_enc) {
142 gchar *ret = NULL, table[] = "0123456789abcdef";
143 if (!to_enc) return NULL;
145 ret = g_new(gchar, to_enc->len*2 + 1);
146 for (i = 0; i < to_enc->len; i++) {
147 /* most significant 4 bits */
148 ret[i*2] = table[to_enc->data[i] >> 4];
149 /* least significant 4 bits */
150 ret[i*2 + 1] = table[to_enc->data[i] & 0xf];
152 ret[to_enc->len*2] = '\0';
158 s3_compute_md5_hash(const GByteArray *to_hash) {
161 if (!to_hash) return NULL;
163 ret = g_byte_array_sized_new(S3_MD5_HASH_BYTE_LEN);
164 g_byte_array_set_size(ret, S3_MD5_HASH_BYTE_LEN);
167 MD5_Update(&md5_ctx, to_hash->data, to_hash->len);
168 MD5_Final(ret->data, &md5_ctx);