Script 'mail_helper' called by obssrc
Hello community,

here is the log from the commit of package libiscsi for openSUSE:Factory 
checked in at 2024-06-09 20:19:00
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/libiscsi (Old)
 and      /work/SRC/openSUSE:Factory/.libiscsi.new.19518 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "libiscsi"

Sun Jun  9 20:19:00 2024 rev:25 rq:1179242 version:1.20.0+git.20240530

Changes:
--------
--- /work/SRC/openSUSE:Factory/libiscsi/libiscsi.changes        2024-03-01 
23:34:58.912105856 +0100
+++ /work/SRC/openSUSE:Factory/.libiscsi.new.19518/libiscsi.changes     
2024-06-09 20:19:19.643630576 +0200
@@ -1,0 +2,13 @@
+Fri Jun  7 13:49:23 UTC 2024 - Martin Pluskal <mplus...@suse.com>
+
+- Update to version 1.20.0+git.20240530:
+  * fix use after free in recent commit
+  * Add support for Data Digest
+  * login: add support for gnutls
+  * login: do not try to "emulate" the libgcrypt API
+  * configure: add --with-libgcrypt option
+  * A possible 'fix' for https://github.com/sahlberg/libiscsi/issues/415 This 
patch adds a timestamp before each logged line. That could help correlating a 
logging to a network-trace. Because of offsets in time between the tracer and 
the test and the DUT, this does not always help.
+  * Manually set task to null after free to avoid double free issue
+  * lun_reset cancelling lun tasks only
+
+-------------------------------------------------------------------

Old:
----
  libiscsi-1.20.0+git.20240206.obscpio

New:
----
  libiscsi-1.20.0+git.20240530.obscpio

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ libiscsi.spec ++++++
--- /var/tmp/diff_new_pack.qKerhJ/_old  2024-06-09 20:19:20.191649692 +0200
+++ /var/tmp/diff_new_pack.qKerhJ/_new  2024-06-09 20:19:20.195649831 +0200
@@ -18,7 +18,7 @@
 
 %define         sover 10
 Name:           libiscsi
-Version:        1.20.0+git.20240206
+Version:        1.20.0+git.20240530
 Release:        0
 Summary:        iSCSI client library and utilities
 License:        GPL-2.0-only AND LGPL-2.1-only

++++++ _servicedata ++++++
--- /var/tmp/diff_new_pack.qKerhJ/_old  2024-06-09 20:19:20.235651227 +0200
+++ /var/tmp/diff_new_pack.qKerhJ/_new  2024-06-09 20:19:20.239651366 +0200
@@ -3,6 +3,6 @@
                 <param name="url">g...@github.com:sahlberg/libiscsi.git</param>
               <param 
name="changesrevision">e6bcdf5fdbf39729399c4f0914661ca1055107a1</param></service><service
 name="tar_scm">
                 <param 
name="url">https://github.com/sahlberg/libiscsi.git</param>
-              <param 
name="changesrevision">fef688aa99804588c09beb6ef7a3313dc9cf7492</param></service></servicedata>
+              <param 
name="changesrevision">b25ee4f0c4e6a27c2f1fa6b9734d6244295a9ac4</param></service></servicedata>
 (No newline at EOF)
 

++++++ libiscsi-1.20.0+git.20240206.obscpio -> 
libiscsi-1.20.0+git.20240530.obscpio ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libiscsi-1.20.0+git.20240206/README.md 
new/libiscsi-1.20.0+git.20240530/README.md
--- old/libiscsi-1.20.0+git.20240206/README.md  2024-02-06 00:51:38.000000000 
+0100
+++ new/libiscsi-1.20.0+git.20240530/README.md  2024-05-29 23:49:48.000000000 
+0200
@@ -45,6 +45,7 @@
 target_user=<account>
 target_password=<password>
 header_digest=<crc32c|none>
+data_digest=<crc32c|none>
 Transport:
 iser
 
@@ -125,6 +126,15 @@
 application wants to force a specific setting.
 
 
+Data Digest
+===========
+
+Libiscsi supports DataDigest.  By default, libiscsi will offer None so that
+Data digest will not be used, no matter what the target setting is.  This can
+be overridden by an application by calling iscsi_set_data_digest() if the
+application wants to force a specific setting.
+
+
 Patches
 =======
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libiscsi-1.20.0+git.20240206/configure.ac 
new/libiscsi-1.20.0+git.20240530/configure.ac
--- old/libiscsi-1.20.0+git.20240206/configure.ac       2024-02-06 
00:51:38.000000000 +0100
+++ new/libiscsi-1.20.0+git.20240530/configure.ac       2024-05-29 
23:49:48.000000000 +0200
@@ -78,8 +78,43 @@
 
 AC_CONFIG_HEADERS([config.h])
 
