public inbox for pve-devel@lists.proxmox.com
 help / color / mirror / Atom feed
From: Felix Driessler <fdriessler@inett.de>
To: pve-devel@lists.proxmox.com
Subject: [PATCH pve-stoage 4/4] iscsiPlugin: add chap auth
Date: Fri, 27 Mar 2026 11:14:56 +0100	[thread overview]
Message-ID: <20260327101456.16614-5-fdriessler@inett.de> (raw)
In-Reply-To: <20260327101456.16614-1-fdriessler@inett.de>

Signed-off-by: Felix Driessler <fdriessler@inett.de>
---
 src/PVE/Storage/ISCSIPlugin.pm | 122 ++++++++++++++++++++++++++++++++-
 1 file changed, 119 insertions(+), 3 deletions(-)

diff --git a/src/PVE/Storage/ISCSIPlugin.pm b/src/PVE/Storage/ISCSIPlugin.pm
index bb5576b..777c3b0 100644
--- a/src/PVE/Storage/ISCSIPlugin.pm
+++ b/src/PVE/Storage/ISCSIPlugin.pm
@@ -159,13 +159,21 @@ sub iscsi_discovery {
 }
 
 sub iscsi_login {
-    my ($target, $portals, $cache) = @_;
+    my ($target, $portals, $cache, $scfg, $storeid) = @_;
 
     assert_iscsi_support();
 
     eval { iscsi_discovery($target, $portals, $cache); };
     warn $@ if $@;
 
+    if ($scfg->{enablechap}) {
+        eval { iscsi_chap_enable($scfg, $storeid) };
+        warn $@ if $@;
+    } else {
+        eval { iscsi_chap_disable($target); };
+        warn $@ if $@;
+    }
+
     # Disable retries to avoid blocking pvestatd for too long, next iteration will retry anyway
     eval {
         my $cmd = [
@@ -193,9 +201,42 @@ sub iscsi_logout {
 
     assert_iscsi_support();
 
+    eval { iscsi_chap_disable($target); };
+    warn $@ if $@;
+
     run_command([$ISCSIADM, '--mode', 'node', '--targetname', $target, '--logout']);
 }
 
+sub iscsi_chap_enable {
+    my ($scfg, $storeid) = @_;
+
+    my $password = iscsi_get_password($scfg, $storeid);
+    my $target = $scfg->{target};
+    my $username = $scfg->{username};
+
+    $password =~ m|^(.*)$|
+        or die "incorrect Password.";
+    $password = $1;
+
+    run_command([
+        $ISCSIADM, '--mode', 'node', '--targetname', $target,
+        '-o', 'update', '-n', 'node.session.auth.authmethod', '-v', 'CHAP',
+        '-o', 'update', '-n', 'node.session.auth.username', '-v', $username,
+        '-o', 'update', '-n', 'node.session.auth.password', '-v', $password,
+    ]);
+}
+
+sub iscsi_chap_disable {
+    my ($target) = @_;
+
+    run_command([
+        $ISCSIADM, '--mode', 'node', '--targetname', $target,
+        '-o', 'update', '-n', 'node.session.auth.authmethod', '-v', 'None',
+        '-o', 'update', '-n', 'node.session.auth.username', '-v', '""',
+        '-o', 'update', '-n', 'node.session.auth.password', '-v', '""',
+    ]);
+}
+
 my $rescan_filename = "/var/run/pve-iscsi-rescan.lock";
 
 sub iscsi_session_rescan {
@@ -342,7 +383,9 @@ sub plugindata {
     return {
         content => [{ images => 1, none => 1 }, { images => 1 }],
         select_existing => 1,
-        'sensitive-properties' => {},
+        'sensitive-properties' => {
+            password => 1,
+        },
     };
 }
 
@@ -357,6 +400,11 @@ sub properties {
             type => 'string',
             format => 'pve-storage-portal-dns',
         },
+        enablechap => {
+            description => "Enable CHAP Authentication.",
+            type => 'boolean',
+            default => 0,
+        },
     };
 }
 
@@ -368,9 +416,47 @@ sub options {
         disable => { optional => 1 },
         content => { optional => 1 },
         bwlimit => { optional => 1 },
+        enablechap => { optional => 1 },
+        username => { optional => 1 },
+        password => { optional => 1 },
     };
 }
 
+# Helpers
+
+sub iscsi_password_file_name {
+    my ($scfg, $storeid) = @_;
+
+    return "/etc/pve/priv/storage/${storeid}.pw";
+}
+
+sub iscsi_set_password {
+    my ($scfg, $storeid, $password) = @_;
+
+    my $pwfile = iscsi_password_file_name($scfg, $storeid);
+    mkdir "/etc/pve/priv/storage";
+
+    PVE::Tools::file_set_contents($pwfile, "$password\n", 0600, 1);
+}
+
+sub iscsi_delete_password {
+    my ($scfg, $storeid) = @_;
+
+    my $pwfile = iscsi_password_file_name($scfg, $storeid);
+
+    unlink $pwfile;
+}
+
+sub iscsi_get_password {
+    my ($scfg, $storeid) = @_;
+
+    my $pwfile = iscsi_password_file_name($scfg, $storeid);
+
+    my $contents = PVE::Tools::file_read_firstline($pwfile);
+
+    return eval { decode('UTF-8', $contents, 1) } // $contents;
+}
+
 # Storage implementation
 
 sub parse_volname {
@@ -505,7 +591,7 @@ sub activate_storage {
     }
 
     if ($do_login) {
-        eval { iscsi_login($scfg->{target}, $portals, $cache); };
+        eval { iscsi_login($scfg->{target}, $portals, $cache, $scfg, $storeid); };
         warn $@ if $@;
     } else {
         # make sure we get all devices
@@ -711,4 +797,34 @@ sub volume_import {
     die "volume import is not possible on iscsi storage\n";
 }
 
+sub on_add_hook {
+    my ($class, $storeid, $scfg, %param) = @_;
+    if (defined(my $password = $param{password}) && $scfg->{enablechap}) {
+        iscsi_set_password($scfg, $storeid, $password);
+    }
+    else {
+        iscsi_delete_password($scfg, $storeid);
+    }
+}
+
+sub on_update_hook {
+    return if !assert_iscsi_support(1);
+
+    my ($class, $storeid, $scfg, %param) = @_;
+    if (exists($param{password})) {
+        if (defined(my $password = $param{password}) && $scfg->{enablechap}) {
+            if ($password != "") {
+                iscsi_set_password($scfg, $storeid, $password);
+            }
+        }
+        else {
+            iscsi_delete_password($scfg, $storeid);
+        }
+    }
+
+    eval { iscsi_logout($scfg->{target}); };
+    activate_storage($class, $storeid, $scfg)
+}
+
+
 1;
-- 
2.52.0



Felix Driessler
Junior Systems Engineer // #GernPerDU

Linux - Open Source - IT Solutions

T: +49-681-410993-0
E: fdriessler@inett.de
https://www.inett.de



inett GmbH | Altenkesseler Strasse 17 / B8 | 66115 Saarbrücken | Germany

Vertrieb: vertrieb@inett.de // +49-681-410993-33
Support: support@inett.de // +49-681-410993-42





Geschäftsführung: Marco Gabriel | Amtsgericht Saarbrücken HRB 16588



      parent reply	other threads:[~2026-03-27 10:15 UTC|newest]

Thread overview: 5+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
     [not found] <f53ca227-2275-443f-84f8-48b2785269b2.2bc2ceb6-a3a3-4c49-9566-519c7d2ab20e.21103ee5-34fe-43b6-b130-08f8ab2b25ae@emailsignatures365.codetwo.com>
2026-03-27 10:14 ` [PATCH pve-manager/pve-storage 0/4] extend iscsi configuration Felix Driessler
     [not found]   ` <f53ca227-2275-443f-84f8-48b2785269b2.2bc2ceb6-a3a3-4c49-9566-519c7d2ab20e.d935a384-10c1-4974-ba2a-7adab51bb127@emailsignatures365.codetwo.com>
2026-03-27 10:14     ` [PATCH pve-manager 1/4] ui: Add Display of WWID for ISCSI Felix Driessler
     [not found]   ` <f53ca227-2275-443f-84f8-48b2785269b2.2bc2ceb6-a3a3-4c49-9566-519c7d2ab20e.5ac71d0a-bc32-41c3-8898-7681716f7a92@emailsignatures365.codetwo.com>
2026-03-27 10:14     ` [PATCH pve-manager 2/4] ui: Add CHAP Authentication " Felix Driessler
     [not found]   ` <f53ca227-2275-443f-84f8-48b2785269b2.2bc2ceb6-a3a3-4c49-9566-519c7d2ab20e.24fbb610-73bc-4d0e-8ec7-c0b5fbde4ff8@emailsignatures365.codetwo.com>
2026-03-27 10:14     ` [PATCH pve-stoage 3/4] iscsiPlugin: add wwid Felix Driessler
     [not found]   ` <f53ca227-2275-443f-84f8-48b2785269b2.2bc2ceb6-a3a3-4c49-9566-519c7d2ab20e.6c58b149-eb37-45dd-84d7-651f4453edab@emailsignatures365.codetwo.com>
2026-03-27 10:14     ` Felix Driessler [this message]

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20260327101456.16614-5-fdriessler@inett.de \
    --to=fdriessler@inett.de \
    --cc=pve-devel@lists.proxmox.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
Service provided by Proxmox Server Solutions GmbH | Privacy | Legal