Duplicate argv data before poptFreeContext().
[rsync.git] / checksum.c
index 4fa8faa073a655339c24d01310858a986c2e57ca..c6007f36895bba698667377b1f787ea1d1444a95 100644 (file)
@@ -57,6 +57,9 @@ struct name_num_item valid_checksums_items[] = {
 #endif
        { CSUM_MD5, NNI_BUILTIN|NNI_EVP, "md5", NULL },
        { CSUM_MD4, NNI_BUILTIN|NNI_EVP, "md4", NULL },
+#ifdef SHA_DIGEST_LENGTH
+       { CSUM_SHA1, NNI_EVP, "sha1", NULL },
+#endif
        { CSUM_NONE, 0, "none", NULL },
        { 0, 0, NULL, NULL }
 };
@@ -66,6 +69,15 @@ struct name_num_obj valid_checksums = {
 };
 
 struct name_num_item valid_auth_checksums_items[] = {
+#ifdef SHA512_DIGEST_LENGTH
+       { CSUM_SHA512, NNI_EVP, "sha512", NULL },
+#endif
+#ifdef SHA256_DIGEST_LENGTH
+       { CSUM_SHA256, NNI_EVP, "sha256", NULL },
+#endif
+#ifdef SHA_DIGEST_LENGTH
+       { CSUM_SHA1, NNI_EVP, "sha1", NULL },
+#endif
        { CSUM_MD5, NNI_BUILTIN|NNI_EVP, "md5", NULL },
        { CSUM_MD4, NNI_BUILTIN|NNI_EVP, "md4", NULL },
        { 0, 0, NULL, NULL }
@@ -82,15 +94,16 @@ struct name_num_item implied_checksum_md5 =
     { CSUM_MD5, NNI_BUILTIN, "md5", NULL };
 
 struct name_num_item *xfer_sum_nni; /* used for the transfer checksum2 computations */
-const EVP_MD *xfer_sum_evp_md;
 int xfer_sum_len;
 struct name_num_item *file_sum_nni; /* used for the pre-transfer --checksum computations */
-const EVP_MD *file_sum_evp_md;
-int file_sum_len;
+int file_sum_len, file_sum_extra_cnt;
 
 #ifdef USE_OPENSSL
+const EVP_MD *xfer_sum_evp_md;
+const EVP_MD *file_sum_evp_md;
 EVP_MD_CTX *ctx_evp = NULL;
 #endif
+
 static int initialized_choices = 0;
 
 struct name_num_item *parse_csum_name(const char *name, int len)
@@ -129,9 +142,9 @@ struct name_num_item *parse_csum_name(const char *name, int len)
        return nni;
 }
 