-AC_CHECK_LIB([gcrypt], [gcry_control])
-AM_CONDITIONAL([HAVE_LIBGCRYPT], [test $ac_cv_lib_gcrypt_gcry_control = yes])
+AC_ARG_WITH([gnutls],
+           [AS_HELP_STRING([--with-gnutls],
+                           [Use gnutls to compute MD5])],
+           [WITH_GNUTLS=$withval],
+           [WITH_GNUTLS=auto])
+
+AC_ARG_WITH([libgcrypt],
+           [AS_HELP_STRING([--with-libgcrypt],
+                           [Use libgcrypt to compute MD5])],
+           [WITH_LIBGCRYPT=$withval],
+           [WITH_LIBGCRYPT=auto])
+
+if test "$WITH_GNUTLS" != no; then
+  AC_CHECK_LIB([gnutls], [gnutls_hash_init])
+  if test "$WITH_GNUTLS" = yes && test "$ac_cv_lib_gnutls_gnutls_hash_init" != 
yes; then
+    AC_MSG_ERROR([gnutls not found])
+  fi
+  WITH_GNUTLS=$ac_cv_lib_gnutls_gnutls_hash_init
+fi
+if test "$WITH_GNUTLS" = yes; then
+  WITH_LIBGCRYPT=no
+fi
+
+if test "$WITH_LIBGCRYPT" != no; then
+  AC_CHECK_LIB([gcrypt], [gcry_control])
+  if test "$WITH_LIBGCRYPT" = yes && test "$ac_cv_lib_gcrypt_gcry_control" != 
yes; then
+    AC_MSG_ERROR([libgcrypt not found])
+  fi
+  WITH_LIBGCRYPT=$ac_cv_lib_gcrypt_gcry_control
+fi
+
+NEED_MD5=no
+if test "$WITH_GNUTLS" = no && test "$WITH_LIBGCRYPT" = no; then
+  NEED_MD5=yes
+fi
+AM_CONDITIONAL([NEED_MD5],
+              [expr "$NEED_MD5" : yes > /dev/null 2>&1])
 
 # For MinGW.
 AC_CHECK_LIB([ws2_32], [gethostbyname])
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libiscsi-1.20.0+git.20240206/include/iscsi-private.h 
new/libiscsi-1.20.0+git.20240530/include/iscsi-private.h
--- old/libiscsi-1.20.0+git.20240206/include/iscsi-private.h    2024-02-06 
00:51:38.000000000 +0100
+++ new/libiscsi-1.20.0+git.20240530/include/iscsi-private.h    2024-05-29 
23:49:48.000000000 +0200
@@ -61,6 +61,13 @@
 
        long long data_pos;
        unsigned char *data;
+
+       /*
+        * Some data structures wrt Data Digest (if negociated)
+        */
+       unsigned char data_digest_buf[ISCSI_DIGEST_SIZE];
+       int received_data_digest_bytes;
+       uint32_t calculated_data_digest;
 };
 void iscsi_free_iscsi_in_pdu(struct iscsi_context *iscsi, struct iscsi_in_pdu 
*in);
 
@@ -105,6 +112,8 @@
        uint32_t statsn;
        enum iscsi_header_digest want_header_digest;
        enum iscsi_header_digest header_digest;
+       enum iscsi_data_digest want_data_digest;
+       enum iscsi_data_digest data_digest;
 
        int fd;
        int is_connected;
@@ -272,6 +281,8 @@
        struct iscsi_scsi_cbdata scsi_cbdata;
        time_t scsi_timeout;
        uint32_t expxferlen;
