Icinga / icinga2

The core of our monitoring platform with a powerful configuration language and REST API.
https://icinga.com/docs/icinga2/latest
GNU General Public License v2.0
2.03k stars 578 forks source link

Error: boost::bad_any_cast: failed conversion using boost::any_cast #6178

Closed bodsch closed 6 years ago

bodsch commented 6 years ago

I can't use the new feature to create hashed passwords. Every call with various parameters died with critical/Application: Error: boost::bad_any_cast: failed conversion using boost::any_cast


As an example here is a corresponding call. The named crash-report are not exists.

/etc/icinga2 # icinga2 api user --user foo --password bar --salt aaaaa --oneline
critical/Application: Error: boost::bad_any_cast: failed conversion using boost::any_cast

Additional information is available in '/var/log/icinga2/crash/report.1521797967.126665'

Aborted
/etc/icinga2 # cat /var/log/icinga2/crash/report.1521797967.126665
cat: can't open '/var/log/icinga2/crash/report.1521797967.126665': No such file or directory
/etc/icinga2 # 

Context

Your Environment

Copyright (c) 2012-2017 Icinga Development Team (https://www.icinga.com/) License GPLv2+: GNU GPL version 2 or later http://gnu.org/licenses/gpl2.html This is free software: you are free to change and redistribute it. There is NO WARRANTY, to the extent permitted by law.

Application information: Installation root: /usr Sysconf directory: /etc Run directory: /run Local state directory: /var Package data directory: /usr/share/icinga2 State path: /var/lib/icinga2/icinga2.state Modified attributes path: /var/lib/icinga2/modified-attributes.conf Objects path: /var/cache/icinga2/icinga2.debug Vars path: /var/cache/icinga2/icinga2.vars PID path: /run/icinga2/icinga2.pid

System information: Platform: Alpine Linux Platform version: Unknown Kernel: Linux Kernel version: 4.9.76-gentoo-r1 Architecture: x86_64

Build information: Compiler: GNU 6.4.0 Build host: 78f183f2e840

* Operating System and version:

cat /etc/alpine-release 3.7.0

* Enabled features (`icinga2 feature list`):

icinga2 feature list

Disabled features: api checker command compatlog debuglog elasticsearch gelf graphite ido-mysql ido-pgsql influxdb livestatus mainlog notification opentsdb perfdata statusdata syslog Enabled features:

* Config validation (`icinga2 daemon -C`):

icinga2 daemon -C

information/cli: Icinga application loader (version: r2.8.2-1) information/cli: Loading configuration file(s). information/ConfigItem: Committing config item(s). information/ConfigItem: Instantiated 3 Zones. information/ConfigItem: Instantiated 1 Endpoint. information/ConfigItem: Instantiated 3 ServiceGroups. information/ConfigItem: Instantiated 12 Notifications. information/ConfigItem: Instantiated 2 NotificationCommands. information/ConfigItem: Instantiated 209 CheckCommands. information/ConfigItem: Instantiated 1 IcingaApplication. information/ConfigItem: Instantiated 1 Host. information/ConfigItem: Instantiated 2 HostGroups. information/ConfigItem: Instantiated 1 UserGroup. information/ConfigItem: Instantiated 3 TimePeriods. information/ConfigItem: Instantiated 1 User. information/ConfigItem: Instantiated 11 Services. information/ConfigItem: Instantiated 1 ScheduledDowntime. information/ScriptGlobal: Dumping variables to file '/var/cache/icinga2/icinga2.vars' information/cli: Finished validating the configuration file(s).


I tried the boost library of alpine (`1.62.0`) and a self compiled (`1.66.0`) version.
Icinga2 itself is self compiled with the following parameters:

cmake .. \ -DCMAKE_VERBOSE_MAKEFILE=OFF \ -DCMAKE_BUILD_TYPE=None \ -DCMAKE_INSTALL_PREFIX=/usr \ -DCMAKE_INSTALL_SYSCONFDIR=/etc \ -DCMAKE_INSTALL_SBINDIR=/usr/sbin \ -DCMAKE_INSTALL_LIBDIR=/usr/lib \ -DCMAKE_INSTALL_LOCALSTATEDIR=/var \ -DICINGA2_WITH_COMPAT=ON \ -DICINGA2_WITH_LIVESTATUS=ON \ -DICINGA2_GIT_VERSION_INFO=OFF \ -DICINGA2_RUNDIR=/run \ -DICINGA2_SYSCONFIGFILE=/etc/icinga2 \ -DICINGA2_PLUGINDIR=/usr/lib/monitoring-plugins \ -DICINGA2_UNITY_BUILD=FALSE \ -DICINGA2_LTO_BUILD=OFF && \


----
I hope, these Information helps.
dnsmichi commented 6 years ago

@Crunsher

Only support/2.8 has this problem, git master is fine.

michi@mbmif ~/coding/icinga/icinga2 (support/2.8=) $ sudo icinga2 api user --user foo --password bar
critical/Application: Error: boost::bad_any_cast: failed conversion using boost::any_cast

Additional information is available in '/usr/local/icinga2/var/log/icinga2/crash/report.1521802662.187690'

Abort trap: 6
mbmif ~ # lldb -- icinga2 api user --user foo --password bar
(lldb) target create "icinga2"
error: '/usr/local/icinga2/sbin/icinga2' doesn't contain any 'host' platform architectures: x86_64h, x86_64, i386
(lldb) ^D
mbmif ~ # lldb -- /usr/local/icinga2/lib/icinga2/sbin/icinga2 api user --user foo --password bar
(lldb) target create "/usr/local/icinga2/lib/icinga2/sbin/icinga2"
Current executable set to '/usr/local/icinga2/lib/icinga2/sbin/icinga2' (x86_64).
(lldb) settings set -- target.run-args  "api" "user" "--user" "foo" "--password" "bar"
(lldb) r
Process 93486 launched: '/usr/local/icinga2/lib/icinga2/sbin/icinga2' (x86_64)
critical/Application: Error: boost::bad_any_cast: failed conversion using boost::any_cast

Additional information is available in '/usr/local/icinga2/var/log/icinga2/crash/report.1521802899.251752'

libc++abi.dylib: terminate_handler unexpectedly threw an exception
Process 93486 stopped
* thread #1, queue = 'com.apple.main-thread', stop reason = signal SIGABRT
    frame #0: 0x00007fff6be43e3e libsystem_kernel.dylib`__pthread_kill + 10
libsystem_kernel.dylib`__pthread_kill:
->  0x7fff6be43e3e <+10>: jae    0x7fff6be43e48            ; <+20>
    0x7fff6be43e40 <+12>: movq   %rax, %rdi
    0x7fff6be43e43 <+15>: jmp    0x7fff6be3b0b8            ; cerror_nocancel
    0x7fff6be43e48 <+20>: retq
Target 0: (icinga2) stopped.
(lldb) up
frame #1: 0x00007fff6bf82150 libsystem_pthread.dylib`pthread_kill + 333
libsystem_pthread.dylib`pthread_kill:
    0x7fff6bf82150 <+333>: movl   %eax, %r15d
    0x7fff6bf82153 <+336>: cmpl   $-0x1, %r15d
    0x7fff6bf82157 <+340>: jne    0x7fff6bf82161            ; <+350>
    0x7fff6bf82159 <+342>: callq  0x7fff6bf8519c            ; symbol stub for: __error
(lldb)
frame #2: 0x00007fff6bda0312 libsystem_c.dylib`abort + 127
libsystem_c.dylib`abort:
    0x7fff6bda0312 <+127>: movl   $0x2710, %edi             ; imm = 0x2710
    0x7fff6bda0317 <+132>: callq  0x7fff6bd728e4            ; usleep$NOCANCEL
    0x7fff6bda031c <+137>: callq  0x7fff6bda0321            ; __abort

libsystem_c.dylib`__abort:
    0x7fff6bda0321 <+0>:   cmpq   $0x0, 0x38f8ae1f(%rip)    ; gCRAnnotations + 7
(lldb)
frame #3: 0x00007fff69d7bf8f libc++abi.dylib`abort_message + 245
libc++abi.dylib`__cxa_bad_cast:
    0x7fff69d7bf8f <+0>: pushq  %rbp
    0x7fff69d7bf90 <+1>: movq   %rsp, %rbp
    0x7fff69d7bf93 <+4>: pushq  %rbx
    0x7fff69d7bf94 <+5>: pushq  %rax
(lldb)
frame #4: 0x00007fff69d977ed libc++abi.dylib`std::__terminate(void (*)()) + 44
libc++abi.dylib`std::__terminate:
    0x7fff69d977ed <+44>: movq   %rax, %rbx
    0x7fff69d977f0 <+47>: callq  0x7fff69d97304            ; __cxa_end_catch
    0x7fff69d977f5 <+52>: movq   %rbx, %rdi
    0x7fff69d977f8 <+55>: callq  0x7fff69d7b690            ; __clang_call_terminate
(lldb)
frame #5: 0x00007fff69d9726d libc++abi.dylib`__cxa_throw + 121
libc++abi.dylib`__cxxabiv1::exception_cleanup_func:
    0x7fff69d9726d <+0>: cmpl   $0x1, %edi
    0x7fff69d97270 <+3>: jne    0x7fff69d9727e            ; <+17>
    0x7fff69d97272 <+5>: addq   $0x20, %rsi
    0x7fff69d97276 <+9>: movq   %rsi, %rdi
(lldb)
frame #6: 0x00000001010fc8a5 libbase.2.8.2.dylib`::__cxa_throw(obj=0x0000000101b09e48, pvtinfo=0x000000010003f7e0, dest=(libcli.2.8.2.dylib`boost::exception_detail::clone_impl<boost::exception_detail::error_info_injector<boost::bad_any_cast> >::~clone_impl() at exception.hpp:485))(void *)) at exception.cpp:144
   141          *ex << ContextTraceErrorInfo(context);
   142  #endif /* NO_CAST_EXCEPTION */
   143
-> 144      real_cxa_throw(obj, tinfo, dest);
   145  }
   146  #endif /* HAVE_CXXABI_H */
   147
(lldb)
frame #7: 0x0000000100386bc2 libcli.2.8.2.dylib`void boost::throw_exception<boost::bad_any_cast>(e=0x00007ffeefbfab88) at throw_exception.hpp:69
   66       throw_exception_assert_compatibility(e);
   67
   68   #ifndef BOOST_EXCEPTION_DISABLE
-> 69       throw enable_current_exception(enable_error_info(e));
   70   #else
   71       throw e;
   72   #endif
(lldb)
frame #8: 0x000000010039636d libcli.2.8.2.dylib`std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const& boost::any_cast<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&>(operand=0x000000010018d610) at any.hpp:268
   265
   266          nonref * result = any_cast<nonref>(boost::addressof(operand));
   267          if(!result)
-> 268              boost::throw_exception(bad_any_cast());
   269
   270          // Attempt to avoid construction of a temporary object in cases when
   271          // `ValueType` is not a reference. Example:
(lldb)
frame #9: 0x0000000100396315 libcli.2.8.2.dylib`std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const& boost::any_cast<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&>(operand=0x000000010018d610) at any.hpp:294
   291      inline ValueType any_cast(const any & operand)
   292      {
   293          typedef BOOST_DEDUCED_TYPENAME remove_reference<ValueType>::type nonref;
-> 294          return any_cast<const nonref &>(const_cast<any &>(operand));
   295      }
   296
   297  #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
(lldb)
frame #10: 0x000000010037ba45 libcli.2.8.2.dylib`std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const& boost::program_options::variable_value::as<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > >(this=0x000000010018d610) const at variables_map.hpp:69
   66               throws boost::bad_any_cast exception. */
   67          template<class T>
   68          const T& as() const {
-> 69              return boost::any_cast<const T&>(v);
   70          }
   71          /** @overload */
   72          template<class T>
(lldb)
frame #11: 0x000000010043232b libcli.2.8.2.dylib`icinga::ApiUserCommand::Run(this=0x0000000101c128c0, vm=0x00007ffeefbfdf68, ap=size=1) const at apiusercommand.cpp:71
   68           return 1;
   69       }
   70
-> 71       passwd = vm["passwd"].as<std::string>();
   72       salt = vm.count("salt") ? String(vm["salt"].as<std::string>()) : RandomString(8);
   73
   74       if (salt.FindFirstOf('$') != String::NPos) {
dnsmichi commented 6 years ago
michi@mbmif ~/coding/icinga/icinga2 (support/2.8=) $ git diff master lib/cli/apiusercommand.cpp
diff --git a/lib/cli/apiusercommand.cpp b/lib/cli/apiusercommand.cpp
index 5bd77ab89..188691ae0 100644
--- a/lib/cli/apiusercommand.cpp
+++ b/lib/cli/apiusercommand.cpp
@@ -56,18 +56,19 @@ void ApiUserCommand::InitParameters(boost::program_options::options_description&
  */
 int ApiUserCommand::Run(const boost::program_options::variables_map& vm, const std::vector<std::string>& ap) const
 {
-       String passwd, salt;
+       String user, passwd, salt;
        if (!vm.count("user") && !vm.count("oneline")) {
                Log(LogCritical, "cli", "Username (--user) must be specified.");
                return 1;
-       }
+       } else
+               user = vm["user"].as<std::string>();

        if (!vm.count("password")) {
                Log(LogCritical, "cli", "Password (--password) must be specified.");
                return 1;
        }

-       passwd = vm["password"].as<std::string>();
+       passwd = vm["passwd"].as<std::string>();
        salt = vm.count("salt") ? String(vm["salt"].as<std::string>()) : RandomString(8);

        if (salt.FindFirstOf('$') != String::NPos) {
@@ -82,11 +83,11 @@ int ApiUserCommand::Run(const boost::program_options::variables_map& vm, const s
        }

        if (vm.count("oneline"))
-               std::cout << hashedPassword << std::endl;
+               std::cout << '"' << hashedPassword << "\"\n";
        else {
                std::cout << "object ApiUser ";

-               ConfigWriter::EmitString(std::cout, vm["user"].as<std::string>());
+               ConfigWriter::EmitString(std::cout, user);

                std::cout << "{\n"
                        << "  password_hash = ";
dnsmichi commented 6 years ago
commit 54384528edc23fa913b7807ca50f93456f80e1da
Author: Jean Flach <jean-marcel.flach@icinga.com>
Date:   Tue Feb 20 09:45:55 2018 +0100

    Fix crash in api user command

wasn't backported. Cherry-picked and compiled:

mbmif ~ # lldb -- /usr/local/icinga2/lib/icinga2/sbin/icinga2 api user --user foo --password bar
(lldb) target create "/usr/local/icinga2/lib/icinga2/sbin/icinga2"
Current executable set to '/usr/local/icinga2/lib/icinga2/sbin/icinga2' (x86_64).
(lldb) settings set -- target.run-args  "api" "user" "--user" "foo" "--password" "bar"
(lldb) r
Process 96129 launched: '/usr/local/icinga2/lib/icinga2/sbin/icinga2' (x86_64)
object ApiUser "foo"{
  password_hash = "$5$daaa7cfca40627f2$7f406ef2e1cad1e759e3b0209b4db7a4f5d44778dbad7b0eda502c2e28b1bc0a"
  // client_cn = ""

  permissions = [ "*" ]
}
Process 96129 exited with status = 0 (0x00000000)
Crunsher commented 6 years ago

Damn, 2.8.3?

dnsmichi commented 6 years ago

Most likely, I've merged and backported 2 doc issues too. But not today, @bodsch can test the support branch in his containers where he's building from source anyways. Next week we can decide what to do.

Note: This is a new feature in a bugfix release, an exception for security related stuff. Testing workflow for bugfix releases doesn't include looking at new features.

bodsch commented 6 years ago

yes, i can do that. i modify my project ... fastly. :)

dnsmichi commented 6 years ago

No hurry, as said this is a new optional feature shipped within a bugfix release. It doesn't harm any existing environment nor breaks an upgrade.

bodsch commented 6 years ago

my build are successfully

Copyright (c) 2012-2017 Icinga Development Team (https://www.icinga.com/) License GPLv2+: GNU GPL version 2 or later http://gnu.org/licenses/gpl2.html This is free software: you are free to change and redistribute it. There is NO WARRANTY, to the extent permitted by law.

Application information: Installation root: /usr Sysconf directory: /etc Run directory: /run Local state directory: /var Package data directory: /usr/share/icinga2 State path: /var/lib/icinga2/icinga2.state Modified attributes path: /var/lib/icinga2/modified-attributes.conf Objects path: /var/cache/icinga2/icinga2.debug Vars path: /var/cache/icinga2/icinga2.vars PID path: /run/icinga2/icinga2.pid

System information: Platform: Alpine Linux Platform version: Unknown Kernel: Linux Kernel version: 4.9.76-gentoo-r1 Architecture: x86_64

Build information: Compiler: GNU 6.4.0 Build host: afb79def2208


- Operating System and version:

cat /etc/alpine-release 3.7.0

- Enabled features (`icinga2 feature list`):

icinga2 feature list

Disabled features: api checker command compatlog debuglog elasticsearch gelf graphite ido-mysql ido-pgsql influxdb livestatus mainlog notification opentsdb perfdata statusdata syslog Enabled features:


and it works:

icinga2 api user --user foo --password bar --oneline --salt 0001

$5$0001$86631e52c40fadf0917a5aed97979e54f95fc41c509fa546200b46010369cb70 /etc/icinga2 # icinga2 api user --user foo --password bar --salt 0001 object ApiUser "foo"{ password_hash = "$5$0001$86631e52c40fadf0917a5aed97979e54f95fc41c509fa546200b46010369cb70" // client_cn = ""

permissions = [ "*" ] }

dnsmichi commented 6 years ago

I'm assigning 2.8.3 here, as this only affects support/2.8. Depending on release plans, either a bugfix version is released or 2.9 which doesn't have that problem.

kitokirisaki commented 6 years ago

@dnsmichi, when will the build come to the icinga repositories?

Crunsher commented 6 years ago

There is currently no release date for 2.8.3

kitokirisaki commented 6 years ago

Can I enter the password directly in the file, or how can I set the currently?

Crunsher commented 6 years ago

Yes, you can still write config directly. Just using 'password' accepts clear text passwords. And you can use mkpasswd -m sha-256 from the command line to create a hashed password string.

Authentication still works, it's only the password creation CLI tool for hashed strings that's broken.

dnsmichi commented 6 years ago

Just use icinga2 api setup like before to generate a random ApiUser object. The issue is about a new optional feature.