+#ifdef USE_OPENSSL
 static const EVP_MD *csum_evp_md(struct name_num_item *nni)
 {
-#ifdef USE_OPENSSL
        const EVP_MD *emd;
        if (!(nni->flags & NNI_EVP))
                return NULL;
@@ -141,7 +154,7 @@ static const EVP_MD *csum_evp_md(struct name_num_item *nni)
                emd = NULL;
        else
 #endif
-               emd = EVP_get_digestbyname(nni->name);                                               
+               emd = EVP_get_digestbyname(nni->name);
        if (emd && !(nni->flags & NNI_EVP_OK)) { /* Make sure it works before we advertise it */
                if (!ctx_evp && !(ctx_evp = EVP_MD_CTX_create()))
                        out_of_memory("csum_evp_md");
@@ -155,10 +168,8 @@ static const EVP_MD *csum_evp_md(struct name_num_item *nni)
        if (!emd)
                nni->flags &= ~NNI_EVP;
        return emd;
-#else
-       return NULL;
-#endif
 }
+#endif
 
 void parse_checksum_choice(int final_call)
 {
@@ -176,8 +187,12 @@ void parse_checksum_choice(int final_call)
        }
        xfer_sum_len = csum_len_for_type(xfer_sum_nni->num, 0);
        file_sum_len = csum_len_for_type(file_sum_nni->num, 0);
+#ifdef USE_OPENSSL
        xfer_sum_evp_md = csum_evp_md(xfer_sum_nni);
        file_sum_evp_md = csum_evp_md(file_sum_nni);
+#endif
+
+       file_sum_extra_cnt = (file_sum_len + EXTRA_LEN - 1) / EXTRA_LEN;
 
        if (xfer_sum_nni->num == CSUM_NONE)
                whole_file = 1;
@@ -211,6 +226,18 @@ int csum_len_for_type(int cst, BOOL flist_csum)
                return MD4_DIGEST_LEN;
          case CSUM_MD5:
                return MD5_DIGEST_LEN;
+#ifdef SHA_DIGEST_LENGTH
+         case CSUM_SHA1:
+               return SHA_DIGEST_LENGTH;
+#endif
+#ifdef SHA256_DIGEST_LENGTH
+         case CSUM_SHA256:
+               return SHA256_DIGEST_LENGTH;
+#endif
+#ifdef SHA512_DIGEST_LENGTH
+         case CSUM_SHA512:
+               return SHA512_DIGEST_LENGTH;
+#endif
          case CSUM_XXH64:
          case CSUM_XXH3_64:
                return 64/8;
@@ -236,6 +263,9 @@ int canonical_checksum(int csum_type)
                break;
          case CSUM_MD4:
          case CSUM_MD5:
+         case CSUM_SHA1:
+         case CSUM_SHA256:
+         case CSUM_SHA512:
                return -1;
          case CSUM_XXH64:
          case CSUM_XXH3_64:
@@ -516,9 +546,15 @@ static XXH64_state_t* xxh64_state;
 static XXH3_state_t* xxh3_state;
 #endif
 static struct name_num_item *cur_sum_nni;
-static const EVP_MD *cur_sum_evp_md;
 int cur_sum_len;
 
+#ifdef USE_OPENSSL
+static const EVP_MD *cur_sum_evp_md;
+#endif
+
+/* Initialize a hash digest accumulator.  Data is supplied via
+ * sum_update() and the resulting binary digest is retrieved via
+ * sum_end().  This only supports one active sum at a time. */
 int sum_init(struct name_num_item *nni, int seed)
 {
        char s[4];
@@ -527,7 +563,9 @@ int sum_init(struct name_num_item *nni, int seed)
                nni = parse_csum_name(NULL, 0);
        cur_sum_nni = nni;
        cur_sum_len = csum_len_for_type(nni->num, 0);
+#ifdef USE_OPENSSL
        cur_sum_evp_md = csum_evp_md(nni);
+#endif
 
 #ifdef USE_OPENSSL
        if (cur_sum_evp_md) {
@@ -580,14 +618,7 @@ int sum_init(struct name_num_item *nni, int seed)
        return cur_sum_len;
 }
 
-/**
- * Feed data into an MD4 accumulator, md.  The results may be
- * retrieved using sum_end().  md is used for different purposes at
- * different points during execution.
- *
- * @todo Perhaps get rid of md and just pass in the address each time.
- * Very slightly clearer and slower.
- **/
+/* Feed data into a hash digest accumulator. */
 void sum_update(const char *p, int32 len)
 {
 #ifdef USE_OPENSSL
@@ -749,11 +780,17 @@ static void verify_digest(struct name_num_item *nni, BOOL check_auth_list)
 
 void init_checksum_choices()
 {
+#if defined SUPPORT_XXH3 || defined USE_OPENSSL
        struct name_num_item *nni;
+#endif
 
        if (initialized_choices)
                return;
 
+#if defined USE_OPENSSL && OPENSSL_VERSION_NUMBER < 0x10100000L
+       OpenSSL_add_all_algorithms();
+#endif
+
 #if defined SUPPORT_XXH3 || defined USE_OPENSSL
        for (nni = valid_checksums.list; nni->name; nni++)
                verify_digest(nni, True);