+
+       uint32_t calculated_data_digest;
 };
 
 struct iscsi_pdu *iscsi_allocate_pdu(struct iscsi_context *iscsi,
@@ -293,6 +304,7 @@
 void iscsi_pdu_set_datasn(struct iscsi_pdu *pdu, uint32_t datasn);
 void iscsi_pdu_set_bufferoffset(struct iscsi_pdu *pdu, uint32_t bufferoffset);
 void iscsi_cancel_pdus(struct iscsi_context *iscsi);
+void iscsi_cancel_lun_pdus(struct iscsi_context *iscsi, uint32_t lun);
 int iscsi_pdu_add_data(struct iscsi_context *iscsi, struct iscsi_pdu *pdu,
                       const unsigned char *dptr, int dsize);
 int iscsi_queue_pdu(struct iscsi_context *iscsi, struct iscsi_pdu *pdu);
@@ -350,6 +362,9 @@
 void iscsi_sfree(struct iscsi_context *iscsi, void* ptr);
 
 uint32_t crc32c(uint8_t *buf, int len);
+void crc32c_init(uint32_t *crc_ptr);
+uint32_t crc32c_chain(uint32_t crc, uint8_t *buf, int len);
+uint32_t crc32c_chain_done(uint32_t crc);
 
 struct scsi_task *iscsi_scsi_get_task_from_pdu(struct iscsi_pdu *pdu);
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libiscsi-1.20.0+git.20240206/include/iscsi.h 
new/libiscsi-1.20.0+git.20240530/include/iscsi.h
--- old/libiscsi-1.20.0+git.20240206/include/iscsi.h    2024-02-06 
00:51:38.000000000 +0100
+++ new/libiscsi-1.20.0+git.20240530/include/iscsi.h    2024-05-29 
23:49:48.000000000 +0200
@@ -336,6 +336,29 @@
                            enum iscsi_header_digest header_digest);
 
 /*
+ * Types of data digest we support. Default is NONE
+ */
+enum iscsi_data_digest {
+       ISCSI_DATA_DIGEST_NONE        = 0,
+       ISCSI_DATA_DIGEST_NONE_CRC32C = 1,
+       ISCSI_DATA_DIGEST_CRC32C_NONE = 2,
+       ISCSI_DATA_DIGEST_CRC32C      = 3,
+       ISCSI_DATA_DIGEST_LAST        = ISCSI_DATA_DIGEST_CRC32C
+};
+
+/*
+ * Set the desired data digest for a scsi context.
+ * Data digest can only be set/changed before the context
+ * is logged in to the target.
+ *
+ * Returns:
+ *  0: success
+ * <0: error
+ */
+EXTERN int iscsi_set_data_digest(struct iscsi_context *iscsi,
+                           enum iscsi_data_digest data_digest);
+
+/*
  * Specify the username and password to use for chap authentication
  */
 EXTERN int iscsi_set_initiator_username_pwd(struct iscsi_context *iscsi,
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libiscsi-1.20.0+git.20240206/lib/Makefile.am 
new/libiscsi-1.20.0+git.20240530/lib/Makefile.am
--- old/libiscsi-1.20.0+git.20240206/lib/Makefile.am    2024-02-06 
00:51:38.000000000 +0100
+++ new/libiscsi-1.20.0+git.20240530/lib/Makefile.am    2024-05-29 
23:49:48.000000000 +0200
@@ -12,7 +12,7 @@
 libiscsipriv_la_SOURCES += ../win32/win32_compat.c
 endif
 
-if !HAVE_LIBGCRYPT
+if NEED_MD5
 libiscsipriv_la_SOURCES += md5.c
 endif
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libiscsi-1.20.0+git.20240206/lib/connect.c 
new/libiscsi-1.20.0+git.20240530/lib/connect.c
--- old/libiscsi-1.20.0+git.20240206/lib/connect.c      2024-02-06 
00:51:38.000000000 +0100
+++ new/libiscsi-1.20.0+git.20240530/lib/connect.c      2024-05-29 
23:49:48.000000000 +0200
@@ -431,6 +431,7 @@
        iscsi_set_targetname(tmp_iscsi, iscsi->target_name);
 
        iscsi_set_header_digest(tmp_iscsi, iscsi->want_header_digest);
+       iscsi_set_data_digest(tmp_iscsi, iscsi->want_data_digest);
 
        iscsi_set_initiator_username_pwd(tmp_iscsi, iscsi->user, iscsi->passwd);
        iscsi_set_target_username_pwd(tmp_iscsi, iscsi->target_user, 
iscsi->target_passwd);
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libiscsi-1.20.0+git.20240206/lib/crc32c.c 
new/libiscsi-1.20.0+git.20240530/lib/crc32c.c
--- old/libiscsi-1.20.0+git.20240206/lib/crc32c.c       2024-02-06 
00:51:38.000000000 +0100
+++ new/libiscsi-1.20.0+git.20240530/lib/crc32c.c       2024-05-29 
23:49:48.000000000 +0200
@@ -118,3 +118,22 @@
        return crc^0xffffffff;
 }
 
+void crc32c_init(uint32_t *crc_ptr)
+{
+   if (crc_ptr)
+      *crc_ptr = 0xffffffff;
+}
+
+uint32_t crc32c_chain(uint32_t crc, uint8_t *buf, int len)
+{
+       while (len-- > 0) {
+               crc = (crc>>8) ^ crctable[(crc ^ (*buf++)) & 0xFF];
+       }
+       return crc;
+}
+
+uint32_t crc32c_chain_done(uint32_t crc)
+{
+       return crc^0xffffffff;
+}
+
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libiscsi-1.20.0+git.20240206/lib/init.c 
new/libiscsi-1.20.0+git.20240530/lib/init.c
--- old/libiscsi-1.20.0+git.20240206/lib/init.c 2024-02-06 00:51:38.000000000 
+0100
+++ new/libiscsi-1.20.0+git.20240530/lib/init.c 2024-05-29 23:49:48.000000000 
+0200
@@ -244,6 +244,7 @@
        iscsi->want_immediate_data                    = 
ISCSI_IMMEDIATE_DATA_YES;
        iscsi->use_immediate_data                     = 
ISCSI_IMMEDIATE_DATA_YES;
        iscsi->want_header_digest                     = 
ISCSI_HEADER_DIGEST_NONE_CRC32C;
+       iscsi->want_data_digest                       = ISCSI_DATA_DIGEST_NONE;
 
        iscsi->tcp_keepcnt=3;
        iscsi->tcp_keepintvl=30;
@@ -493,6 +494,25 @@
 }
 
 int
