Script 'mail_helper' called by obssrc
Hello community,

here is the log from the commit of package suseconnect-ng for openSUSE:Factory 
checked in at 2026-06-13 18:44:50
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/suseconnect-ng (Old)
 and      /work/SRC/openSUSE:Factory/.suseconnect-ng.new.1981 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "suseconnect-ng"

Sat Jun 13 18:44:50 2026 rev:35 rq:1358761 version:1.22.1

Changes:
--------
--- /work/SRC/openSUSE:Factory/suseconnect-ng/suseconnect-ng.changes    
2026-06-10 15:46:40.556613368 +0200
+++ /work/SRC/openSUSE:Factory/.suseconnect-ng.new.1981/suseconnect-ng.changes  
2026-06-13 18:45:01.359660059 +0200
@@ -1,0 +2,8 @@
+Wed Jun 10 18:43:58 UTC 2026 - Earl Sampson <[email protected]>
+
+- Update version to 1.22.1:
+  - library: Allow clients to disable the token handling mechanism 
(jsc#SCC-801)
+  - Ensure updated system certs are included when creating HTTP client
+    connections (bsc#1268017, jsc#SCC-804)
+
+-------------------------------------------------------------------

Old:
----
  suseconnect-ng-1.22.0.tar.xz

New:
----
  suseconnect-ng-1.22.1.tar.xz

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

Other differences:
------------------
++++++ suseconnect-ng.spec ++++++
--- /var/tmp/diff_new_pack.TAp6lC/_old  2026-06-13 18:45:02.799720048 +0200
+++ /var/tmp/diff_new_pack.TAp6lC/_new  2026-06-13 18:45:02.799720048 +0200
@@ -19,7 +19,7 @@
 %global project github.com/SUSE/connect-ng
 
 Name:           suseconnect-ng
-Version:        1.22.0
+Version:        1.22.1
 Release:        0
 URL:            https://github.com/SUSE/connect-ng
 License:        LGPL-3.0-or-later
@@ -100,6 +100,14 @@
 %description -n suseconnect-ruby-bindings
 This package provides bindings needed to use libsuseconnect from Ruby scripts.
 
+%package -n mcp-server-suseconnect
+Summary:        MCP server for suseconnect
+Group:          System/Management
+Requires:       suseconnect-ng = %version
+
+%description -n mcp-server-suseconnect
+This package provides an MCP server for suseconnect to enable integration into 
the agentic SLES framework.
+
 %prep
 %autosetup -p1 -a2 -n%{name}-%{version}
 
@@ -110,6 +118,7 @@
 go build -v -ldflags "-s -w" -mod=vendor -buildmode=pie -o 
bin/zypper-migration %{project}/cmd/zypper-migration
 go build -v -ldflags "-s -w" -mod=vendor -buildmode=pie -o 
bin/zypper-search-packages %{project}/cmd/zypper-search-packages
 go build -v -ldflags "-s -w" -mod=vendor -buildmode=pie -o 
bin/suse-uptime-tracker %{project}/cmd/suse-uptime-tracker
+go build -v -ldflags "-s -w" -mod=vendor -buildmode=pie -o bin/suseconnect-mcp 
%{project}/cmd/suseconnect-mcp
 
 # the library
 mkdir -p %_builddir/go/lib
@@ -118,8 +127,9 @@
 %install
 # Install binary + symlinks
 install -D -m 0755 bin/suseconnect %{buildroot}/%{_bindir}/suseconnect
-install -D -m 0755 bin/suse-uptime-tracker 
%{buildroot}/%{_bindir}/suse-uptime-tracker
 ln -s %{_bindir}/suseconnect %{buildroot}/%{_bindir}/SUSEConnect
+install -D -m 0755 bin/suse-uptime-tracker 
%{buildroot}/%{_bindir}/suse-uptime-tracker
+install -D -m 0755 bin/suseconnect-mcp %{buildroot}/%{_bindir}/suseconnect-mcp
 
 install -d -m 0755 %{buildroot}/%{_sbindir}
 ln -s %{_bindir}/suseconnect %{buildroot}/%{_sbindir}/SUSEConnect
@@ -249,3 +259,6 @@
 %doc third_party/yast/README.md
 %{_libdir}/ruby/vendor_ruby/%rb_ver/suse
 
+%files -n mcp-server-suseconnect
+%{_bindir}/suseconnect-mcp
+

++++++ _service ++++++
--- /var/tmp/diff_new_pack.TAp6lC/_old  2026-06-13 18:45:02.863722714 +0200
+++ /var/tmp/diff_new_pack.TAp6lC/_new  2026-06-13 18:45:02.871723047 +0200
@@ -2,7 +2,7 @@
   <service name="tar_scm" mode="manual">
     <param name="scm">git</param>
     <param name="url">https://github.com/SUSE/connect-ng.git</param>
-    <param name="revision">v1.22.0</param>
+    <param name="revision">v1.22.1</param>
     <param name="versionformat">@PARENT_TAG@</param>
     <param name="versionrewrite-pattern">v(\d+\.\d+\.\d+)</param>
     <param name="versionrewrite-replacement">\1</param>

++++++ suseconnect-ng-1.22.0.tar.xz -> suseconnect-ng-1.22.1.tar.xz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/suseconnect-ng-1.22.0/README.md 
new/suseconnect-ng-1.22.1/README.md
--- old/suseconnect-ng-1.22.0/README.md 2026-06-08 20:16:18.000000000 +0200
+++ new/suseconnect-ng-1.22.1/README.md 2026-06-11 17:47:03.000000000 +0200
@@ -15,6 +15,60 @@
 
 SUSEConnect-ng communicates with SCC over this [REST 
API](https://github.com/SUSE/connect/blob/master/doc/SCC-API-%28Implemented%29.md).
 
+### Prerequisites
+The following tools should be available and verified as working:
+
+  * A Golang v1.24 or later environment
+    * needed to run certain go commands locally for testing and
+      validation.
+  * `git`
+  * `make`
+  * `docker`
+
+### Quick Start
+
+  * Clone the repo
+      ```
+      git clone https://github.com/SUSE/connect-ng
+      cd connect-ng
+      ```
+
+  * When building for the first time, execute 
+      ```
+      make vendor
+      ```
+
+  * Run build which will create `out/suseconnect` binary.
+      ```
+      make build
+      ```
+
+  * Setup .env file to run tests
+    * Copy .env-example file to .env file and fill following values
+        ```
+        REGCODE="<regcode>"
+        EXPIRED_REGCODE="<regcode>"
+        HA_REGCODE="<ha regcode>"
+        ```
+
+        These regcodes can be your personal regcodes attached to your 
organization. Please refer 
[Activating-and-Managing-Subscriptions](https://scc.suse.com/docs/userguide#UG-Activating-and-Managing-Subscriptions)
+
+  * To run the unit tests
+      ```
+      make test
+      ```
+
+  * To run the feature tests   
+    Run the feature tests within a container by using the registration codes 
as provided by the .env file.
+       ```
+       make feature-tests
+       ```
+
+  * To run the YAST2 registration tests
+      ```
+      make test-yast
+      ```  
+
 ### Build
 Requires Go >= 1.24
 
@@ -24,7 +78,7 @@
 This will create a `out/suseconnect` binary.
 
 ### Build in container
-If you don't have a go compiler installed, you can run the build in a 
container: 
+If you don't have a go compiler installed, you can run the build in a 
container:
 ```
 docker run --rm -v $(pwd):/connect registry.suse.com/bci/golang:1.24-openssl 
sh -c "git config --global --add safe.directory /connect; cd /connect; make 
build"
 ```
@@ -47,11 +101,12 @@
 
 For feature tests you first need to create an `.env` file in the root directory
 of the project with the following contents:
+For that copy .env-example file to .env file and fill following values
 
 ``` sh
-VALID_REGCODE="<regcode>"
+REGCODE="<regcode>"
 EXPIRED_REGCODE="<regcode>"
-NOT_ACTIVATED_REGCODE="<regcode>"
+HA_REGCODE="<regcode>"
 ```
 
 These values can be picked up from Glue's production environment. Once that is
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/suseconnect-ng-1.22.0/build/packaging/suseconnect-ng.changes 
new/suseconnect-ng-1.22.1/build/packaging/suseconnect-ng.changes
--- old/suseconnect-ng-1.22.0/build/packaging/suseconnect-ng.changes    
2026-06-08 20:16:18.000000000 +0200
+++ new/suseconnect-ng-1.22.1/build/packaging/suseconnect-ng.changes    
2026-06-11 17:47:03.000000000 +0200
@@ -1,4 +1,12 @@
 -------------------------------------------------------------------
+Wed Jun 10 18:43:58 UTC 2026 - Earl Sampson <[email protected]>
+
+- Update version to 1.22.1:
+  - library: Allow clients to disable the token handling mechanism 
(jsc#SCC-801)
+  - Ensure updated system certs are included when creating HTTP client
+    connections (bsc#1268017, jsc#SCC-804)
+
+-------------------------------------------------------------------
 Mon Apr  6 15:40:58 UTC 2026 - Fergal Mc Carthy <[email protected]>
 
 - Update version to 1.22:
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/suseconnect-ng-1.22.0/build/packaging/suseconnect-ng.spec 
new/suseconnect-ng-1.22.1/build/packaging/suseconnect-ng.spec
--- old/suseconnect-ng-1.22.0/build/packaging/suseconnect-ng.spec       
2026-06-08 20:16:18.000000000 +0200
+++ new/suseconnect-ng-1.22.1/build/packaging/suseconnect-ng.spec       
2026-06-11 17:47:03.000000000 +0200
@@ -19,7 +19,7 @@
 %global project github.com/SUSE/connect-ng
 
 Name:           suseconnect-ng
-Version:        1.22.0
+Version:        1.22.1
 Release:        0
 URL:            https://github.com/SUSE/connect-ng
 License:        LGPL-3.0-or-later
@@ -100,6 +100,14 @@
 %description -n suseconnect-ruby-bindings
 This package provides bindings needed to use libsuseconnect from Ruby scripts.
 
+%package -n mcp-server-suseconnect
+Summary:        MCP server for suseconnect
+Group:          System/Management
+Requires:       suseconnect-ng = %version
+
+%description -n mcp-server-suseconnect
+This package provides an MCP server for suseconnect to enable integration into 
the agentic SLES framework.
+
 %prep
 %autosetup -p1 -a2 -n%{name}-%{version}
 
@@ -110,6 +118,7 @@
 go build -v -ldflags "-s -w" -mod=vendor -buildmode=pie -o 
bin/zypper-migration %{project}/cmd/zypper-migration
 go build -v -ldflags "-s -w" -mod=vendor -buildmode=pie -o 
bin/zypper-search-packages %{project}/cmd/zypper-search-packages
 go build -v -ldflags "-s -w" -mod=vendor -buildmode=pie -o 
bin/suse-uptime-tracker %{project}/cmd/suse-uptime-tracker
+go build -v -ldflags "-s -w" -mod=vendor -buildmode=pie -o bin/suseconnect-mcp 
%{project}/cmd/suseconnect-mcp
 
 # the library
 mkdir -p %_builddir/go/lib
@@ -118,8 +127,9 @@
 %install
 # Install binary + symlinks
 install -D -m 0755 bin/suseconnect %{buildroot}/%{_bindir}/suseconnect
-install -D -m 0755 bin/suse-uptime-tracker 
%{buildroot}/%{_bindir}/suse-uptime-tracker
 ln -s %{_bindir}/suseconnect %{buildroot}/%{_bindir}/SUSEConnect
+install -D -m 0755 bin/suse-uptime-tracker 
%{buildroot}/%{_bindir}/suse-uptime-tracker
+install -D -m 0755 bin/suseconnect-mcp %{buildroot}/%{_bindir}/suseconnect-mcp
 
 install -d -m 0755 %{buildroot}/%{_sbindir}
 ln -s %{_bindir}/suseconnect %{buildroot}/%{_sbindir}/SUSEConnect
@@ -249,4 +259,7 @@
 %doc third_party/yast/README.md
 %{_libdir}/ruby/vendor_ruby/%rb_ver/suse
 
+%files -n mcp-server-suseconnect
+%{_bindir}/suseconnect-mcp
+
 %changelog
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/suseconnect-ng-1.22.0/cmd/public-api-demo/main.go 
new/suseconnect-ng-1.22.1/cmd/public-api-demo/main.go
--- old/suseconnect-ng-1.22.0/cmd/public-api-demo/main.go       2026-06-08 
20:16:18.000000000 +0200
+++ new/suseconnect-ng-1.22.1/cmd/public-api-demo/main.go       2026-06-11 
17:47:03.000000000 +0200
@@ -42,6 +42,10 @@
                isProxy = true
        }
 
+       if disableTokens := os.Getenv("DISABLE_TOKEN_HANDLING"); disableTokens 
!= "" {
+               opts.DisableTokenHandling = true
+       }
+
        if credentialTracing := os.Getenv("TRACE_CREDENTIAL_UPDATES"); 
credentialTracing != "" {
                creds.ShowTraces = true
        }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/suseconnect-ng-1.22.0/cmd/suseconnect-mcp/suseconnect_mcp.go 
new/suseconnect-ng-1.22.1/cmd/suseconnect-mcp/suseconnect_mcp.go
--- old/suseconnect-ng-1.22.0/cmd/suseconnect-mcp/suseconnect_mcp.go    
2026-06-08 20:16:18.000000000 +0200
+++ new/suseconnect-ng-1.22.1/cmd/suseconnect-mcp/suseconnect_mcp.go    
2026-06-11 17:47:03.000000000 +0200
@@ -3,10 +3,8 @@
 import (
        "context"
        "errors"
-       "flag"
        "fmt"
        "log/slog"
-       "net/http"
        "os"
 
        "github.com/SUSE/connect-ng/internal/connect"
@@ -171,9 +169,6 @@
 }
 
 func main() {
-       listenAddr := flag.String("http", "", "address for http transport, 
defaults to stdio")
-       flag.Parse()
-
        if os.Geteuid() != 0 {
                fmt.Fprintln(os.Stderr, "Root privileges are required to run 
the MCP server.")
                os.Exit(1)
@@ -181,46 +176,68 @@
 
        server := mcp.NewServer(&mcp.Implementation{Name: "suseconnect", 
Version: "v0.0.1"}, nil)
 
+       // DestructiveHint is *bool (unset defaults to true); Go won't let us 
take &false.
+       ptr := func(b bool) *bool { return &b }
+
        mcp.AddTool(server, &mcp.Tool{
                Name:        "RegistrationStatus",
                Description: "Tool to output the registration status of the 
system and activated/non-activated installed products",
+               Annotations: &mcp.ToolAnnotations{
+                       Title:        "Show registration status",
+                       ReadOnlyHint: true,
+               },
        }, RegistrationStatus)
        mcp.AddTool(server, &mcp.Tool{
                Name:        "ListExtensions",
                Description: "List available extension products for your SUSE 
system. Your system's base product must be activated first.",
+               Annotations: &mcp.ToolAnnotations{
+                       Title:        "List available extensions",
+                       ReadOnlyHint: true,
+               },
        }, ListExtensions)
        mcp.AddTool(server, &mcp.Tool{
                Name:        "RegisterSystem",
                Description: "Registers and activates your SUSE system. This 
will enable access to online repositories and additional extensions and 
modules.",
+               Annotations: &mcp.ToolAnnotations{
+                       Title:           "Register system",
+                       ReadOnlyHint:    false,
+                       DestructiveHint: ptr(false),
+                       IdempotentHint:  false,
+               },
        }, RegisterSystem)
        mcp.AddTool(server, &mcp.Tool{
                Name:        "ActivateProduct",
                Description: "Activates and additional extension product or 
module on your SUSE system. Available extensions can get queried with the 
ListExtensions tool.",
+               Annotations: &mcp.ToolAnnotations{
+                       Title:           "Activate product",
+                       ReadOnlyHint:    false,
+                       DestructiveHint: ptr(false),
+                       IdempotentHint:  false,
+               },
        }, ActivateProduct)
        mcp.AddTool(server, &mcp.Tool{
                Name:        "DeregisterSystem",
                Description: "Deregisters your SUSE system. This will remove 
the system's registration and disable access to online repositories.",
+               Annotations: &mcp.ToolAnnotations{
+                       Title:           "Deregister system (destructive)",
+                       ReadOnlyHint:    false,
+                       DestructiveHint: ptr(true),
+                       IdempotentHint:  true,
+               },
        }, DeregisterSystem)
        mcp.AddTool(server, &mcp.Tool{
                Name:        "DeactivateProduct",
                Description: "Deactivates an extension product or module on 
your SUSE system.",
+               Annotations: &mcp.ToolAnnotations{
+                       Title:           "Deactivate product (destructive)",
+                       ReadOnlyHint:    false,
+                       DestructiveHint: ptr(true),
+                       IdempotentHint:  true,
+               },
        }, DeactivateProduct)
 
-       if *listenAddr == "" {
-               // Run the server on the stdio transport.
-               if err := server.Run(context.Background(), 
&mcp.StdioTransport{}); err != nil {
-                       slog.Error("Server failed", "error", err)
-               }
-       } else {
-               // Create a streamable HTTP handler.
-               handler := mcp.NewStreamableHTTPHandler(func(*http.Request) 
*mcp.Server {
-                       return server
-               }, nil)
-
-               // Run the server on the HTTP transport.
-               slog.Info("Server listening", "address", *listenAddr)
-               if err := http.ListenAndServe(*listenAddr, handler); err != nil 
{
-                       slog.Error("Server failed", "error", err)
-               }
+       // Run the server on the stdio transport.
+       if err := server.Run(context.Background(), &mcp.StdioTransport{}); err 
!= nil {
+               slog.Error("Server failed", "error", err)
        }
 }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/suseconnect-ng-1.22.0/internal/connect/cert_pool.go 
new/suseconnect-ng-1.22.1/internal/connect/cert_pool.go
--- old/suseconnect-ng-1.22.0/internal/connect/cert_pool.go     2026-06-08 
20:16:18.000000000 +0200
+++ new/suseconnect-ng-1.22.1/internal/connect/cert_pool.go     1970-01-01 
01:00:00.000000000 +0100
@@ -1,131 +0,0 @@
-// TODO: remove when https://github.com/golang/go/issues/41888 is fixed
-// code copied from standard library crypto/x509/root.go to enable system 
certs reloading
-
-package connect
-
-import (
-       "crypto/x509"
-       "io/fs"
-       "os"
-       "path/filepath"
-       "strings"
-)
-
-func systemRootsPool() *x509.CertPool {
-       systemRoots, systemRootsErr := _loadSystemRoots()
-       if systemRootsErr != nil {
-               return nil
-       }
-       return systemRoots
-}
-
-const (
-       // certFileEnv is the environment variable which identifies where to 
locate
-       // the SSL certificate file. If set this overrides the system default.
-       _certFileEnv = "SSL_CERT_FILE"
-
-       // certDirEnv is the environment variable which identifies which 
directory
-       // to check for SSL certificate files. If set this overrides the system 
default.
-       // It is a colon separated list of directories.
-       // See https://www.openssl.org/docs/man1.0.2/man1/c_rehash.html.
-       _certDirEnv = "SSL_CERT_DIR"
-)
-
-// Possible certificate files; stop after finding one.
-var _certFiles = []string{
-       "/etc/ssl/certs/ca-certificates.crt",                // 
Debian/Ubuntu/Gentoo etc.
-       "/etc/pki/tls/certs/ca-bundle.crt",                  // Fedora/RHEL 6
-       "/etc/ssl/ca-bundle.pem",                            // OpenSUSE
-       "/etc/pki/tls/cacert.pem",                           // OpenELEC
-       "/etc/pki/ca-trust/extracted/pem/tls-ca-bundle.pem", // CentOS/RHEL 7
-       "/etc/ssl/cert.pem",                                 // Alpine Linux
-}
-
-// Possible directories with certificate files; stop after successfully
-// reading at least one file from a directory.
-var _certDirectories = []string{
-       "/etc/ssl/certs",               // SLES10/SLES11, 
https://golang.org/issue/12139
-       "/etc/pki/tls/certs",           // Fedora/RHEL
-       "/system/etc/security/cacerts", // Android
-}
-
-func _loadSystemRoots() (*x509.CertPool, error) {
-       roots := x509.NewCertPool()
-       rootsLen := 0
-
-       files := _certFiles
-       if f := os.Getenv(_certFileEnv); f != "" {
-               files = []string{f}
-       }
-
-       var firstErr error
-       for _, file := range files {
-               data, err := os.ReadFile(file)
-               if err == nil {
-                       roots.AppendCertsFromPEM(data)
-                       rootsLen++
-                       break
-               }
-               if firstErr == nil && !os.IsNotExist(err) {
-                       firstErr = err
-               }
-       }
-
-       dirs := _certDirectories
-       if d := os.Getenv(_certDirEnv); d != "" {
-               // OpenSSL and BoringSSL both use ":" as the SSL_CERT_DIR 
separator.
-               // See:
-               //  * https://golang.org/issue/35325
-               //  * https://www.openssl.org/docs/man1.0.2/man1/c_rehash.html
-               dirs = strings.Split(d, ":")
-       }
-
-       for _, directory := range dirs {
-               fis, err := _readUniqueDirectoryEntries(directory)
-               if err != nil {
-                       if firstErr == nil && !os.IsNotExist(err) {
-                               firstErr = err
-                       }
-                       continue
-               }
-               for _, fi := range fis {
-                       data, err := os.ReadFile(directory + "/" + fi.Name())
-                       if err == nil {
-                               roots.AppendCertsFromPEM(data)
-                               rootsLen++
-                       }
-               }
-       }
-
-       if rootsLen > 0 || firstErr == nil {
-               return roots, nil
-       }
-
-       return nil, firstErr
-}
-
-// readUniqueDirectoryEntries is like os.ReadDir but omits
-// symlinks that point within the directory.
-func _readUniqueDirectoryEntries(dir string) ([]fs.DirEntry, error) {
-       files, err := os.ReadDir(dir)
-       if err != nil {
-               return nil, err
-       }
-       uniq := files[:0]
-       for _, f := range files {
-               if !_isSameDirSymlink(f, dir) {
-                       uniq = append(uniq, f)
-               }
-       }
-       return uniq, nil
-}
-
-// isSameDirSymlink reports whether fi in dir is a symlink with a
-// target not containing a slash.
-func _isSameDirSymlink(f fs.DirEntry, dir string) bool {
-       if f.Type()&fs.ModeSymlink == 0 {
-               return false
-       }
-       target, err := os.Readlink(filepath.Join(dir, f.Name()))
-       return err == nil && !strings.Contains(target, "/")
-}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/suseconnect-ng-1.22.0/pkg/connection/cert_pool.go 
new/suseconnect-ng-1.22.1/pkg/connection/cert_pool.go
--- old/suseconnect-ng-1.22.0/pkg/connection/cert_pool.go       1970-01-01 
01:00:00.000000000 +0100
+++ new/suseconnect-ng-1.22.1/pkg/connection/cert_pool.go       2026-06-11 
17:47:03.000000000 +0200
@@ -0,0 +1,134 @@
+// TODO: remove when https://github.com/golang/go/issues/41888 is fixed
+// code copied from standard library crypto/x509/root.go to enable system 
certs reloading
+
+package connection
+
+import (
+       "crypto/x509"
+       "io/fs"
+       "os"
+       "path/filepath"
+       "strings"
+
+       "github.com/SUSE/connect-ng/internal/util"
+)
+
+func systemRootsPool() *x509.CertPool {
+       systemRoots, systemRootsErr := _loadSystemRoots()
+       if systemRootsErr != nil {
+               util.Debug.Printf("Failed to load system roots: %s", 
systemRootsErr.Error())
+               return nil
+       }
+       return systemRoots
+}
+
+const (
+       // certFileEnv is the environment variable which identifies where to 
locate
+       // the SSL certificate file. If set this overrides the system default.
+       _certFileEnv = "SSL_CERT_FILE"
+
+       // certDirEnv is the environment variable which identifies which 
directory
+       // to check for SSL certificate files. If set this overrides the system 
default.
+       // It is a colon separated list of directories.
+       // See https://www.openssl.org/docs/man1.0.2/man1/c_rehash.html.
+       _certDirEnv = "SSL_CERT_DIR"
+)
+
+// Possible certificate files; stop after finding one.
+var _certFiles = []string{
+       "/etc/ssl/certs/ca-certificates.crt",                // 
Debian/Ubuntu/Gentoo etc.
+       "/etc/pki/tls/certs/ca-bundle.crt",                  // Fedora/RHEL 6
+       "/etc/ssl/ca-bundle.pem",                            // OpenSUSE
+       "/etc/pki/tls/cacert.pem",                           // OpenELEC
+       "/etc/pki/ca-trust/extracted/pem/tls-ca-bundle.pem", // CentOS/RHEL 7
+       "/etc/ssl/cert.pem",                                 // Alpine Linux
+}
+
+// Possible directories with certificate files; stop after successfully
+// reading at least one file from a directory.
+var _certDirectories = []string{
+       "/etc/ssl/certs",               // SLES10/SLES11, 
https://golang.org/issue/12139
+       "/etc/pki/tls/certs",           // Fedora/RHEL
+       "/system/etc/security/cacerts", // Android
+}
+
+func _loadSystemRoots() (*x509.CertPool, error) {
+       roots := x509.NewCertPool()
+       rootsLen := 0
+
+       files := _certFiles
+       if f := os.Getenv(_certFileEnv); f != "" {
+               files = []string{f}
+       }
+
+       var firstErr error
+       for _, file := range files {
+               data, err := os.ReadFile(file)
+               if err == nil {
+                       roots.AppendCertsFromPEM(data)
+                       rootsLen++
+                       break
+               }
+               if firstErr == nil && !os.IsNotExist(err) {
+                       firstErr = err
+               }
+       }
+
+       dirs := _certDirectories
+       if d := os.Getenv(_certDirEnv); d != "" {
+               // OpenSSL and BoringSSL both use ":" as the SSL_CERT_DIR 
separator.
+               // See:
+               //  * https://golang.org/issue/35325
+               //  * https://www.openssl.org/docs/man1.0.2/man1/c_rehash.html
+               dirs = strings.Split(d, ":")
+       }
+
+       for _, directory := range dirs {
+               fis, err := _readUniqueDirectoryEntries(directory)
+               if err != nil {
+                       if firstErr == nil && !os.IsNotExist(err) {
+                               firstErr = err
+                       }
+                       continue
+               }
+               for _, fi := range fis {
+                       data, err := os.ReadFile(directory + "/" + fi.Name())
+                       if err == nil {
+                               roots.AppendCertsFromPEM(data)
+                               rootsLen++
+                       }
+               }
+       }
+
+       if rootsLen > 0 || firstErr == nil {
+               return roots, nil
+       }
+
+       return nil, firstErr
+}
+
+// readUniqueDirectoryEntries is like os.ReadDir but omits
+// symlinks that point within the directory.
+func _readUniqueDirectoryEntries(dir string) ([]fs.DirEntry, error) {
+       files, err := os.ReadDir(dir)
+       if err != nil {
+               return nil, err
+       }
+       uniq := files[:0]
+       for _, f := range files {
+               if !_isSameDirSymlink(f, dir) {
+                       uniq = append(uniq, f)
+               }
+       }
+       return uniq, nil
+}
+
+// isSameDirSymlink reports whether fi in dir is a symlink with a
+// target not containing a slash.
+func _isSameDirSymlink(f fs.DirEntry, dir string) bool {
+       if f.Type()&fs.ModeSymlink == 0 {
+               return false
+       }
+       target, err := os.Readlink(filepath.Join(dir, f.Name()))
+       return err == nil && !strings.Contains(target, "/")
+}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/suseconnect-ng-1.22.0/pkg/connection/connection.go 
new/suseconnect-ng-1.22.1/pkg/connection/connection.go
--- old/suseconnect-ng-1.22.0/pkg/connection/connection.go      2026-06-08 
20:16:18.000000000 +0200
+++ new/suseconnect-ng-1.22.1/pkg/connection/connection.go      2026-06-11 
17:47:03.000000000 +0200
@@ -9,6 +9,8 @@
        "io"
        "net/http"
        "strings"
+
+       "github.com/SUSE/connect-ng/internal/util"
 )
 
 const (
@@ -86,11 +88,19 @@
 }
 
 func (conn ApiConnection) Do(request *http.Request) ([]byte, error) {
-       token, tokenErr := conn.Credentials.Token()
-       if tokenErr != nil {
-               return []byte{}, tokenErr
+
+       // Allow clients to disable token handling completely if they
+       // do not need duplicate detection. This is the case for the
+       // scc-operator (https://github.com/rancher/scc-operator/)
+       rotateToken := conn.Options.DisableTokenHandling == false
+
+       if rotateToken == true {
+               token, tokenErr := conn.Credentials.Token()
+               if tokenErr != nil {
+                       return []byte{}, tokenErr
+               }
+               request.Header.Set("System-Token", token)
        }
-       request.Header.Set("System-Token", token)
 
        response, doErr := conn.setupHTTPClient().Do(request)
        if doErr != nil {
@@ -99,9 +109,11 @@
        defer response.Body.Close()
 
        // Update the credentials from the new system token.
-       token = response.Header.Get("System-Token")
-       if err := conn.Credentials.UpdateToken(token); err != nil {
-               return nil, err
+       if rotateToken == true {
+               token := response.Header.Get("System-Token")
+               if err := conn.Credentials.UpdateToken(token); err != nil {
+                       return nil, err
+               }
        }
 
        // Check if there was an error from the given API response.
@@ -149,12 +161,30 @@
                transport.Proxy = conn.Options.Proxy
        }
 
+       // retrieve current system root certs pool; this ensures any new certs
+       // added since x509.SystemCertPool() was first initialised are included
+       // TODO: rework if https://github.com/golang/go/issues/41888 is resolved
+       pool := systemRootsPool()
+
+       // if we fail to retrieve the latest systemRootsPoll fall back on using
+       // a clone of the x509.SystemCertPool(), otherwise use a new empty pool.
+       if pool == nil {
+               systemPool, err := x509.SystemCertPool()
+               if err == nil {
+                       pool = systemPool.Clone()
+               } else {
+                       util.Debug.Printf("Failed to retrieve 
x509.SystemCertPool(): %s", err.Error())
+                       pool = x509.NewCertPool()
+               }
+       }
+
+       // if a cert has been provided add it to the pool
        if conn.Options.Certificate != nil {
-               pool := x509.NewCertPool()
                pool.AddCert(conn.Options.Certificate)
-
-               transport.TLSClientConfig.RootCAs = pool
        }
 
+       // use the pool for handling TLS certs
+       transport.TLSClientConfig.RootCAs = pool
+
        return &http.Client{Transport: transport, Timeout: conn.Options.Timeout}
 }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/suseconnect-ng-1.22.0/pkg/connection/connection_test.go 
new/suseconnect-ng-1.22.1/pkg/connection/connection_test.go
--- old/suseconnect-ng-1.22.0/pkg/connection/connection_test.go 2026-06-08 
20:16:18.000000000 +0200
+++ new/suseconnect-ng-1.22.1/pkg/connection/connection_test.go 2026-06-11 
17:47:03.000000000 +0200
@@ -228,6 +228,34 @@
        creds.AssertExpectations(t)
 }
 
+func TestConnectionTokenDisabled(t *testing.T) {
+       assert := assert.New(t)
+
+       handler := func(response http.ResponseWriter) {
+               response.WriteHeader(http.StatusOK)
+       }
+
+       server := NewTestServerSetupWith(t, "GET", "/test/api", handler)
+       defer server.Close()
+
+       opts := DefaultOptions("testApp", "1.0", "en_US")
+       opts.URL = server.URL
+       opts.DisableTokenHandling = true
+
+       creds := &MockCredentials{}
+       conn := New(opts, creds)
+
+       request, buildErr := conn.BuildRequest("GET", "/test/api", "")
+       assert.NoError(buildErr)
+
+       _, doErr := conn.Do(request)
+       assert.NoError(doErr)
+
+       creds.AssertNotCalled(t, "Token")
+       creds.AssertNotCalled(t, "UpdateToken")
+       creds.AssertExpectations(t)
+}
+
 func TestCustomCertificateSuccess(t *testing.T) {
        assert := assert.New(t)
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/suseconnect-ng-1.22.0/pkg/connection/options.go 
new/suseconnect-ng-1.22.1/pkg/connection/options.go
--- old/suseconnect-ng-1.22.0/pkg/connection/options.go 2026-06-08 
20:16:18.000000000 +0200
+++ new/suseconnect-ng-1.22.1/pkg/connection/options.go 2026-06-11 
17:47:03.000000000 +0200
@@ -49,16 +49,20 @@
 
        // Timeout on how long to wait for an API response
        Timeout time.Duration
+
+       // Disable Token handling
+       DisableTokenHandling bool
 }
 
 // Returns the Options suitable for targeting the SCC reference server.
 func DefaultOptions(appName, version, language string) Options {
        return Options{
-               URL:              DefaultBaseURL,
-               Secure:           true,
-               AppName:          appName,
-               Version:          version,
-               PreferedLanguage: language,
-               Timeout:          DefaultTimeout,
+               URL:                  DefaultBaseURL,
+               Secure:               true,
+               AppName:              appName,
+               Version:              version,
+               PreferedLanguage:     language,
+               Timeout:              DefaultTimeout,
+               DisableTokenHandling: false,
        }
 }

++++++ vendor.tar.xz ++++++

Reply via email to