PageRenderTime 53ms CodeModel.GetById 19ms RepoModel.GetById 0ms app.codeStats 0ms

/amanda/tags/amanda261p2/device-src/s3-util.c

#
C | 171 lines | 115 code | 23 blank | 33 comment | 12 complexity | 0bb5ff5054494ec93f85834f884da0af MD5 | raw file
  1. /*
  2. * Copyright (c) 2005-2008 Zmanda Inc. All Rights Reserved.
  3. *
  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.
  7. *
  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.
  12. *
  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.
  16. *
  17. * Contact information: Zmanda Inc., 465 S Mathlida Ave, Suite 300
  18. * Sunnyvale, CA 94086, USA, or: http://www.zmanda.com
  19. */
  20. #ifdef HAVE_CONFIG_H
  21. /* use a relative path here to avoid conflicting with Perl's config.h. */
  22. #include "../config/config.h"
  23. #endif
  24. #ifdef HAVE_REGEX_H
  25. #include <sys/types.h>
  26. #include <regex.h>
  27. #endif
  28. #ifdef HAVE_AMANDA_H
  29. #include "amanda.h"
  30. #endif
  31. #include <glib.h>
  32. #include <openssl/md5.h>
  33. #include <openssl/bio.h>
  34. #include <openssl/evp.h>
  35. #include <openssl/bn.h>
  36. #include "s3-util.h"
  37. #ifdef HAVE_REGEX_H
  38. int
  39. s3_regexec_wrap(regex_t *regex,
  40. const char *str,
  41. size_t nmatch,
  42. regmatch_t pmatch[],
  43. int eflags)
  44. {
  45. char *message;
  46. int size;
  47. int reg_result;
  48. reg_result = regexec(regex, str, nmatch, pmatch, eflags);
  49. if (reg_result != 0 && reg_result != REG_NOMATCH) {
  50. size = regerror(reg_result, regex, NULL, 0);
  51. message = g_malloc(size);
  52. regerror(reg_result, regex, message, size);
  53. /* this is programmer error (bad regexp), so just log
  54. * and abort(). There's no good way to signal a
  55. * permanaent error from interpret_response. */
  56. g_critical(_("Regex error: %s"), message);
  57. }
  58. return reg_result;
  59. }
  60. #else
  61. int
  62. s3_regexec_wrap(regex_t *regex,
  63. const char *str,
  64. size_t nmatch,
  65. regmatch_t pmatch[],
  66. int eflags)
  67. {
  68. GMatchInfo *match_info;
  69. int ret = REG_NOERROR;
  70. guint i;
  71. g_assert(regex && *regex);
  72. g_regex_match(*regex, str, eflags, &match_info);
  73. if (g_match_info_matches(match_info)) {
  74. g_assert(g_match_info_get_match_count(match_info) <= (glong) nmatch);
  75. for (i = 0; i < nmatch; i++) {
  76. pmatch[i].rm_eo = pmatch[i].rm_so = -1;
  77. g_match_info_fetch_pos(match_info, i, &pmatch[i].rm_so, &pmatch[i].rm_eo);
  78. }
  79. } else {
  80. ret = REG_NOMATCH;
  81. }
  82. g_match_info_free(match_info);
  83. return ret;
  84. }
  85. #endif
  86. #ifndef HAVE_AMANDA_H
  87. char*
  88. find_regex_substring(const char* base_string, const regmatch_t match)
  89. {
  90. g_assert(match.rm_eo >= match.rm_so);
  91. return g_strndup(base_string+match.rm_so, match.rm_eo - match.rm_so);
  92. }
  93. #endif
  94. gchar*
  95. s3_base64_encode(const GByteArray *to_enc) {
  96. BIO *bio_b64 = NULL, *bio_buff = NULL;
  97. long bio_b64_len;
  98. char *bio_b64_data = NULL, *ret = NULL;
  99. if (!to_enc) return NULL;
  100. /* Initialize base64 encoding filter */
  101. bio_b64 = BIO_new(BIO_f_base64());
  102. g_assert(bio_b64);
  103. BIO_set_flags(bio_b64, BIO_FLAGS_BASE64_NO_NL);
  104. /* Initialize memory buffer for the base64 encoding */
  105. bio_buff = BIO_new(BIO_s_mem());
  106. g_assert(bio_buff);
  107. bio_buff = BIO_push(bio_b64, bio_buff);
  108. /* Write the MD5 hash into the buffer to encode it in base64 */
  109. BIO_write(bio_buff, to_enc->data, to_enc->len);
  110. /* BIO_flush is a macro and GCC 4.1.2 complains without this cast*/
  111. (void) BIO_flush(bio_buff);
  112. /* Pull out the base64 encoding of the MD5 hash */
  113. bio_b64_len = BIO_get_mem_data(bio_buff, &bio_b64_data);
  114. g_assert(bio_b64_data);
  115. ret = g_strndup(bio_b64_data, bio_b64_len);
  116. /* If bio_b64 is freed separately, freeing bio_buff will
  117. * invalidly free memory and potentially segfault.
  118. */
  119. BIO_free_all(bio_buff);
  120. return ret;
  121. }
  122. gchar*
  123. s3_hex_encode(const GByteArray *to_enc) {
  124. guint i;
  125. gchar *ret = NULL, table[] = "0123456789abcdef";
  126. if (!to_enc) return NULL;
  127. ret = g_new(gchar, to_enc->len*2 + 1);
  128. for (i = 0; i < to_enc->len; i++) {
  129. /* most significant 4 bits */
  130. ret[i*2] = table[to_enc->data[i] >> 4];
  131. /* least significant 4 bits */
  132. ret[i*2 + 1] = table[to_enc->data[i] & 0xf];
  133. }
  134. ret[to_enc->len*2] = '\0';
  135. return ret;
  136. }
  137. GByteArray*
  138. s3_compute_md5_hash(const GByteArray *to_hash) {
  139. MD5_CTX md5_ctx;
  140. GByteArray *ret;
  141. if (!to_hash) return NULL;
  142. ret = g_byte_array_sized_new(S3_MD5_HASH_BYTE_LEN);
  143. g_byte_array_set_size(ret, S3_MD5_HASH_BYTE_LEN);
  144. MD5_Init(&md5_ctx);
  145. MD5_Update(&md5_ctx, to_hash->data, to_hash->len);
  146. MD5_Final(ret->data, &md5_ctx);
  147. return ret;
  148. }