+iscsi_set_data_digest(struct iscsi_context *iscsi,
+                       enum iscsi_data_digest data_digest)
+{
+       if (iscsi->is_loggedin) {
+               iscsi_set_error(iscsi, "trying to set data digest while "
+                               "logged in");
+               return -1;
+       }
+       if ((unsigned)data_digest > ISCSI_DATA_DIGEST_LAST) {
+               iscsi_set_error(iscsi, "invalid data digest value");
+               return -1;
+       }
+
+       iscsi->want_data_digest = data_digest;
+
+       return 0;
+}
+
+int
 iscsi_is_logged_in(struct iscsi_context *iscsi)
 {
        return iscsi->is_loggedin;
@@ -602,19 +622,32 @@
                        if (value != NULL) {
                                *value++ = 0;
                        }
-                        if (!strcmp(key, "header_digest")) {
-                                if (!strcmp(value, "crc32c")) {
-                                        iscsi_set_header_digest(
-                                            iscsi, ISCSI_HEADER_DIGEST_CRC32C);
-                                } else if (!strcmp(value, "none")) {
-                                        iscsi_set_header_digest(
-                                            iscsi, ISCSI_HEADER_DIGEST_NONE);
-                                } else {
-                                        iscsi_set_error(iscsi,
-                                            "Invalid URL argument for 
header_digest: %s", value);
-                                        return NULL;
-                                }
-                        }
+                       if (!strcmp(key, "header_digest")) {
+                               if (!strcmp(value, "crc32c")) {
+                                       iscsi_set_header_digest(
+                                               iscsi, 
ISCSI_HEADER_DIGEST_CRC32C);
+                               } else if (!strcmp(value, "none")) {
+                                       iscsi_set_header_digest(
+                                               iscsi, 
ISCSI_HEADER_DIGEST_NONE);
+                               } else {
+                                       iscsi_set_error(iscsi,
+                                               "Invalid URL argument for 
header_digest: %s", value);
+                                       return NULL;
+                               }
+                       }
+                       if (!strcmp(key, "data_digest")) {
+                               if (!strcmp(value, "crc32c")) {
+                                       iscsi_set_data_digest(
+                                               iscsi, 
ISCSI_DATA_DIGEST_CRC32C);
+                               } else if (!strcmp(value, "none")) {
+                                       iscsi_set_data_digest(
+                                               iscsi, ISCSI_DATA_DIGEST_NONE);
+                               } else {
+                                       iscsi_set_error(iscsi,
+                                               "Invalid URL argument for 
data_digest: %s", value);
+                                       return NULL;
+                               }
+                       }
                        if (!strcmp(key, "target_user")) {
                                target_user = value;
                        } else if (!strcmp(key, "target_password")) {
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libiscsi-1.20.0+git.20240206/lib/libiscsi.def 
new/libiscsi-1.20.0+git.20240530/lib/libiscsi.def
--- old/libiscsi-1.20.0+git.20240206/lib/libiscsi.def   2024-02-06 
00:51:38.000000000 +0100
+++ new/libiscsi-1.20.0+git.20240530/lib/libiscsi.def   2024-05-29 
23:49:48.000000000 +0200
@@ -115,6 +115,7 @@
 iscsi_set_log_level
 iscsi_set_log_fn
 iscsi_set_header_digest
+iscsi_set_data_digest
 iscsi_set_initiator_username_pwd
 iscsi_set_isid_en
 iscsi_set_isid_oui
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libiscsi-1.20.0+git.20240206/lib/libiscsi.syms.in 
new/libiscsi-1.20.0+git.20240530/lib/libiscsi.syms.in
--- old/libiscsi-1.20.0+git.20240206/lib/libiscsi.syms.in       2024-02-06 
00:51:38.000000000 +0100
+++ new/libiscsi-1.20.0+git.20240530/lib/libiscsi.syms.in       2024-05-29 
23:49:48.000000000 +0200
@@ -116,6 +116,7 @@
 iscsi_set_bind_interfaces
 iscsi_set_cache_allocations
 iscsi_set_header_digest
+iscsi_set_data_digest
 iscsi_set_immediate_data
 iscsi_set_initial_r2t
 iscsi_set_initiator_username_pwd
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libiscsi-1.20.0+git.20240206/lib/login.c 
new/libiscsi-1.20.0+git.20240530/lib/login.c
--- old/libiscsi-1.20.0+git.20240206/lib/login.c        2024-02-06 
00:51:38.000000000 +0100
+++ new/libiscsi-1.20.0+git.20240530/lib/login.c        2024-05-29 
23:49:48.000000000 +0200
@@ -44,6 +44,10 @@
 #include "iscsi-private.h"
 #include "scsi-lowlevel.h"
 #include "md5.h"
+
+#ifdef HAVE_LIBGNUTLS
+#include <gnutls/crypto.h>
+#endif
 #ifdef HAVE_LIBGCRYPT
 #include <gcrypt.h>
 #endif
@@ -202,7 +206,24 @@
                return 0;
        }
 
-       strncpy(str,"DataDigest=None",MAX_STRING_SIZE);
+       switch (iscsi->want_data_digest) {
+       case ISCSI_DATA_DIGEST_NONE:
+               strncpy(str,"DataDigest=None",MAX_STRING_SIZE);
+               break;
+       case ISCSI_DATA_DIGEST_NONE_CRC32C:
+               strncpy(str,"DataDigest=None,CRC32C",MAX_STRING_SIZE);
+               break;
+       case ISCSI_DATA_DIGEST_CRC32C_NONE:
+               strncpy(str,"DataDigest=CRC32C,None",MAX_STRING_SIZE);
+               break;
+       case ISCSI_DATA_DIGEST_CRC32C:
+               strncpy(str,"DataDigest=CRC32C",MAX_STRING_SIZE);
+               break;
+       default:
+               iscsi_set_error(iscsi, "invalid data digest value");
+               return -1;
+       }
+
        if (iscsi_pdu_add_data(iscsi, pdu, (unsigned char *)str, strlen(str)+1)
            != 0) {
                iscsi_set_error(iscsi, "Out-of-memory: pdu add data failed.");
@@ -681,41 +702,61 @@
        return i + '0';
 }
 
-#ifndef HAVE_LIBGCRYPT
-typedef struct MD5Context *gcry_md_hd_t;
-#define gcry_md_write MD5Update
-#define GCRY_MD_MD5 1
+#if defined HAVE_LIBGNUTLS
+#define md5_context_t gnutls_hash_hd_t
+#define md5_open(hd)  gnutls_hash_init(hd, GNUTLS_DIG_MD5)
+#define md5_write     gnutls_hash
+#define md5_read      gnutls_hash_output
+
+static void md5_close(md5_context_t h)
+{
+       unsigned char digest[16];
+
+       gnutls_hash_deinit(h, digest);
+}
+
+#elif defined HAVE_LIBGCRYPT
+typedef gcry_md_hd_t md5_context_t;
+#define md5_open(hd) gcry_md_open(hd, GCRY_MD_MD5, 0)
+#define md5_write gcry_md_write
+#define md5_close gcry_md_close
+
+static void md5_read(md5_context_t h, uint8_t *result)
+{
+       memcpy(result, gcry_md_read(h, 0), 16);
+}
+#else
+typedef struct MD5Context *md5_context_t;
+#define md5_write MD5Update
 
-static void gcry_md_open(gcry_md_hd_t *hd, int algo, unsigned int flags)
+static void md5_open(md5_context_t *hd)
 {
-       assert(algo == GCRY_MD_MD5 && flags == 0);
        *hd = malloc(sizeof(struct MD5Context));
        if (*hd) {
                MD5Init(*hd);
        }
 }
 
-static void gcry_md_putc(gcry_md_hd_t h, unsigned char c)
-{
-       MD5Update(h, &c, 1);
-}
-
-static char *gcry_md_read(gcry_md_hd_t h, int algo)
+static void md5_read(md5_context_t h, uint8_t *result)
 {
        unsigned char digest[16];
-       assert(algo == 0 || algo == GCRY_MD_MD5);
 
        MD5Final(digest, h);
-       return memcpy(h->buf, digest, sizeof(digest));
+       memcpy(result, digest, sizeof(digest));
 }
 
-static void gcry_md_close(gcry_md_hd_t h)
+static void md5_close(md5_context_t h)
 {
        memset(h, 0, sizeof(*h));
        free(h);
 }
 #endif
 
+static inline void md5_putc(md5_context_t h, unsigned char c)
+{
+       md5_write(h, &c, 1);
+}
+
 /* size of the challenge used for bidirectional chap */
 #define TARGET_CHAP_C_SIZE 32
 
@@ -726,7 +767,7 @@
        char * strp;
        unsigned char c, cc[2];
        unsigned char digest[CHAP_R_SIZE];
-       gcry_md_hd_t ctx;
+       md5_context_t ctx;
        int i;
 
        if (iscsi->current_phase != ISCSI_PDU_LOGIN_CSG_SECNEG
@@ -739,22 +780,22 @@
                return -1;
        }
 
-       gcry_md_open(&ctx, GCRY_MD_MD5, 0);
+       md5_open(&ctx);
        if (ctx == NULL) {
                iscsi_set_error(iscsi, "Cannot create MD5 algorithm");
                return -1;
        }
-       gcry_md_putc(ctx, iscsi->chap_i);
-       gcry_md_write(ctx, (unsigned char *)iscsi->passwd, 
strlen(iscsi->passwd));
+       md5_putc(ctx, iscsi->chap_i);
+       md5_write(ctx, (unsigned char *)iscsi->passwd, strlen(iscsi->passwd));
 
        strp = iscsi->chap_c;
        while (*strp != 0) {
                c = (h2i(strp[0]) << 4) | h2i(strp[1]);
                strp += 2;
-               gcry_md_putc(ctx, c);
+               md5_putc(ctx, c);
        }
-       memcpy(digest, gcry_md_read(ctx, 0), sizeof(digest));
-       gcry_md_close(ctx);
+       md5_read(ctx, digest);
+       md5_close(ctx);
 
        strncpy(str,"CHAP_R=0x",MAX_STRING_SIZE);
        if (iscsi_pdu_add_data(iscsi, pdu, (unsigned char *)str, strlen(str))
@@ -822,20 +863,19 @@
                        return -1;
                }
 
-               gcry_md_open(&ctx, GCRY_MD_MD5, 0);
+               md5_open(&ctx);
                if (ctx == NULL) {
                        iscsi_set_error(iscsi, "Cannot create MD5 algorithm");
                        return -1;
                }
-               gcry_md_putc(ctx, iscsi->target_chap_i);
-               gcry_md_write(ctx, (unsigned char *)iscsi->target_passwd,
+               md5_putc(ctx, iscsi->target_chap_i);
+               md5_write(ctx, (unsigned char *)iscsi->target_passwd,
                              strlen(iscsi->target_passwd));
-               gcry_md_write(ctx, (unsigned char *)target_chap_c,
+               md5_write(ctx, (unsigned char *)target_chap_c,
                              TARGET_CHAP_C_SIZE);
 
-               memcpy(iscsi->target_chap_r, gcry_md_read(ctx, 0),
-                      sizeof(iscsi->target_chap_r));
-               gcry_md_close(ctx);
+               md5_read(ctx, iscsi->target_chap_r);
+               md5_close(ctx);
        }
 
        return 0;
@@ -1200,6 +1240,16 @@
                        }
                }
 
+               if (!strncmp(ptr, "DataDigest=", 11)) {
+                       if (!strcmp(ptr + 11, "CRC32C")) {
+                               iscsi->want_data_digest
+                                 = ISCSI_DATA_DIGEST_CRC32C;
+                       } else {
+                               iscsi->want_data_digest
+                                 = ISCSI_DATA_DIGEST_NONE;
+                       }
+               }
+
                if (!strncmp(ptr, "FirstBurstLength=", 17)) {
                        iscsi->first_burst_length = strtol(ptr + 17, NULL, 10);
                }
@@ -1370,6 +1420,7 @@
                iscsi->is_loggedin = 1;
                iscsi_itt_post_increment(iscsi);
                iscsi->header_digest  = iscsi->want_header_digest;
+               iscsi->data_digest  = iscsi->want_data_digest;
                ISCSI_LOG(iscsi, 2, "login successful");
                pdu->callback(iscsi, SCSI_STATUS_GOOD, NULL, pdu->private_data);
        } else {
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libiscsi-1.20.0+git.20240206/lib/pdu.c 
new/libiscsi-1.20.0+git.20240530/lib/pdu.c
--- old/libiscsi-1.20.0+git.20240206/lib/pdu.c  2024-02-06 00:51:38.000000000 
+0100
+++ new/libiscsi-1.20.0+git.20240530/lib/pdu.c  2024-05-29 23:49:48.000000000 
+0200
@@ -225,6 +225,9 @@
        /* flags */
        pdu->flags = flags;
 
+       /* DataDigest - may or may not be calculated.  Initialize anyway. */
+       crc32c_init(&pdu->calculated_data_digest);
+
        return pdu;
 }
 
@@ -537,6 +540,25 @@
                }
        }
 
+       /* verify data checksum ... */
+       if (iscsi->data_digest != ISCSI_DATA_DIGEST_NONE) {
+               int dsl = scsi_get_uint32(&in->hdr[4]) & 0x00ffffff;
+               /* ... but only if some data is present. */
+               if (dsl) {
+                       uint32_t crc_rcvd = 0;
+                       uint32_t crc = 
crc32c_chain_done(in->calculated_data_digest);
+
+                       crc_rcvd |= in->data_digest_buf[0];
+                       crc_rcvd |= in->data_digest_buf[1] << 8;
+                       crc_rcvd |= in->data_digest_buf[2] << 16;
+                       crc_rcvd |= in->data_digest_buf[3] << 24;
+                       if (crc != crc_rcvd) {
+                               iscsi_set_error(iscsi, "data checksum 
verification failed: calculated 0x%" PRIx32 " received 0x%" PRIx32, crc, 
crc_rcvd);
+                               return -1;
+                       }
+               }
+       }
+
        if (ahslen != 0) {
                iscsi_set_error(iscsi, "cant handle expanded headers yet");
                return -1;
@@ -946,4 +968,37 @@
                }
                iscsi->drv->free_pdu(iscsi, pdu);
        }
+}
+
+void
+iscsi_cancel_lun_pdus(struct iscsi_context *iscsi, uint32_t lun)
+{
+       struct iscsi_pdu *pdu;
+       struct iscsi_pdu *next_pdu;
+       uint32_t cmdsn_gap = 0;
+       struct scsi_task * task = NULL;
+
+       for (pdu = iscsi->outqueue; pdu; pdu = next_pdu) {
+               next_pdu = pdu->next;
+               task = iscsi_scsi_get_task_from_pdu(pdu);
+
+               if (cmdsn_gap > 0) {
+                       iscsi_pdu_set_cmdsn(pdu, pdu->cmdsn - cmdsn_gap);
+               }
+               if (task == NULL || task->lun != lun) {
+                       continue;
+               }
+               if (!(pdu->outdata.data[0] & ISCSI_PDU_IMMEDIATE) &&
+                   (pdu->outdata.data[0] & 0x3f) != ISCSI_PDU_DATA_OUT) {
+                       iscsi->cmdsn--;
+                       cmdsn_gap++;
+               }
+               ISCSI_LIST_REMOVE(&iscsi->outqueue, pdu);
+               iscsi_set_error(iscsi, "command cancelled");
+               if (pdu->callback) {
+                       pdu->callback(iscsi, SCSI_STATUS_CANCELLED,
+                               NULL, pdu->private_data);
+               }
+               iscsi->drv->free_pdu(iscsi, pdu);
+       }
 }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libiscsi-1.20.0+git.20240206/lib/scsi-lowlevel.c 
new/libiscsi-1.20.0+git.20240530/lib/scsi-lowlevel.c
--- old/libiscsi-1.20.0+git.20240206/lib/scsi-lowlevel.c        2024-02-06 
00:51:38.000000000 +0100
+++ new/libiscsi-1.20.0+git.20240530/lib/scsi-lowlevel.c        2024-05-29 
23:49:48.000000000 +0200
@@ -79,7 +79,9 @@
        }
 
        free(task->datain.data);
+       task->datain.data = NULL;
        free(task);
+       task = NULL;
 }
 
 struct scsi_task *
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libiscsi-1.20.0+git.20240206/lib/socket.c 
new/libiscsi-1.20.0+git.20240530/lib/socket.c
--- old/libiscsi-1.20.0+git.20240206/lib/socket.c       2024-02-06 
00:51:38.000000000 +0100
+++ new/libiscsi-1.20.0+git.20240530/lib/socket.c       2024-05-29 
23:49:48.000000000 +0200
@@ -62,6 +62,7 @@
 #include <sys/uio.h>
 #endif
 
+#include <stdbool.h>
 #include <stdint.h>
 #include <stdio.h>
 #include <stdlib.h>
@@ -514,7 +515,7 @@
 }
 
 ssize_t
-iscsi_iovector_readv_writev(struct iscsi_context *iscsi, struct scsi_iovector 
*iovector, uint32_t pos, ssize_t count, int do_write)
+iscsi_iovector_readv_writev(struct iscsi_context *iscsi, struct scsi_iovector 
*iovector, uint32_t pos, ssize_t count, uint32_t *data_digest_ptr, int do_write)
 {
        struct scsi_iovec *iov, *iov2;
        int niov;
@@ -598,6 +599,19 @@
                n = readv(iscsi->fd, (struct iovec*) iov, niov);
        }
 
+       /* Update the data digest */
+       if (data_digest_ptr && n > 0) {
+               int i;
+               size_t bytes_to_crc = n;
+               struct iovec *iov_ptr = (struct iovec*)iov;
+
+               for ( i=0; iov_ptr && i<niov && bytes_to_crc; iov_ptr++, i++) {
+                       size_t chunk = MIN(bytes_to_crc, iov_ptr->iov_len);
+                       *data_digest_ptr = crc32c_chain(*data_digest_ptr, 
iov_ptr->iov_base, chunk);
+                       bytes_to_crc -= chunk;
+               }
+       }
+
        /* restore original values */
        iov->iov_base = (void*) ((uintptr_t)iov->iov_base - pos);
        iov->iov_len += pos;
@@ -619,6 +633,7 @@
 {
        struct iscsi_in_pdu *in;
        ssize_t hdr_size, data_size, count, padding_size;
+       bool do_data_digest = (iscsi->data_digest != ISCSI_DATA_DIGEST_NONE);
 
        do {
                hdr_size = ISCSI_HEADER_SIZE(iscsi->header_digest);
@@ -628,6 +643,7 @@
                                iscsi_set_error(iscsi, "Out-of-memory: failed 
to malloc iscsi_in_pdu");
                                return -1;
                        }
+                       crc32c_init(&(iscsi->incoming->calculated_data_digest));
                        iscsi->incoming->hdr = iscsi_smalloc(iscsi, hdr_size);
                        if (iscsi->incoming->hdr == NULL) {
                                iscsi_set_error(iscsi, "Out-of-memory");
@@ -682,7 +698,7 @@
                        iovector_in = iscsi_get_scsi_task_iovector_in(iscsi, 
in);
                        if (iovector_in != NULL && count > padding_size) {
                                uint32_t offset = scsi_get_uint32(&in->hdr[40]);
-                               count = iscsi_iovector_readv_writev(iscsi, 
iovector_in, in->data_pos + offset, count - padding_size, 0);
+                               count = iscsi_iovector_readv_writev(iscsi, 
iovector_in, in->data_pos + offset, count - padding_size, do_data_digest ? 
&(in->calculated_data_digest) : NULL, 0);
                        } else {
                                if (iovector_in == NULL) {
                                        if (in->data == NULL) {
@@ -695,6 +711,8 @@
                                        buf = &in->data[in->data_pos];
                                }
                                count = recv(iscsi->fd, (void *)buf, count, 0);
+                               if (do_data_digest && count > 0)
+                                       in->calculated_data_digest = 
crc32c_chain(in->calculated_data_digest, buf, count);
                        }
                        if (count == 0) {
                                /* remote side has closed the socket. */
@@ -713,6 +731,28 @@
                        break;
                }
 
+               /* Handle Data Digest receive */
+               if (data_size != 0 && do_data_digest &&
+                       in->received_data_digest_bytes < ISCSI_DIGEST_SIZE) {
+
+                       count = recv(iscsi->fd, (void *)(in->data_digest_buf + 
in->received_data_digest_bytes), ISCSI_DIGEST_SIZE - 
in->received_data_digest_bytes, 0);
+                       if (count == 0) {
+                               /* remote side has closed the socket. */
+                               return -1;
+                       }
+                       if (count < 0) {
+                               if (errno == EINTR || errno == EAGAIN) {
+                                       break;
+                               }
+                               return -1;
+                       }
+                       in->received_data_digest_bytes += count;
+
+                       if (in->received_data_digest_bytes < ISCSI_DIGEST_SIZE) 
{
+                               break;
+                       }
+               }
+
                iscsi->incoming = NULL;
                if (iscsi_process_pdu(iscsi, in) != 0) {
                        iscsi_free_iscsi_in_pdu(iscsi, in);
@@ -751,6 +791,7 @@
        struct iscsi_pdu *pdu;
        static char padding_buf[3];
        int socket_flags = 0;
+       bool do_data_digest = (iscsi->data_digest != ISCSI_DATA_DIGEST_NONE);
 
 #ifdef MSG_NOSIGNAL
        socket_flags |= MSG_NOSIGNAL;
@@ -848,7 +889,7 @@
                        count = iscsi_iovector_readv_writev(iscsi,
                                iovector_out,
                                pdu->payload_offset + pdu->payload_written,
-                               pdu->payload_len - pdu->payload_written, 1);
+                               pdu->payload_len - pdu->payload_written, 
do_data_digest ? &(pdu->calculated_data_digest) : NULL, 1);
                        if (count == -1) {
                                if (errno == EAGAIN || errno == EWOULDBLOCK) {
                                        return 0;
@@ -873,12 +914,56 @@
                                                "socket :%d", errno);
                                return -1;
                        }
+
+                       if (do_data_digest)
+                               pdu->calculated_data_digest = 
crc32c_chain(pdu->calculated_data_digest, (uint8_t *)padding_buf, count);
+
                        pdu->payload_written += count;
                }
+
                /* if we havent written the full padding yet. */
+               if (pdu->payload_written < total) {
+                       return 0;
+               }
+
+               /*
+                * Maybe update the total again, and write the digest, but only 
if
+                * 1. DataDigest has been negociated, and
+                * 2. We have actually written some data
+                */
+               if (do_data_digest && pdu->payload_written) {
+                       uint32_t data_digest = 
crc32c_chain_done(pdu->calculated_data_digest);
+                       char data_digest_buf[ISCSI_DIGEST_SIZE];
+
+                       total += ISCSI_DIGEST_SIZE;
+
+                       data_digest_buf[3] = (data_digest >> 24);
+                       data_digest_buf[2] = (data_digest >> 16);
+                       data_digest_buf[1] = (data_digest >>  8);
+                       data_digest_buf[0] = (data_digest);
+
+                       /* Write data digest */
+                       if (pdu->payload_written < total) {
+                               int todo = total - pdu->payload_written;
+                               count = send(iscsi->fd, data_digest_buf + 
(ISCSI_DIGEST_SIZE - todo), todo, socket_flags);
+                               if (count == -1) {
+                                       if (errno == EAGAIN || errno == 
EWOULDBLOCK) {
+                                               return 0;
+                                       }
+                                       iscsi_set_error(iscsi, "Error when 
writing to "
+                                                       "socket :%d", errno);
+                                       return -1;
+                               }
+
+                               pdu->payload_written += count;
+                       }
+               }
+
+               /* if we havent written everything yet. */
                if (pdu->payload_written != total) {
                        return 0;
                }
+
                if (pdu->flags & ISCSI_PDU_CORK_WHEN_SENT) {
                        iscsi->is_corked = 1;
                }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libiscsi-1.20.0+git.20240206/lib/task_mgmt.c 
new/libiscsi-1.20.0+git.20240530/lib/task_mgmt.c
--- old/libiscsi-1.20.0+git.20240206/lib/task_mgmt.c    2024-02-06 
00:51:38.000000000 +0100
+++ new/libiscsi-1.20.0+git.20240530/lib/task_mgmt.c    2024-05-29 
23:49:48.000000000 +0200
@@ -130,7 +130,7 @@
                      uint32_t lun,
                      iscsi_command_cb cb, void *private_data)
 {
-       iscsi_scsi_cancel_all_tasks(iscsi);
+       iscsi_cancel_lun_pdus(iscsi, lun);
 
        return iscsi_task_mgmt_async(iscsi,
                      lun, ISCSI_TM_LUN_RESET,
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/libiscsi-1.20.0+git.20240206/test-tool/iscsi-support.c 
new/libiscsi-1.20.0+git.20240530/test-tool/iscsi-support.c
--- old/libiscsi-1.20.0+git.20240206/test-tool/iscsi-support.c  2024-02-06 
00:51:38.000000000 +0100
+++ new/libiscsi-1.20.0+git.20240530/test-tool/iscsi-support.c  2024-05-29 
23:49:48.000000000 +0200
@@ -457,6 +457,8 @@
         va_list ap;
         static char message[1024];
         int ret;
+        struct timespec ts;
+        struct tm tm;
 
         if (loglevel < level) {
                 return;
@@ -467,6 +469,17 @@
                 return;
         }
 
+        if (clock_gettime(CLOCK_REALTIME, &ts) == -1) {
+                return;
+       }
+
+        if (!localtime_r(&ts.tv_sec, &tm)) {
+                return;
+        }
+
+        printf("    %04d-%02d-%02d %02d:%02d:%02d.%06d ",
+                tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday, tm.tm_hour, 
tm.tm_min, tm.tm_sec, (int)ts.tv_nsec / 1000);
+
         va_start(ap, format);
         ret = vsnprintf(message, 1024, format, ap);
         va_end(ap);

++++++ libiscsi.obsinfo ++++++
--- /var/tmp/diff_new_pack.qKerhJ/_old  2024-06-09 20:19:20.491660157 +0200
+++ /var/tmp/diff_new_pack.qKerhJ/_new  2024-06-09 20:19:20.495660297 +0200
@@ -1,5 +1,5 @@
 name: libiscsi
-version: 1.20.0+git.20240206
-mtime: 1707177098
-commit: fef688aa99804588c09beb6ef7a3313dc9cf7492
+version: 1.20.0+git.20240530
+mtime: 1717019388
+commit: b25ee4f0c4e6a27c2f1fa6b9734d6244295a9ac4
 

Reply via email to