SlideShare a Scribd company logo
Solid C++ code by example
                                         olve.maudal@tandberg.com

    Sometimes you see code that is perfectly OK according to the definition of the language,
    but which is flawed because it breaks too many established idioms and conventions. On
    the other hand, a solid piece of code is something that looks like it is written by an
    experienced person who cares about professionalism in programming.

    This will be an interactive discussion about good vs bad C++ code. We will discuss
    simple C++ idioms and coding conventions, but we will also touch upon best practices
    when working with C++ in large codebases with lots of developers with mixed skills.




           A presentation at Norwegian Developer Conference 2010
                       Track 7 (1140-1240) June 17, 2010

Disclaimer: there are some issues that we do not address properly here (at least 3). They are left as an exercise for the reader. Email
me if you find them, or if you want to know more!
~/myprog/foo.hpp
namespace bar {
  class Foo {
     int _value;
     int my_magic(int a, int b);
  public:
     Foo(int seed);
     int calc(int number = 7);
     int getValue() {
       return _value;
     }
     void print(char* prefix);
  };
}
~/myprog/foo.hpp
namespace bar {
  class Foo {
     int _value;
     int my_magic(int a, int b);
  public:
     Foo(int seed);
     int calc(int number = 7);
     int getValue() {
       return _value;
     }
     void print(char* prefix);
  };
}
~/myprog/foo.hpp
namespace bar {
  class Foo {          Solid code?
     int _value;
     int my_magic(int a, int b);
  public:
     Foo(int seed);
     int calc(int number = 7);
     int getValue() {
       return _value;
     }
     void print(char* prefix);
  };
}
~/myprog/foo.hpp
namespace bar {
  class Foo {
     int _value;
     int my_magic(int a, int b);
  public:
     Foo(int seed);
     int calc(int number = 7);
     int getValue() {
       return _value;
     }
     void print(char* prefix);
  };
}
~/myprog/foo.hpp
namespace bar {
  class Foo {          Bad code?
     int _value;
     int my_magic(int a, int b);
  public:
     Foo(int seed);
     int calc(int number = 7);
     int getValue() {
       return _value;
     }
     void print(char* prefix);
  };
}
~/myprog/foo.hpp
namespace bar {
  class Foo {
     int _value;
     int my_magic(int a, int b);
  public:
     Foo(int seed);
     int calc(int number = 7);
     int getValue() {
       return _value;
     }
     void print(char* prefix);
  };
}
PAL - a Primitive Authentication Library in C++ for educational purposes

                                    http://github.com/olvemaudal/pal


(from the README file)

Here is the main "use story":

As a client, when prompted for ntlm authentication by the server, I want a tool/library that can help me
to create the initial ntlm request (type 1 message) that I can send to the server to receive a challenge
(type 2 message) that needs to be solved by applying my username and password to create an ntlm
response that I can send to the server. (phew...)

Here are some (imaginary) additional requirements:
- must be in C or C++, since embeeded
- it should be possible and convenient to create a <100kb client using the PAL library
- must use C++ (due to PHB decision)
- must use nothing but C++ 1998 (due to compiler support, eg tr1 or boost can not be used)
- initally the library will only be used to communicate HTTP with a Windows 2003 Server SP2,
  currently no need to support other servers
Issues discussed here
1. base classes should have virtual destructors
2. header files should have header guards
3. make sure you include the proper header files, especially in header files
4. no need to include files included by the base class declaration
5. single argument constructors should be specified as explicit
6. focus on usage of class; public stuff first, then private stuff
7. always focus on readability, you spend more time reading code than writing it
8. importing a namespace in implementation files is usually not a good idea
9. "never" import a namespace in a header file
10. initialize objects properly, use the initialization list
11. prefer std::size_t when working with memory indexing and offsets
12. for non-trivial objects, prefer pass by const over pass by copy
13. query methods should be specified as const
14. order the include files like this; own, project/platform, standard
15. avoid magic numbers, use explaination variables
16. avoid superfluous use of ()
17. prefer forward declarations when you can
18. do not use explicit on multi argument constructors
19. consider explainability, don't do things that needs elaborate explainations
20. avoid default arguments (they are often not used anyway)
21. do not throw pointers to exceptions (eg, not "throw new ...")
22. treat warnings like errors (-Werror) and compile with high warning levels (-Wall -Wextra)
23. consider using -Weffc++ and -pedantic as well
24. do not mess with borrowed things
25. always consider the sideeffects of what you do
ntlm_message.hpp
#include <vector>

namespace pal {

    class ntlm_message {
    public:
        virtual std::vector<uint8_t> as_bytes() const = 0;
    };

}
Find 3 issues
#include <vector>

namespace pal {

    class ntlm_message {
    public:
        virtual std::vector<uint8_t> as_bytes() const = 0;
    };

}
#include <vector>

namespace pal {

    class ntlm_message {
    public:
        virtual std::vector<uint8_t> as_bytes() const = 0;
    };

}
#include <vector>

namespace pal {

    class ntlm_message {
    public:
        virtual std::vector<uint8_t> as_bytes() const = 0;
    };

}




    WTF? This class must have a
       virtual destructor!
#include <vector>

namespace pal {

    class ntlm_message {
    public:
        virtual std::vector<uint8_t> as_bytes() const = 0;
    };

}
#include <vector>

namespace pal {

    class ntlm_message {
    public:
        virtual std::vector<uint8_t> as_bytes() const = 0;
    };

}



         missing header guard
#include <vector>

namespace pal {

    class ntlm_message {
    public:
        virtual std::vector<uint8_t> as_bytes() const = 0;
    };

}
#include <vector>

namespace pal {

    class ntlm_message {
    public:
        virtual std::vector<uint8_t> as_bytes() const = 0;
    };

}



      should include <stdint.h>
#include <vector>

namespace pal {

    class ntlm_message {
    public:
        virtual std::vector<uint8_t> as_bytes() const = 0;
    };

}
#ifndef PAL_NTLM_MESSAGE_HPP_INCLUDED
#define PAL_NTLM_MESSAGE_HPP_INCLUDED

#include <vector>

namespace pal {

    class ntlm_message {
    public:
        virtual std::vector<uint8_t> as_bytes() const = 0;
    };

}

#endif
#ifndef PAL_NTLM_MESSAGE_HPP_INCLUDED
#define PAL_NTLM_MESSAGE_HPP_INCLUDED

#include <vector>

namespace pal {

    class ntlm_message {
    public:

         virtual std::vector<uint8_t> as_bytes() const = 0;
    };

}

#endif
#ifndef PAL_NTLM_MESSAGE_HPP_INCLUDED
#define PAL_NTLM_MESSAGE_HPP_INCLUDED

#include <vector>

namespace pal {

    class ntlm_message {
    public:
        virtual ~ntlm_message() {}
        virtual std::vector<uint8_t> as_bytes() const = 0;
    };

}

#endif
#ifndef PAL_NTLM_MESSAGE_HPP_INCLUDED
#define PAL_NTLM_MESSAGE_HPP_INCLUDED


#include <vector>

namespace pal {

    class ntlm_message {
    public:
        virtual ~ntlm_message() {}
        virtual std::vector<uint8_t> as_bytes() const = 0;
    };

}

#endif
#ifndef PAL_NTLM_MESSAGE_HPP_INCLUDED
#define PAL_NTLM_MESSAGE_HPP_INCLUDED

#include <stdint.h>
#include <vector>

namespace pal {

    class ntlm_message {
    public:
        virtual ~ntlm_message() {}
        virtual std::vector<uint8_t> as_bytes() const = 0;
    };

}

#endif
#ifndef PAL_NTLM_MESSAGE_HPP_INCLUDED
#define PAL_NTLM_MESSAGE_HPP_INCLUDED

#include <stdint.h>
#include <vector>

namespace pal {

    class ntlm_message {
    public:
        virtual ~ntlm_message() {}
        virtual std::vector<uint8_t> as_bytes() const = 0;
    };

}

#endif
#ifndef PAL_NTLM_MESSAGE_HPP_INCLUDED
#define PAL_NTLM_MESSAGE_HPP_INCLUDED

#include <stdint.h>
#include <vector>

namespace pal {

    class ntlm_message {
    public:
        virtual ~ntlm_message() {}
        virtual std::vector<uint8_t> as_bytes() const = 0;
    };

}

#endif        This is Solid C++!
type1_message.hpp
#ifndef PAL_TYPE1_MESSAGE_HPP_INCLUDED
#define PAL_TYPE1_MESSAGE_HPP_INCLUDED

#include "ntlm_message.hpp"

#include <vector>

namespace pal {

    class type1_message : public ntlm_message {
        uint32_t ssp_flags_;
    public:
        type1_message(uint32_t ssp_flags);
        virtual std::vector<uint8_t> as_bytes() const;
    };

}

#endif
#ifndef PAL_TYPE1_MESSAGE_HPP_INCLUDED
#define PAL_TYPE1_MESSAGE_HPP_INCLUDED

#include "ntlm_message.hpp"

#include <vector>

namespace pal {

    class type1_message : public ntlm_message {
        uint32_t ssp_flags_;
    public:
        type1_message(uint32_t ssp_flags);
        virtual std::vector<uint8_t> as_bytes() const;
    };

}

#endif
                                         Find 3 issues
#ifndef PAL_TYPE1_MESSAGE_HPP_INCLUDED
#define PAL_TYPE1_MESSAGE_HPP_INCLUDED

#include "ntlm_message.hpp"

#include <vector>

namespace pal {

    class type1_message : public ntlm_message {
        uint32_t ssp_flags_;
    public:
        type1_message(uint32_t ssp_flags);
        virtual std::vector<uint8_t> as_bytes() const;
    };

}

#endif
#ifndef PAL_TYPE1_MESSAGE_HPP_INCLUDED
#define PAL_TYPE1_MESSAGE_HPP_INCLUDED

#include "ntlm_message.hpp"

#include <vector>

namespace pal {

    class type1_message : public ntlm_message {
        uint32_t ssp_flags_;
    public:
        type1_message(uint32_t ssp_flags);
        virtual std::vector<uint8_t> as_bytes() const;
    };

}

#endif            no need to include
                   <vector> again
#ifndef PAL_TYPE1_MESSAGE_HPP_INCLUDED
#define PAL_TYPE1_MESSAGE_HPP_INCLUDED

#include "ntlm_message.hpp"

#include <vector>

namespace pal {

    class type1_message : public ntlm_message {
        uint32_t ssp_flags_;
    public:
        type1_message(uint32_t ssp_flags);
        virtual std::vector<uint8_t> as_bytes() const;
    };

}

#endif
#ifndef PAL_TYPE1_MESSAGE_HPP_INCLUDED
#define PAL_TYPE1_MESSAGE_HPP_INCLUDED

#include "ntlm_message.hpp"

#include <vector>

namespace pal {

    class type1_message : public ntlm_message {
        uint32_t ssp_flags_;
    public:
        type1_message(uint32_t ssp_flags);
        virtual std::vector<uint8_t> as_bytes() const;
    };

}
                    focus on usage;
#endif
                  public stuff first, then
                      private stuff
#ifndef PAL_TYPE1_MESSAGE_HPP_INCLUDED
#define PAL_TYPE1_MESSAGE_HPP_INCLUDED

#include "ntlm_message.hpp"

#include <vector>

namespace pal {

    class type1_message : public ntlm_message {
        uint32_t ssp_flags_;
    public:
        type1_message(uint32_t ssp_flags);
        virtual std::vector<uint8_t> as_bytes() const;
    };

}

#endif
#ifndef PAL_TYPE1_MESSAGE_HPP_INCLUDED
#define PAL_TYPE1_MESSAGE_HPP_INCLUDED

#include "ntlm_message.hpp"

#include <vector>

namespace pal {

    class type1_message : public ntlm_message {
        uint32_t ssp_flags_;
    public:
        type1_message(uint32_t ssp_flags);
        virtual std::vector<uint8_t> as_bytes() const;
    };

}
                 single argument
#endif
               constructors should
              nearly always have the
              explicit specifier
#ifndef PAL_TYPE1_MESSAGE_HPP_INCLUDED
#define PAL_TYPE1_MESSAGE_HPP_INCLUDED

#include "ntlm_message.hpp"

#include <vector>

namespace pal {

    class type1_message : public ntlm_message {
        uint32_t ssp_flags_;
    public:
        type1_message(uint32_t ssp_flags);
        virtual std::vector<uint8_t> as_bytes() const;
    };

}

#endif
#ifndef PAL_TYPE1_MESSAGE_HPP_INCLUDED
#define PAL_TYPE1_MESSAGE_HPP_INCLUDED

#include "ntlm_message.hpp"

namespace pal {

    class type1_message : public ntlm_message {
        uint32_t ssp_flags_;
    public:
        type1_message(uint32_t ssp_flags);
        virtual std::vector<uint8_t> as_bytes() const;
    };

}

#endif
#ifndef PAL_TYPE1_MESSAGE_HPP_INCLUDED
#define PAL_TYPE1_MESSAGE_HPP_INCLUDED

#include "ntlm_message.hpp"

namespace pal {

    class type1_message : public ntlm_message {

        uint32_t ssp_flags_;
    public:
        type1_message(uint32_t ssp_flags);
        virtual std::vector<uint8_t> as_bytes() const;
    };

}

#endif
#ifndef PAL_TYPE1_MESSAGE_HPP_INCLUDED
#define PAL_TYPE1_MESSAGE_HPP_INCLUDED

#include "ntlm_message.hpp"

namespace pal {

    class type1_message : public ntlm_message {
    private:
        uint32_t ssp_flags_;
    public:
        type1_message(uint32_t ssp_flags);
        virtual std::vector<uint8_t> as_bytes() const;
    };

}

#endif
#ifndef PAL_TYPE1_MESSAGE_HPP_INCLUDED
#define PAL_TYPE1_MESSAGE_HPP_INCLUDED

#include "ntlm_message.hpp"

namespace pal {

    class type1_message : public ntlm_message {
    private:
        uint32_t ssp_flags_;
    public:
        type1_message(uint32_t ssp_flags);
        virtual std::vector<uint8_t> as_bytes() const;
    };

}

#endif
#ifndef PAL_TYPE1_MESSAGE_HPP_INCLUDED
#define PAL_TYPE1_MESSAGE_HPP_INCLUDED

#include "ntlm_message.hpp"

namespace pal {

    class type1_message : public ntlm_message {
    public:
        type1_message(uint32_t ssp_flags);
        virtual std::vector<uint8_t> as_bytes() const;
    private:
        uint32_t ssp_flags_;
    };

}

#endif
#ifndef PAL_TYPE1_MESSAGE_HPP_INCLUDED
#define PAL_TYPE1_MESSAGE_HPP_INCLUDED

#include "ntlm_message.hpp"

namespace pal {

    class type1_message : public ntlm_message {
    public:
        type1_message(uint32_t ssp_flags);
        virtual std::vector<uint8_t> as_bytes() const;
    private:
        uint32_t ssp_flags_;
    };

}

#endif
#ifndef PAL_TYPE1_MESSAGE_HPP_INCLUDED
#define PAL_TYPE1_MESSAGE_HPP_INCLUDED

#include "ntlm_message.hpp"

namespace pal {

    class type1_message : public ntlm_message {
    public:
        explicit type1_message(uint32_t ssp_flags);
        virtual std::vector<uint8_t> as_bytes() const;
    private:
        uint32_t ssp_flags_;
    };

}

#endif
#ifndef PAL_TYPE1_MESSAGE_HPP_INCLUDED
#define PAL_TYPE1_MESSAGE_HPP_INCLUDED

#include "ntlm_message.hpp"

namespace pal {

    class type1_message : public ntlm_message {
    public:
        explicit type1_message(uint32_t ssp_flags);
        virtual std::vector<uint8_t> as_bytes() const;
    private:
        uint32_t ssp_flags_;
    };

}

#endif
#ifndef PAL_TYPE1_MESSAGE_HPP_INCLUDED
#define PAL_TYPE1_MESSAGE_HPP_INCLUDED

#include "ntlm_message.hpp"

namespace pal {

    class type1_message : public ntlm_message {
    public:
        explicit type1_message(uint32_t ssp_flags);
        virtual std::vector<uint8_t> as_bytes() const;
    private:
        uint32_t ssp_flags_;
    };

}

#endif                        Looks good!
type1_message.cpp
#include "type1_message.hpp"

#include "tools.hpp"

/*
 * See http://davenport.sourceforge.net/ntlm.html
 *
 * Type 1 Message
 *
 *   0 NTLMSSP Signature                  "NTLMSSP0"
 *   8 NTLM Message Type                  {0x01,0x00,0x00,0x00}
 * 12 Flags                               uint32 as little endian
 * (16) Supplied Domain (optional)        (security buffer)
 * (24) Supplied Workstation (optional)   (security buffer)
 * (32) (start of datablock) if required
 */

using namespace std;

pal::type1_message::type1_message(uint32_t ssp_flags)
{
    ssp_flags_ = ssp_flags;
}

vector<uint8_t> pal::type1_message::as_bytes() const
{
    uint8_t message[16] = {
        'N', 'T', 'L', 'M', 'S', 'S', 'P', '0',
        0x01, 0x00, 0x00, 0x00, 0, 0, 0, 0
    };
    const int ssp_flags_offset = 12;
    pal::write_little_endian_from_uint32(&message[ssp_flags_offset], ssp_flags_);
    return vector<uint8_t>(message, message + sizeof message);
}
#include "type1_message.hpp"

#include "tools.hpp"                                    Find at least 3
/*                                                        issues here
 * See http://davenport.sourceforge.net/ntlm.html
 *
 * Type 1 Message
 *
 *   0 NTLMSSP Signature                  "NTLMSSP0"
 *   8 NTLM Message Type                  {0x01,0x00,0x00,0x00}
 * 12 Flags                               uint32 as little endian
 * (16) Supplied Domain (optional)        (security buffer)
 * (24) Supplied Workstation (optional)   (security buffer)
 * (32) (start of datablock) if required
 */

using namespace std;

pal::type1_message::type1_message(uint32_t ssp_flags)
{
    ssp_flags_ = ssp_flags;
}

vector<uint8_t> pal::type1_message::as_bytes() const
{
    uint8_t message[16] = {
        'N', 'T', 'L', 'M', 'S', 'S', 'P', '0',
        0x01, 0x00, 0x00, 0x00, 0, 0, 0, 0
    };
    const int ssp_flags_offset = 12;
    pal::write_little_endian_from_uint32(&message[ssp_flags_offset], ssp_flags_);
    return vector<uint8_t>(message, message + sizeof message);
}
#include "type1_message.hpp"

#include "tools.hpp"

/*
 * See http://davenport.sourceforge.net/ntlm.html
 *
 * Type 1 Message
 *
 *   0 NTLMSSP Signature                  "NTLMSSP0"
 *   8 NTLM Message Type                  {0x01,0x00,0x00,0x00}
 * 12 Flags                               uint32 as little endian
 * (16) Supplied Domain (optional)        (security buffer)
 * (24) Supplied Workstation (optional)   (security buffer)
 * (32) (start of datablock) if required
 */

using namespace std;

pal::type1_message::type1_message(uint32_t ssp_flags)
{
    ssp_flags_ = ssp_flags;
}

vector<uint8_t> pal::type1_message::as_bytes() const
{
    uint8_t message[16] = {
        'N', 'T', 'L', 'M', 'S', 'S', 'P', '0',
        0x01, 0x00, 0x00, 0x00, 0, 0, 0, 0
    };
    const int ssp_flags_offset = 12;
    pal::write_little_endian_from_uint32(&message[ssp_flags_offset], ssp_flags_);
    return vector<uint8_t>(message, message + sizeof message);
}
#include "type1_message.hpp"

#include "tools.hpp"

/*focus on readability;
 * See http://davenport.sourceforge.net/ntlm.html
importing a namespace might
 *
 * Type 1 Message
save some keystrokes, but often
 *
 *   0 NTLMSSP Signature                  "NTLMSSP0"
 it does not increase readability
 *   8 NTLM Message Type
 * 12 Flags
                                          {0x01,0x00,0x00,0x00}
                                          uint32 as little endian
 * (16) Supplied Domain (optional)        (security buffer)
 * (24) Supplied Workstation (optional)   (security buffer)
 * (32) (start of datablock) if required
 */

using namespace std;

pal::type1_message::type1_message(uint32_t ssp_flags)
{
    ssp_flags_ = ssp_flags;
}

vector<uint8_t> pal::type1_message::as_bytes() const
{
    uint8_t message[16] = {
        'N', 'T', 'L', 'M', 'S', 'S', 'P', '0',
        0x01, 0x00, 0x00, 0x00, 0, 0, 0, 0
    };
    const int ssp_flags_offset = 12;
    pal::write_little_endian_from_uint32(&message[ssp_flags_offset], ssp_flags_);
    return vector<uint8_t>(message, message + sizeof message);
}
#include "type1_message.hpp"

#include "tools.hpp"

/*
 * See http://davenport.sourceforge.net/ntlm.html
 *
 * Type 1 Message
 *
 *   0 NTLMSSP Signature                  "NTLMSSP0"
 *   8 NTLM Message Type                  {0x01,0x00,0x00,0x00}
 * 12 Flags                               uint32 as little endian
 * (16) Supplied Domain (optional)        (security buffer)
 * (24) Supplied Workstation (optional)   (security buffer)
 * (32) (start of datablock) if required
 */

using namespace std;

pal::type1_message::type1_message(uint32_t ssp_flags)
{
    ssp_flags_ = ssp_flags;
}

vector<uint8_t> pal::type1_message::as_bytes() const
{
    uint8_t message[16] = {
        'N', 'T', 'L', 'M', 'S', 'S', 'P', '0',
        0x01, 0x00, 0x00, 0x00, 0, 0, 0, 0
    };
    const int ssp_flags_offset = 12;
    pal::write_little_endian_from_uint32(&message[ssp_flags_offset], ssp_flags_);
    return vector<uint8_t>(message, message + sizeof message);
}
#include "type1_message.hpp"

#include "tools.hpp"
                   use the initializer list
/*
 * See http://davenport.sourceforge.net/ntlm.html
 *
 * Type 1 Message
 *
 *   0 NTLMSSP Signature                  "NTLMSSP0"
 *   8 NTLM Message Type                  {0x01,0x00,0x00,0x00}
 * 12 Flags                               uint32 as little endian
 * (16) Supplied Domain (optional)        (security buffer)
 * (24) Supplied Workstation (optional)   (security buffer)
 * (32) (start of datablock) if required
 */

using namespace std;

pal::type1_message::type1_message(uint32_t ssp_flags)
{
    ssp_flags_ = ssp_flags;
}

vector<uint8_t> pal::type1_message::as_bytes() const
{
    uint8_t message[16] = {
        'N', 'T', 'L', 'M', 'S', 'S', 'P', '0',
        0x01, 0x00, 0x00, 0x00, 0, 0, 0, 0
    };
    const int ssp_flags_offset = 12;
    pal::write_little_endian_from_uint32(&message[ssp_flags_offset], ssp_flags_);
    return vector<uint8_t>(message, message + sizeof message);
}
#include "type1_message.hpp"

#include "tools.hpp"

/*
 * See http://davenport.sourceforge.net/ntlm.html
 *
 * Type 1 Message
 *
 *   0 NTLMSSP Signature                  "NTLMSSP0"
 *   8 NTLM Message Type                  {0x01,0x00,0x00,0x00}
 * 12 Flags                               uint32 as little endian
 * (16) Supplied Domain (optional)        (security buffer)
 * (24) Supplied Workstation (optional)   (security buffer)
 * (32) (start of datablock) if required
 */

using namespace std;

pal::type1_message::type1_message(uint32_t ssp_flags)
{
    ssp_flags_ = ssp_flags;
}

vector<uint8_t> pal::type1_message::as_bytes() const
{
    uint8_t message[16] = {
        'N', 'T', 'L', 'M', 'S', 'S', 'P', '0',
        0x01, 0x00, 0x00, 0x00, 0, 0, 0, 0
    };
    const int ssp_flags_offset = 12;
    pal::write_little_endian_from_uint32(&message[ssp_flags_offset], ssp_flags_);
    return vector<uint8_t>(message, message + sizeof message);
}
#include "type1_message.hpp"

#include "tools.hpp"
                      use std::size_t when
/*
 * See                      appropriate
          http://davenport.sourceforge.net/ntlm.html
 *
 * Type    1 Message
 *
 *   0     NTLMSSP Signature                  "NTLMSSP0"
 *   8     NTLM Message Type                  {0x01,0x00,0x00,0x00}
 * 12      Flags                              uint32 as little endian
 * (16)    Supplied Domain (optional)         (security buffer)
 * (24)    Supplied Workstation (optional)    (security buffer)
 * (32)    (start of datablock) if required
 */

using namespace std;

pal::type1_message::type1_message(uint32_t ssp_flags)
{
    ssp_flags_ = ssp_flags;
}

vector<uint8_t> pal::type1_message::as_bytes() const
{
    uint8_t message[16] = {
        'N', 'T', 'L', 'M', 'S', 'S', 'P', '0',
        0x01, 0x00, 0x00, 0x00, 0, 0, 0, 0
    };
    const int ssp_flags_offset = 12;
    pal::write_little_endian_from_uint32(&message[ssp_flags_offset], ssp_flags_);
    return vector<uint8_t>(message, message + sizeof message);
}
#include "type1_message.hpp"

#include "tools.hpp"

/*
 * See http://davenport.sourceforge.net/ntlm.html
 *
 * Type 1 Message
 *
 *   0 NTLMSSP Signature                  "NTLMSSP0"
 *   8 NTLM Message Type                  {0x01,0x00,0x00,0x00}
 * 12 Flags                               uint32 as little endian
 * (16) Supplied Domain (optional)        (security buffer)
 * (24) Supplied Workstation (optional)   (security buffer)
 * (32) (start of datablock) if required
 */

using namespace std;

pal::type1_message::type1_message(uint32_t ssp_flags)
{
    ssp_flags_ = ssp_flags;
}

vector<uint8_t> pal::type1_message::as_bytes() const
{
    uint8_t message[16] = {
        'N', 'T', 'L', 'M', 'S', 'S', 'P', '0',
        0x01, 0x00, 0x00, 0x00, 0, 0, 0, 0
    };
    const int ssp_flags_offset = 12;
    pal::write_little_endian_from_uint32(&message[ssp_flags_offset], ssp_flags_);
    return vector<uint8_t>(message, message + sizeof message);
}
#include "type1_message.hpp"

#include "tools.hpp"

/*
 * See http://davenport.sourceforge.net/ntlm.html
 *
 * Type 1 Message
 *
 *   0 NTLMSSP Signature                  "NTLMSSP0"
 *   8 NTLM Message Type                  {0x01,0x00,0x00,0x00}
 * 12 Flags                               uint32 as little endian
 * (16) Supplied Domain (optional)        (security buffer)
 * (24) Supplied Workstation (optional)   (security buffer)
 * (32) (start of datablock) if required
 */

using namespace std;

pal::type1_message::type1_message(uint32_t ssp_flags)
{
    ssp_flags_ = ssp_flags;
}

vector<uint8_t> pal::type1_message::as_bytes() const
{
    uint8_t message[16] = {
        'N', 'T', 'L', 'M', 'S', 'S', 'P', '0',
        0x01, 0x00, 0x00, 0x00, 0, 0, 0, 0
    };
    const int ssp_flags_offset = 12;
    pal::write_little_endian_from_uint32(&message[ssp_flags_offset], ssp_flags_);
    return vector<uint8_t>(message, message + sizeof message);
}
#include "type1_message.hpp"

#include "tools.hpp"

/*
 * See http://davenport.sourceforge.net/ntlm.html
 *
 * Type 1 Message
 *
 *   0 NTLMSSP Signature                  "NTLMSSP0"
 *   8 NTLM Message Type                  {0x01,0x00,0x00,0x00}
 * 12 Flags                               uint32 as little endian
 * (16) Supplied Domain (optional)        (security buffer)
 * (24) Supplied Workstation (optional)   (security buffer)
 * (32) (start of datablock) if required
 */



pal::type1_message::type1_message(uint32_t ssp_flags)
{
    ssp_flags_ = ssp_flags;
}

vector<uint8_t> pal::type1_message::as_bytes() const
{
    uint8_t message[16] = {
        'N', 'T', 'L', 'M', 'S', 'S', 'P', '0',
        0x01, 0x00, 0x00, 0x00, 0, 0, 0, 0
    };
    const int ssp_flags_offset = 12;
    pal::write_little_endian_from_uint32(&message[ssp_flags_offset], ssp_flags_);
    return vector<uint8_t>(message, message + sizeof message);
}
#include "type1_message.hpp"

#include "tools.hpp"

/*
 * See http://davenport.sourceforge.net/ntlm.html
 *
 * Type 1 Message
 *
 *   0 NTLMSSP Signature                  "NTLMSSP0"
 *   8 NTLM Message Type                  {0x01,0x00,0x00,0x00}
 * 12 Flags                               uint32 as little endian
 * (16) Supplied Domain (optional)        (security buffer)
 * (24) Supplied Workstation (optional)   (security buffer)
 * (32) (start of datablock) if required
 */



pal::type1_message::type1_message(uint32_t ssp_flags)
{
    ssp_flags_ = ssp_flags;
}

vector<uint8_t> pal::type1_message::as_bytes() const
{
    uint8_t message[16] = {
        'N', 'T', 'L', 'M', 'S', 'S', 'P', '0',
        0x01, 0x00, 0x00, 0x00, 0, 0, 0, 0
    };
    const int ssp_flags_offset = 12;
    pal::write_little_endian_from_uint32(&message[ssp_flags_offset], ssp_flags_);
    return vector<uint8_t>(message, message + sizeof message);
}
#include "type1_message.hpp"

#include "tools.hpp"

/*
 * See http://davenport.sourceforge.net/ntlm.html
 *
 * Type 1 Message
 *
 *   0 NTLMSSP Signature                  "NTLMSSP0"
 *   8 NTLM Message Type                  {0x01,0x00,0x00,0x00}
 * 12 Flags                               uint32 as little endian
 * (16) Supplied Domain (optional)        (security buffer)
 * (24) Supplied Workstation (optional)   (security buffer)
 * (32) (start of datablock) if required
 */



pal::type1_message::type1_message(uint32_t ssp_flags)
{
    ssp_flags_ = ssp_flags;
}

std::vector<uint8_t> pal::type1_message::as_bytes() const
{
    uint8_t message[16] = {
        'N', 'T', 'L', 'M', 'S', 'S', 'P', '0',
        0x01, 0x00, 0x00, 0x00, 0, 0, 0, 0
    };
    const int ssp_flags_offset = 12;
    pal::write_little_endian_from_uint32(&message[ssp_flags_offset], ssp_flags_);
    return vector<uint8_t>(message, message + sizeof message);
}
#include "type1_message.hpp"

#include "tools.hpp"

/*
 * See http://davenport.sourceforge.net/ntlm.html
 *
 * Type 1 Message
 *
 *   0 NTLMSSP Signature                  "NTLMSSP0"
 *   8 NTLM Message Type                  {0x01,0x00,0x00,0x00}
 * 12 Flags                               uint32 as little endian
 * (16) Supplied Domain (optional)        (security buffer)
 * (24) Supplied Workstation (optional)   (security buffer)
 * (32) (start of datablock) if required
 */



pal::type1_message::type1_message(uint32_t ssp_flags)
{
    ssp_flags_ = ssp_flags;
}

std::vector<uint8_t> pal::type1_message::as_bytes() const
{
    uint8_t message[16] = {
        'N', 'T', 'L', 'M', 'S', 'S', 'P', '0',
        0x01, 0x00, 0x00, 0x00, 0, 0, 0, 0
    };
    const int ssp_flags_offset = 12;
    pal::write_little_endian_from_uint32(&message[ssp_flags_offset], ssp_flags_);
    return vector<uint8_t>(message, message + sizeof message);
}
#include "type1_message.hpp"

#include "tools.hpp"

/*
 * See http://davenport.sourceforge.net/ntlm.html
 *
 * Type 1 Message
 *
 *   0 NTLMSSP Signature                  "NTLMSSP0"
 *   8 NTLM Message Type                  {0x01,0x00,0x00,0x00}
 * 12 Flags                               uint32 as little endian
 * (16) Supplied Domain (optional)        (security buffer)
 * (24) Supplied Workstation (optional)   (security buffer)
 * (32) (start of datablock) if required
 */



pal::type1_message::type1_message(uint32_t ssp_flags)
{
    ssp_flags_ = ssp_flags;
}

std::vector<uint8_t> pal::type1_message::as_bytes() const
{
    uint8_t message[16] = {
        'N', 'T', 'L', 'M', 'S', 'S', 'P', '0',
        0x01, 0x00, 0x00, 0x00, 0, 0, 0, 0
    };
    const int ssp_flags_offset = 12;
    pal::write_little_endian_from_uint32(&message[ssp_flags_offset], ssp_flags_);
    return std::vector<uint8_t>(message, message + sizeof message);
}
#include "type1_message.hpp"

#include "tools.hpp"

/*
 * See http://davenport.sourceforge.net/ntlm.html
 *
 * Type 1 Message
 *
 *   0 NTLMSSP Signature                  "NTLMSSP0"
 *   8 NTLM Message Type                  {0x01,0x00,0x00,0x00}
 * 12 Flags                               uint32 as little endian
 * (16) Supplied Domain (optional)        (security buffer)
 * (24) Supplied Workstation (optional)   (security buffer)
 * (32) (start of datablock) if required
 */



pal::type1_message::type1_message(uint32_t ssp_flags)
{
    ssp_flags_ = ssp_flags;
}

std::vector<uint8_t> pal::type1_message::as_bytes() const
{
    uint8_t message[16] = {
        'N', 'T', 'L', 'M', 'S', 'S', 'P', '0',
        0x01, 0x00, 0x00, 0x00, 0, 0, 0, 0
    };
    const int ssp_flags_offset = 12;
    pal::write_little_endian_from_uint32(&message[ssp_flags_offset], ssp_flags_);
    return std::vector<uint8_t>(message, message + sizeof message);
}
#include "type1_message.hpp"

#include "tools.hpp"

/*
 * See http://davenport.sourceforge.net/ntlm.html
 *
 * Type 1 Message
 *
 *   0 NTLMSSP Signature                  "NTLMSSP0"
 *   8 NTLM Message Type                  {0x01,0x00,0x00,0x00}
 * 12 Flags                               uint32 as little endian
 * (16) Supplied Domain (optional)        (security buffer)
 * (24) Supplied Workstation (optional)   (security buffer)
 * (32) (start of datablock) if required
 */



pal::type1_message::type1_message(uint32_t ssp_flags)
{
    ssp_flags_ = ssp_flags;
}

std::vector<uint8_t> pal::type1_message::as_bytes() const
{
    uint8_t message[16] = {
        'N', 'T', 'L', 'M', 'S', 'S', 'P', '0',
        0x01, 0x00, 0x00, 0x00, 0, 0, 0, 0
    };
    const int ssp_flags_offset = 12;
    pal::write_little_endian_from_uint32(&message[ssp_flags_offset], ssp_flags_);
    return std::vector<uint8_t>(message, message + sizeof message);
}
#include "type1_message.hpp"

#include "tools.hpp"

/*
 * See http://davenport.sourceforge.net/ntlm.html
 *
 * Type 1 Message
 *
 *   0 NTLMSSP Signature                  "NTLMSSP0"
 *   8 NTLM Message Type                  {0x01,0x00,0x00,0x00}
 * 12 Flags                               uint32 as little endian
 * (16) Supplied Domain (optional)        (security buffer)
 * (24) Supplied Workstation (optional)   (security buffer)
 * (32) (start of datablock) if required
 */



pal::type1_message::type1_message(uint32_t ssp_flags)
{
    ssp_flags_ = ssp_flags;
}

std::vector<uint8_t> pal::type1_message::as_bytes() const
{
    uint8_t message[16] = {
        'N', 'T', 'L', 'M', 'S', 'S', 'P', '0',
        0x01, 0x00, 0x00, 0x00, 0, 0, 0, 0
    };
    const std::size_t ssp_flags_offset = 12;
    pal::write_little_endian_from_uint32(&message[ssp_flags_offset], ssp_flags_);
    return std::vector<uint8_t>(message, message + sizeof message);
}
#include "type1_message.hpp"

#include "tools.hpp"

/*
 * See http://davenport.sourceforge.net/ntlm.html
 *
 * Type 1 Message
 *
 *   0 NTLMSSP Signature                  "NTLMSSP0"
 *   8 NTLM Message Type                  {0x01,0x00,0x00,0x00}
 * 12 Flags                               uint32 as little endian
 * (16) Supplied Domain (optional)        (security buffer)
 * (24) Supplied Workstation (optional)   (security buffer)
 * (32) (start of datablock) if required
 */



pal::type1_message::type1_message(uint32_t ssp_flags)
{
    ssp_flags_ = ssp_flags;
}

std::vector<uint8_t> pal::type1_message::as_bytes() const
{
    uint8_t message[16] = {
        'N', 'T', 'L', 'M', 'S', 'S', 'P', '0',
        0x01, 0x00, 0x00, 0x00, 0, 0, 0, 0
    };
    const std::size_t ssp_flags_offset = 12;
    pal::write_little_endian_from_uint32(&message[ssp_flags_offset], ssp_flags_);
    return std::vector<uint8_t>(message, message + sizeof message);
}
#include "type1_message.hpp"

#include "tools.hpp"

/*
 * See http://davenport.sourceforge.net/ntlm.html
 *
 * Type 1 Message
 *
 *   0 NTLMSSP Signature                  "NTLMSSP0"
 *   8 NTLM Message Type                  {0x01,0x00,0x00,0x00}
 * 12 Flags                               uint32 as little endian
 * (16) Supplied Domain (optional)        (security buffer)
 * (24) Supplied Workstation (optional)   (security buffer)
 * (32) (start of datablock) if required
 */



pal::type1_message::type1_message(uint32_t ssp_flags)
{
    ssp_flags_ = ssp_flags;
}

std::vector<uint8_t> pal::type1_message::as_bytes() const
{
    uint8_t message[16] = {
        'N', 'T', 'L', 'M', 'S', 'S', 'P', '0',
        0x01, 0x00, 0x00, 0x00, 0, 0, 0, 0
    };
    const std::size_t ssp_flags_offset = 12;
    pal::write_little_endian_from_uint32(&message[ssp_flags_offset], ssp_flags_);
    return std::vector<uint8_t>(message, message + sizeof message);
}
#include "type1_message.hpp"

#include "tools.hpp"

/*
 * See http://davenport.sourceforge.net/ntlm.html
 *
 * Type 1 Message
 *
 *   0 NTLMSSP Signature                  "NTLMSSP0"
 *   8 NTLM Message Type                  {0x01,0x00,0x00,0x00}
 * 12 Flags                               uint32 as little endian
 * (16) Supplied Domain (optional)        (security buffer)
 * (24) Supplied Workstation (optional)   (security buffer)
 * (32) (start of datablock) if required
 */



pal::type1_message::type1_message(uint32_t ssp_flags)
    : ssp_flags_(ssp_flags)
{
}

std::vector<uint8_t> pal::type1_message::as_bytes() const
{
    uint8_t message[16] = {
        'N', 'T', 'L', 'M', 'S', 'S', 'P', '0',
        0x01, 0x00, 0x00, 0x00, 0, 0, 0, 0
    };
    const std::size_t ssp_flags_offset = 12;
    pal::write_little_endian_from_uint32(&message[ssp_flags_offset], ssp_flags_);
    return std::vector<uint8_t>(message, message + sizeof message);
}
#include "type1_message.hpp"

#include "tools.hpp"

/*
 * See http://davenport.sourceforge.net/ntlm.html
 *
 * Type 1 Message
 *
 *   0 NTLMSSP Signature                  "NTLMSSP0"
 *   8 NTLM Message Type                  {0x01,0x00,0x00,0x00}
 * 12 Flags                               uint32 as little endian
 * (16) Supplied Domain (optional)        (security buffer)
 * (24) Supplied Workstation (optional)   (security buffer)
 * (32) (start of datablock) if required
 */



pal::type1_message::type1_message(uint32_t ssp_flags)
    : ssp_flags_(ssp_flags)
{
}

std::vector<uint8_t> pal::type1_message::as_bytes() const
{
    uint8_t message[16] = {
        'N', 'T', 'L', 'M', 'S', 'S', 'P', '0',
        0x01, 0x00, 0x00, 0x00, 0, 0, 0, 0
    };
    const std::size_t ssp_flags_offset = 12;
    pal::write_little_endian_from_uint32(&message[ssp_flags_offset], ssp_flags_);
    return std::vector<uint8_t>(message, message + sizeof message);
}
#include "type1_message.hpp"

#include "tools.hpp"

/*
 * See http://davenport.sourceforge.net/ntlm.html
 *
 * Type 1 Message
 *
 *   0 NTLMSSP Signature                  "NTLMSSP0"
 *   8 NTLM Message Type                  {0x01,0x00,0x00,0x00}
 * 12 Flags                               uint32 as little endian
 * (16) Supplied Domain (optional)        (security buffer)
 * (24) Supplied Workstation (optional)   (security buffer)
 * (32) (start of datablock) if required
 */


pal::type1_message::type1_message(uint32_t ssp_flags)
    : ssp_flags_(ssp_flags)
{
}

std::vector<uint8_t> pal::type1_message::as_bytes() const
{
    uint8_t message[16] = {
        'N', 'T', 'L', 'M', 'S', 'S', 'P', '0',
        0x01, 0x00, 0x00, 0x00, 0, 0, 0, 0
    };
    const std::size_t ssp_flags_offset = 12;
    pal::write_little_endian_from_uint32(&message[ssp_flags_offset], ssp_flags_);
    return std::vector<uint8_t>(message, message + sizeof message);
}
#include "type1_message.hpp"

#include "tools.hpp"

/*
 * See http://davenport.sourceforge.net/ntlm.html
 *
 * Type 1 Message
 *
 *   0 NTLMSSP Signature                  "NTLMSSP0"
 *   8 NTLM Message Type                  {0x01,0x00,0x00,0x00}
 * 12 Flags                               uint32 as little endian
 * (16) Supplied Domain (optional)        (security buffer)
 * (24) Supplied Workstation (optional)   (security buffer)
 * (32) (start of datablock) if required
 */

pal::type1_message::type1_message(uint32_t ssp_flags)
    : ssp_flags_(ssp_flags)
{
}

std::vector<uint8_t> pal::type1_message::as_bytes() const
{
    uint8_t message[16] = {
        'N', 'T', 'L', 'M', 'S', 'S', 'P', '0',
        0x01, 0x00, 0x00, 0x00, 0, 0, 0, 0
    };
    const std::size_t ssp_flags_offset = 12;
    pal::write_little_endian_from_uint32(&message[ssp_flags_offset], ssp_flags_);
    return std::vector<uint8_t>(message, message + sizeof message);
}
#include "type1_message.hpp"

#include "tools.hpp"

/*
                               This is better
 * See http://davenport.sourceforge.net/ntlm.html
 *
 * Type 1 Message
 *
 *   0 NTLMSSP Signature                  "NTLMSSP0"
 *   8 NTLM Message Type                  {0x01,0x00,0x00,0x00}
 * 12 Flags                               uint32 as little endian
 * (16) Supplied Domain (optional)        (security buffer)
 * (24) Supplied Workstation (optional)   (security buffer)
 * (32) (start of datablock) if required
 */

pal::type1_message::type1_message(uint32_t ssp_flags)
    : ssp_flags_(ssp_flags)
{
}

std::vector<uint8_t> pal::type1_message::as_bytes() const
{
    uint8_t message[16] = {
        'N', 'T', 'L', 'M', 'S', 'S', 'P', '0',
        0x01, 0x00, 0x00, 0x00, 0, 0, 0, 0
    };
    const std::size_t ssp_flags_offset = 12;
    pal::write_little_endian_from_uint32(&message[ssp_flags_offset], ssp_flags_);
    return std::vector<uint8_t>(message, message + sizeof message);
}
type2_message.hpp
#ifndef PAL_TYPE2_MESSAGE_HPP_INCLUDED
#define PAL_TYPE2_MESSAGE_HPP_INCLUDED

#include "ntlm_message.hpp"

using namespace std;

namespace pal {

    class type2_message : public ntlm_message {
    public:
        explicit type2_message(vector<uint8_t> buffer);
        virtual vector<uint8_t> as_bytes() const;
        uint32_t ssp_flags();
        uint64_t challenge();
    private:
        const vector<uint8_t> buffer_;
    };

}

#endif
Find 3 issues

#ifndef PAL_TYPE2_MESSAGE_HPP_INCLUDED
#define PAL_TYPE2_MESSAGE_HPP_INCLUDED

#include "ntlm_message.hpp"

using namespace std;

namespace pal {

    class type2_message : public ntlm_message {
    public:
        explicit type2_message(vector<uint8_t> buffer);
        virtual vector<uint8_t> as_bytes() const;
        uint32_t ssp_flags();
        uint64_t challenge();
    private:
        const vector<uint8_t> buffer_;
    };

}

#endif
#ifndef PAL_TYPE2_MESSAGE_HPP_INCLUDED
#define PAL_TYPE2_MESSAGE_HPP_INCLUDED

#include "ntlm_message.hpp"

using namespace std;

namespace pal {

    class type2_message : public ntlm_message {
    public:
        explicit type2_message(vector<uint8_t> buffer);
        virtual vector<uint8_t> as_bytes() const;
        uint32_t ssp_flags();
        uint64_t challenge();
    private:
        const vector<uint8_t> buffer_;
    };

}

#endif
Ouch, do not
                   import namespaces in
                       header files!
#ifndef PAL_TYPE2_MESSAGE_HPP_INCLUDED
#define PAL_TYPE2_MESSAGE_HPP_INCLUDED

#include "ntlm_message.hpp"

using namespace std;

namespace pal {

    class type2_message : public ntlm_message {
    public:
        explicit type2_message(vector<uint8_t> buffer);
        virtual vector<uint8_t> as_bytes() const;
        uint32_t ssp_flags();
        uint64_t challenge();
    private:
        const vector<uint8_t> buffer_;
    };

}

#endif
#ifndef PAL_TYPE2_MESSAGE_HPP_INCLUDED
#define PAL_TYPE2_MESSAGE_HPP_INCLUDED

#include "ntlm_message.hpp"

using namespace std;

namespace pal {

    class type2_message : public ntlm_message {
    public:
        explicit type2_message(vector<uint8_t> buffer);
        virtual vector<uint8_t> as_bytes() const;
        uint32_t ssp_flags();
        uint64_t challenge();
    private:
        const vector<uint8_t> buffer_;
    };

}

#endif
pass this vector as
                             const &

#ifndef PAL_TYPE2_MESSAGE_HPP_INCLUDED
#define PAL_TYPE2_MESSAGE_HPP_INCLUDED

#include "ntlm_message.hpp"

using namespace std;

namespace pal {

    class type2_message : public ntlm_message {
    public:
        explicit type2_message(vector<uint8_t> buffer);
        virtual vector<uint8_t> as_bytes() const;
        uint32_t ssp_flags();
        uint64_t challenge();
    private:
        const vector<uint8_t> buffer_;
    };

}

#endif
#ifndef PAL_TYPE2_MESSAGE_HPP_INCLUDED
#define PAL_TYPE2_MESSAGE_HPP_INCLUDED

#include "ntlm_message.hpp"

using namespace std;

namespace pal {

    class type2_message : public ntlm_message {
    public:
        explicit type2_message(vector<uint8_t> buffer);
        virtual vector<uint8_t> as_bytes() const;
        uint32_t ssp_flags();
        uint64_t challenge();
    private:
        const vector<uint8_t> buffer_;
    };

}

#endif
this looks like query
                  methods, they should
                   probably be const
#ifndef PAL_TYPE2_MESSAGE_HPP_INCLUDED
#define PAL_TYPE2_MESSAGE_HPP_INCLUDED

#include "ntlm_message.hpp"

using namespace std;

namespace pal {

    class type2_message : public ntlm_message {
    public:
        explicit type2_message(vector<uint8_t> buffer);
        virtual vector<uint8_t> as_bytes() const;
        uint32_t ssp_flags();
        uint64_t challenge();
    private:
        const vector<uint8_t> buffer_;
    };

}

#endif
#ifndef PAL_TYPE2_MESSAGE_HPP_INCLUDED
#define PAL_TYPE2_MESSAGE_HPP_INCLUDED

#include "ntlm_message.hpp"

using namespace std;

namespace pal {

    class type2_message : public ntlm_message {
    public:
        explicit type2_message(vector<uint8_t> buffer);
        virtual vector<uint8_t> as_bytes() const;
        uint32_t ssp_flags();
        uint64_t challenge();
    private:
        const vector<uint8_t> buffer_;
    };

}

#endif
#ifndef PAL_TYPE2_MESSAGE_HPP_INCLUDED
#define PAL_TYPE2_MESSAGE_HPP_INCLUDED

#include "ntlm_message.hpp"

namespace pal {

    class type2_message : public ntlm_message {
    public:
        explicit type2_message(vector<uint8_t> buffer);
        virtual vector<uint8_t> as_bytes() const;
        uint32_t ssp_flags();
        uint64_t challenge();
    private:
        const vector<uint8_t> buffer_;
    };

}

#endif
#ifndef PAL_TYPE2_MESSAGE_HPP_INCLUDED
#define PAL_TYPE2_MESSAGE_HPP_INCLUDED

#include "ntlm_message.hpp"

namespace pal {

    class type2_message : public ntlm_message {
    public:
        explicit type2_message(vector<uint8_t> buffer);
        virtual vector<uint8_t> as_bytes() const;
        uint32_t ssp_flags();
        uint64_t challenge();
    private:
        const vector<uint8_t> buffer_;
    };

}

#endif
#ifndef PAL_TYPE2_MESSAGE_HPP_INCLUDED
#define PAL_TYPE2_MESSAGE_HPP_INCLUDED

#include "ntlm_message.hpp"

namespace pal {

    class type2_message : public ntlm_message {
    public:
        explicit type2_message(     vector<uint8_t> buffer);
        virtual      vector<uint8_t> as_bytes() const;
        uint32_t ssp_flags();
        uint64_t challenge();
    private:
        const      vector<uint8_t> buffer_;
    };

}

#endif
#ifndef PAL_TYPE2_MESSAGE_HPP_INCLUDED
#define PAL_TYPE2_MESSAGE_HPP_INCLUDED

#include "ntlm_message.hpp"

namespace pal {

    class type2_message : public ntlm_message {
    public:
        explicit type2_message(std::vector<uint8_t> buffer);
        virtual std::vector<uint8_t> as_bytes() const;
        uint32_t ssp_flags();
        uint64_t challenge();
    private:
        const std::vector<uint8_t> buffer_;
    };

}

#endif
#ifndef PAL_TYPE2_MESSAGE_HPP_INCLUDED
#define PAL_TYPE2_MESSAGE_HPP_INCLUDED

#include "ntlm_message.hpp"

namespace pal {

    class type2_message : public ntlm_message {
    public:
        explicit type2_message(std::vector<uint8_t> buffer);
        virtual std::vector<uint8_t> as_bytes() const;
        uint32_t ssp_flags();
        uint64_t challenge();
    private:
        const std::vector<uint8_t> buffer_;
    };

}

#endif
#ifndef PAL_TYPE2_MESSAGE_HPP_INCLUDED
#define PAL_TYPE2_MESSAGE_HPP_INCLUDED

#include "ntlm_message.hpp"

namespace pal {

    class type2_message : public ntlm_message {
    public:
        explicit type2_message(std::vector<uint8_t> buffer);
        virtual std::vector<uint8_t> as_bytes() const;
        uint32_t ssp_flags();
        uint64_t challenge();
    private:
        const std::vector<uint8_t> buffer_;
    };

}

#endif
#ifndef PAL_TYPE2_MESSAGE_HPP_INCLUDED
#define PAL_TYPE2_MESSAGE_HPP_INCLUDED

#include "ntlm_message.hpp"

namespace pal {

    class type2_message : public ntlm_message {
    public:
        explicit type2_message(std::vector<uint8_t> buffer);
        virtual std::vector<uint8_t> as_bytes() const;
        uint32_t ssp_flags();
        uint64_t challenge();
    private:
        const std::vector<uint8_t> buffer_;
    };

}

#endif
#ifndef PAL_TYPE2_MESSAGE_HPP_INCLUDED
#define PAL_TYPE2_MESSAGE_HPP_INCLUDED

#include "ntlm_message.hpp"

namespace pal {

    class type2_message : public ntlm_message {
    public:
        explicit type2_message(      std::vector<uint8_t>   buffer);
        virtual std::vector<uint8_t> as_bytes() const;
        uint32_t ssp_flags();
        uint64_t challenge();
    private:
        const std::vector<uint8_t> buffer_;
    };

}

#endif
#ifndef PAL_TYPE2_MESSAGE_HPP_INCLUDED
#define PAL_TYPE2_MESSAGE_HPP_INCLUDED

#include "ntlm_message.hpp"

namespace pal {

    class type2_message : public ntlm_message {
    public:
        explicit type2_message(const std::vector<uint8_t> & buffer);
        virtual std::vector<uint8_t> as_bytes() const;
        uint32_t ssp_flags();
        uint64_t challenge();
    private:
        const std::vector<uint8_t> buffer_;
    };

}

#endif
#ifndef PAL_TYPE2_MESSAGE_HPP_INCLUDED
#define PAL_TYPE2_MESSAGE_HPP_INCLUDED

#include "ntlm_message.hpp"

namespace pal {

    class type2_message : public ntlm_message {
    public:
        explicit type2_message(const std::vector<uint8_t> & buffer);
        virtual std::vector<uint8_t> as_bytes() const;
        uint32_t ssp_flags();
        uint64_t challenge();
    private:
        const std::vector<uint8_t> buffer_;
    };

}

#endif
#ifndef PAL_TYPE2_MESSAGE_HPP_INCLUDED
#define PAL_TYPE2_MESSAGE_HPP_INCLUDED

#include "ntlm_message.hpp"

namespace pal {

    class type2_message : public ntlm_message {
    public:
        explicit type2_message(const std::vector<uint8_t> & buffer);
        virtual std::vector<uint8_t> as_bytes() const;
        uint32_t ssp_flags() const;
        uint64_t challenge() const;
    private:
        const std::vector<uint8_t> buffer_;
    };

}

#endif
#ifndef PAL_TYPE2_MESSAGE_HPP_INCLUDED
#define PAL_TYPE2_MESSAGE_HPP_INCLUDED

#include "ntlm_message.hpp"

namespace pal {

    class type2_message : public ntlm_message {
    public:
        explicit type2_message(const std::vector<uint8_t> & buffer);
        virtual std::vector<uint8_t> as_bytes() const;
        uint32_t ssp_flags() const;
        uint64_t challenge() const;
    private:
        const std::vector<uint8_t> buffer_;
    };

}

#endif
This looks like Solid C++

#ifndef PAL_TYPE2_MESSAGE_HPP_INCLUDED
#define PAL_TYPE2_MESSAGE_HPP_INCLUDED

#include "ntlm_message.hpp"

namespace pal {

    class type2_message : public ntlm_message {
    public:
        explicit type2_message(const std::vector<uint8_t> & buffer);
        virtual std::vector<uint8_t> as_bytes() const;
        uint32_t ssp_flags() const;
        uint64_t challenge() const;
    private:
        const std::vector<uint8_t> buffer_;
    };

}

#endif
type2_message.cpp
... page 1 of 2
#include <cstddef>
#include <algorithm>
#include <stdexcept>

#include "tools.hpp"

#include "type2_message.hpp"

/*
 * See http://davenport.sourceforge.net/ntlm.html
 *
 * Type 2 Message
 *
 *   0 NTLMSSP Signature                   {'N','T','L','M','S','S','P','0'}
 *   8 NTLM Message Type                   {0x02,0x00,0x00,0x00}
 * 12 Target Name                          (security buffer)
 * 20 Flags                                uint32 as little endian
 * 24 Challenge                            8 bytes / uint64 as little endian
 * (32) Context (optional)                 8 bytes (2xlong)
 * (40) Target Information                 (security buffer)
 * (48) (start of datablock)
 *      targetname
 *      targetinfo
 *          server (type=0x0100, len, data)
 *          domain (type=0x0200, len, data)
 *          dnsserver (type=0x0300, len, data)
 *          dnsdomain (type=0x0400, len, data)
 *          type5 (type=0x0500, len, data)    // unknown role
 *          <terminator> (type=0,len=0)
 */
                                                                        ...
... page 1 of 2
#include <cstddef>                                   Find one issue
#include <algorithm>
#include <stdexcept>

#include "tools.hpp"

#include "type2_message.hpp"

/*
 * See http://davenport.sourceforge.net/ntlm.html
 *
 * Type 2 Message
 *
 *   0 NTLMSSP Signature                   {'N','T','L','M','S','S','P','0'}
 *   8 NTLM Message Type                   {0x02,0x00,0x00,0x00}
 * 12 Target Name                          (security buffer)
 * 20 Flags                                uint32 as little endian
 * 24 Challenge                            8 bytes / uint64 as little endian
 * (32) Context (optional)                 8 bytes (2xlong)
 * (40) Target Information                 (security buffer)
 * (48) (start of datablock)
 *      targetname
 *      targetinfo
 *          server (type=0x0100, len, data)
 *          domain (type=0x0200, len, data)
 *          dnsserver (type=0x0300, len, data)
 *          dnsdomain (type=0x0400, len, data)
 *          type5 (type=0x0500, len, data)    // unknown role
 *          <terminator> (type=0,len=0)
 */
                                                                        ...
... page 1 of 2
#include <cstddef>
#include <algorithm>
#include <stdexcept>

#include "tools.hpp"

#include "type2_message.hpp"

/*
 * See http://davenport.sourceforge.net/ntlm.html
 *
 * Type 2 Message
 *
 *   0 NTLMSSP Signature                   {'N','T','L','M','S','S','P','0'}
 *   8 NTLM Message Type                   {0x02,0x00,0x00,0x00}
 * 12 Target Name                          (security buffer)
 * 20 Flags                                uint32 as little endian
 * 24 Challenge                            8 bytes / uint64 as little endian
 * (32) Context (optional)                 8 bytes (2xlong)
 * (40) Target Information                 (security buffer)
 * (48) (start of datablock)
 *      targetname
 *      targetinfo
 *          server (type=0x0100, len, data)
 *          domain (type=0x0200, len, data)
 *          dnsserver (type=0x0300, len, data)
 *          dnsdomain (type=0x0400, len, data)
 *          type5 (type=0x0500, len, data)    // unknown role
 *          <terminator> (type=0,len=0)
 */
                                                                        ...
... page 1 of 2          this is not a good way
#include <cstddef>
#include <algorithm>   to order the include files
#include <stdexcept>

#include "tools.hpp"

#include "type2_message.hpp"

/*
 * See http://davenport.sourceforge.net/ntlm.html
 *
 * Type 2 Message
 *
 *   0 NTLMSSP Signature                   {'N','T','L','M','S','S','P','0'}
 *   8 NTLM Message Type                   {0x02,0x00,0x00,0x00}
 * 12 Target Name                          (security buffer)
 * 20 Flags                                uint32 as little endian
 * 24 Challenge                            8 bytes / uint64 as little endian
 * (32) Context (optional)                 8 bytes (2xlong)
 * (40) Target Information                 (security buffer)
 * (48) (start of datablock)
 *      targetname
 *      targetinfo
 *          server (type=0x0100, len, data)
 *          domain (type=0x0200, len, data)
 *          dnsserver (type=0x0300, len, data)
 *          dnsdomain (type=0x0400, len, data)
 *          type5 (type=0x0500, len, data)    // unknown role
 *          <terminator> (type=0,len=0)
 */
                                                                        ...
... page 1 of 2
#include <cstddef>
#include <algorithm>
#include <stdexcept>

#include "tools.hpp"

#include "type2_message.hpp"

/*
 * See http://davenport.sourceforge.net/ntlm.html
 *
 * Type 2 Message
 *
 *   0 NTLMSSP Signature                   {'N','T','L','M','S','S','P','0'}
 *   8 NTLM Message Type                   {0x02,0x00,0x00,0x00}
 * 12 Target Name                          (security buffer)
 * 20 Flags                                uint32 as little endian
 * 24 Challenge                            8 bytes / uint64 as little endian
 * (32) Context (optional)                 8 bytes (2xlong)
 * (40) Target Information                 (security buffer)
 * (48) (start of datablock)
 *      targetname
 *      targetinfo
 *          server (type=0x0100, len, data)
 *          domain (type=0x0200, len, data)
 *          dnsserver (type=0x0300, len, data)
 *          dnsdomain (type=0x0400, len, data)
 *          type5 (type=0x0500, len, data)    // unknown role
 *          <terminator> (type=0,len=0)
 */
                                                                        ...
... page 1 of 2
#include <cstddef>
#include <algorithm>
#include <stdexcept>

#include "tools.hpp"

#include "type2_message.hpp"

/*
 * See http://davenport.sourceforge.net/ntlm.html
 *
 * Type 2 Message
 *
 *   0 NTLMSSP Signature                   {'N','T','L','M','S','S','P','0'}
 *   8 NTLM Message Type                   {0x02,0x00,0x00,0x00}
 * 12 Target Name                          (security buffer)
 * 20 Flags                                uint32 as little endian
 * 24 Challenge                            8 bytes / uint64 as little endian
 * (32) Context (optional)                 8 bytes (2xlong)
 * (40) Target Information                 (security buffer)
 * (48) (start of datablock)
 *      targetname
 *      targetinfo
 *          server (type=0x0100, len, data)
 *          domain (type=0x0200, len, data)
 *          dnsserver (type=0x0300, len, data)
 *          dnsdomain (type=0x0400, len, data)
 *          type5 (type=0x0500, len, data)    // unknown role
 *          <terminator> (type=0,len=0)
 */
                                                                        ...
... page 1 of 2
#include "type2_message.hpp"

#include "tools.hpp"

#include <cstddef>
#include <algorithm>
#include <stdexcept>

/*
 * See http://davenport.sourceforge.net/ntlm.html
 *
 * Type 2 Message
 *
 *   0 NTLMSSP Signature                   {'N','T','L','M','S','S','P','0'}
 *   8 NTLM Message Type                   {0x02,0x00,0x00,0x00}
 * 12 Target Name                          (security buffer)
 * 20 Flags                                uint32 as little endian
 * 24 Challenge                            8 bytes / uint64 as little endian
 * (32) Context (optional)                 8 bytes (2xlong)
 * (40) Target Information                 (security buffer)
 * (48) (start of datablock)
 *      targetname
 *      targetinfo
 *          server (type=0x0100, len, data)
 *          domain (type=0x0200, len, data)
 *          dnsserver (type=0x0300, len, data)
 *          dnsdomain (type=0x0400, len, data)
 *          type5 (type=0x0500, len, data)    // unknown role
 *          <terminator> (type=0,len=0)
 */
                                                                        ...
... page 2 of 2
pal::type2_message::type2_message(const std::vector<uint8_t> & buffer)
    : buffer_(buffer)
{
    const std::size_t min_type2_buffer_size = 32;
    if (buffer.size() < min_type2_buffer_size)
        throw std::invalid_argument("not a type2 message, message too short");
    const uint8_t prefix[12] = {
        'N','T','L','M','S','S','P','0',
        0x02,0x00,0x00,0x00
    };
    if (!std::equal(prefix, prefix + sizeof(prefix), buffer.begin()))
        throw std::invalid_argument("not a type2 message, invalid prefix");
}

uint32_t pal::type2_message::ssp_flags() const
{
    return pal::read_uint32_from_little_endian(&buffer_[20]);
}

uint64_t pal::type2_message::challenge() const
{
    return pal::read_uint64_from_little_endian(&buffer_[24]);
}

std::vector<uint8_t> pal::type2_message::as_bytes() const
{
    return (buffer_);
}
... page 2 of 2
pal::type2_message::type2_message(const std::vector<uint8_t> & buffer)
    : buffer_(buffer)
{
    const std::size_t min_type2_buffer_size = 32;
    if (buffer.size() < min_type2_buffer_size)
        throw std::invalid_argument("not a type2 message, message too short");
    const uint8_t prefix[12] = {
        'N','T','L','M','S','S','P','0',
        0x02,0x00,0x00,0x00
    };
    if (!std::equal(prefix, prefix + sizeof(prefix), buffer.begin()))
        throw std::invalid_argument("not a type2 message, invalid prefix");
}

uint32_t pal::type2_message::ssp_flags() const
{
    return pal::read_uint32_from_little_endian(&buffer_[20]);
}

uint64_t pal::type2_message::challenge() const
{
    return pal::read_uint64_from_little_endian(&buffer_[24]);
}

std::vector<uint8_t> pal::type2_message::as_bytes() const
{
    return (buffer_);
}
                                            Any issues here?
... page 2 of 2
pal::type2_message::type2_message(const std::vector<uint8_t> & buffer)
    : buffer_(buffer)
{
    const std::size_t min_type2_buffer_size = 32;
    if (buffer.size() < min_type2_buffer_size)
        throw std::invalid_argument("not a type2 message, message too short");
    const uint8_t prefix[12] = {
        'N','T','L','M','S','S','P','0',
        0x02,0x00,0x00,0x00
    };
    if (!std::equal(prefix, prefix + sizeof(prefix), buffer.begin()))
        throw std::invalid_argument("not a type2 message, invalid prefix");
}

uint32_t pal::type2_message::ssp_flags() const
{
    return pal::read_uint32_from_little_endian(&buffer_[20]);
}

uint64_t pal::type2_message::challenge() const
{
    return pal::read_uint64_from_little_endian(&buffer_[24]);
}

std::vector<uint8_t> pal::type2_message::as_bytes() const
{
    return (buffer_);
}
... page 2 of 2                magic numbers
pal::type2_message::type2_message(const std::vector<uint8_t> & buffer)
    : buffer_(buffer)
{
    const std::size_t min_type2_buffer_size = 32;
    if (buffer.size() < min_type2_buffer_size)
        throw std::invalid_argument("not a type2 message, message too short");
    const uint8_t prefix[12] = {
        'N','T','L','M','S','S','P','0',
        0x02,0x00,0x00,0x00
    };
    if (!std::equal(prefix, prefix + sizeof(prefix), buffer.begin()))
        throw std::invalid_argument("not a type2 message, invalid prefix");
}

uint32_t pal::type2_message::ssp_flags() const
{
    return pal::read_uint32_from_little_endian(&buffer_[20]);
}

uint64_t pal::type2_message::challenge() const
{
    return pal::read_uint64_from_little_endian(&buffer_[24]);
}

std::vector<uint8_t> pal::type2_message::as_bytes() const
{
    return (buffer_);
}
... page 2 of 2
pal::type2_message::type2_message(const std::vector<uint8_t> & buffer)
    : buffer_(buffer)
{
    const std::size_t min_type2_buffer_size = 32;
    if (buffer.size() < min_type2_buffer_size)
        throw std::invalid_argument("not a type2 message, message too short");
    const uint8_t prefix[12] = {
        'N','T','L','M','S','S','P','0',
        0x02,0x00,0x00,0x00
    };
    if (!std::equal(prefix, prefix + sizeof(prefix), buffer.begin()))
        throw std::invalid_argument("not a type2 message, invalid prefix");
}

uint32_t pal::type2_message::ssp_flags() const
{
    return pal::read_uint32_from_little_endian(&buffer_[20]);
}

uint64_t pal::type2_message::challenge() const
{
    return pal::read_uint64_from_little_endian(&buffer_[24]);
}

std::vector<uint8_t> pal::type2_message::as_bytes() const
{
    return (buffer_);
}
... page 2 of 2
pal::type2_message::type2_message(const std::vector<uint8_t> & buffer)
    : buffer_(buffer)
{
    const std::size_t min_type2_buffer_size = 32;
    if (buffer.size() < min_type2_buffer_size)
        throw std::invalid_argument("not a type2 message, message too short");
    const uint8_t prefix[12] = {
        'N','T','L','M','S','S','P','0',
        0x02,0x00,0x00,0x00
    };
    if (!std::equal(prefix, prefix + sizeof(prefix), buffer.begin()))
        throw std::invalid_argument("not a type2 message, invalid prefix");
}

uint32_t pal::type2_message::ssp_flags() const
{
    return pal::read_uint32_from_little_endian(&buffer_[20]);
}
                    superfluous use of ()
uint64_t pal::type2_message::challenge() const
{
    return pal::read_uint64_from_little_endian(&buffer_[24]);
}

std::vector<uint8_t> pal::type2_message::as_bytes() const
{
    return (buffer_);
}
... page 2 of 2
pal::type2_message::type2_message(const std::vector<uint8_t> & buffer)
    : buffer_(buffer)
{
    const std::size_t min_type2_buffer_size = 32;
    if (buffer.size() < min_type2_buffer_size)
        throw std::invalid_argument("not a type2 message, message too short");
    const uint8_t prefix[12] = {
        'N','T','L','M','S','S','P','0',
        0x02,0x00,0x00,0x00
    };
    if (!std::equal(prefix, prefix + sizeof(prefix), buffer.begin()))
        throw std::invalid_argument("not a type2 message, invalid prefix");
}

uint32_t pal::type2_message::ssp_flags() const
{
    return pal::read_uint32_from_little_endian(&buffer_[20]);
}
                    superfluous use of ()
uint64_t pal::type2_message::challenge() const
{
    return pal::read_uint64_from_little_endian(&buffer_[24]);
}

std::vector<uint8_t> pal::type2_message::as_bytes() const
{
    return (buffer_);
}
... page 2 of 2
pal::type2_message::type2_message(const std::vector<uint8_t> & buffer)
    : buffer_(buffer)
{
    const std::size_t min_type2_buffer_size = 32;
    if (buffer.size() < min_type2_buffer_size)
        throw std::invalid_argument("not a type2 message, message too short");
    const uint8_t prefix[12] = {
        'N','T','L','M','S','S','P','0',
        0x02,0x00,0x00,0x00
    };
    if (!std::equal(prefix, prefix + sizeof((prefix)), buffer.begin()))
        throw std::invalid_argument("not a type2 message, invalid prefix");
}

uint32_t pal::type2_message::ssp_flags() const
{

}             so you really like () do you?
    return pal::read_uint32_from_little_endian(&buffer_[20]);


uint64_t
               Why not add a few more?
         pal::type2_message::challenge() const
{
    return pal::read_uint64_from_little_endian(&buffer_[24]);
}

std::vector<uint8_t> pal::type2_message::as_bytes() const
{
    return (((buffer_)));
}
... page 2 of 2
pal::type2_message::type2_message(const std::vector<uint8_t> & buffer)
    : buffer_(buffer)
{
    const std::size_t min_type2_buffer_size = (32);
    if (buffer.size() < min_type2_buffer_size)
        throw std::invalid_argument("not a type2 message, message too short");
    const uint8_t prefix[12] = {
        'N','T','L','M','S','S','P','0',
        0x02,0x00,0x00,0x00
    };
    if (!std::equal(prefix, prefix + sizeof((prefix)), buffer.begin()))
        throw std::invalid_argument("not a type2 message, invalid prefix");
}

uint32_t pal::type2_message::ssp_flags() const
{

}             so you really like () do you?
    return pal::read_uint32_from_little_endian(&buffer_[20]);


uint64_t
               Why not add a few more?
         pal::type2_message::challenge() const
{
    return pal::read_uint64_from_little_endian(&buffer_[24]);
}

std::vector<uint8_t> pal::type2_message::as_bytes() const
{
    return (((buffer_)));
}
... page 2 of 2
pal::type2_message::type2_message(const std::vector<uint8_t> & buffer)
    : buffer_(buffer)
{
    const std::size_t min_type2_buffer_size = 32;
    if (buffer.size() < min_type2_buffer_size)
        throw std::invalid_argument("not a type2 message, message too short");
    const uint8_t prefix[12] = {
        'N','T','L','M','S','S','P','0',
        0x02,0x00,0x00,0x00
    };
    if (!std::equal(prefix, prefix + sizeof(prefix), buffer.begin()))
        throw std::invalid_argument("not a type2 message, invalid prefix");
}

uint32_t pal::type2_message::ssp_flags() const
{
    return pal::read_uint32_from_little_endian(&buffer_[20]);
}

uint64_t pal::type2_message::challenge() const
{
    return pal::read_uint64_from_little_endian(&buffer_[24]);
}

std::vector<uint8_t> pal::type2_message::as_bytes() const
{
    return (buffer_);
}
... page 2 of 2
pal::type2_message::type2_message(const std::vector<uint8_t> & buffer)
    : buffer_(buffer)
{
    const std::size_t min_type2_buffer_size = 32;
    if (buffer.size() < min_type2_buffer_size)
        throw std::invalid_argument("not a type2 message, message too short");
    const uint8_t prefix[12] = {
        'N','T','L','M','S','S','P','0',
        0x02,0x00,0x00,0x00
    };
    if (!std::equal(prefix, prefix + sizeof(prefix), buffer.begin()))
        throw std::invalid_argument("not a type2 message, invalid prefix");
}

uint32_t pal::type2_message::ssp_flags() const
{

    return pal::read_uint32_from_little_endian(&buffer_[20]);
}

uint64_t pal::type2_message::challenge() const
{
    return pal::read_uint64_from_little_endian(&buffer_[24]);
}

std::vector<uint8_t> pal::type2_message::as_bytes() const
{
    return (buffer_);
}
... page 2 of 2
pal::type2_message::type2_message(const std::vector<uint8_t> & buffer)
    : buffer_(buffer)
{
    const std::size_t min_type2_buffer_size = 32;
    if (buffer.size() < min_type2_buffer_size)
        throw std::invalid_argument("not a type2 message, message too short");
    const uint8_t prefix[12] = {
        'N','T','L','M','S','S','P','0',
        0x02,0x00,0x00,0x00
    };
    if (!std::equal(prefix, prefix + sizeof(prefix), buffer.begin()))
        throw std::invalid_argument("not a type2 message, invalid prefix");
}

uint32_t pal::type2_message::ssp_flags() const
{

    return pal::read_uint32_from_little_endian(&buffer_[20]);
}

uint64_t pal::type2_message::challenge() const
{

    return pal::read_uint64_from_little_endian(&buffer_[24]);
}

std::vector<uint8_t> pal::type2_message::as_bytes() const
{
    return (buffer_);
}
... page 2 of 2
pal::type2_message::type2_message(const std::vector<uint8_t> & buffer)
    : buffer_(buffer)
{
    const std::size_t min_type2_buffer_size = 32;
    if (buffer.size() < min_type2_buffer_size)
        throw std::invalid_argument("not a type2 message, message too short");
    const uint8_t prefix[12] = {
        'N','T','L','M','S','S','P','0',
        0x02,0x00,0x00,0x00
    };
    if (!std::equal(prefix, prefix + sizeof(prefix), buffer.begin()))
        throw std::invalid_argument("not a type2 message, invalid prefix");
}

uint32_t pal::type2_message::ssp_flags() const
{

    return pal::read_uint32_from_little_endian(&buffer_[20]);
}

uint64_t pal::type2_message::challenge() const
{

    return pal::read_uint64_from_little_endian(&buffer_[24]);
}

std::vector<uint8_t> pal::type2_message::as_bytes() const
{
    return (buffer_);
}
... page 2 of 2
pal::type2_message::type2_message(const std::vector<uint8_t> & buffer)
    : buffer_(buffer)
{
    const std::size_t min_type2_buffer_size = 32;
    if (buffer.size() < min_type2_buffer_size)
        throw std::invalid_argument("not a type2 message, message too short");
    const uint8_t prefix[12] = {
        'N','T','L','M','S','S','P','0',
        0x02,0x00,0x00,0x00
    };
    if (!std::equal(prefix, prefix + sizeof(prefix), buffer.begin()))
        throw std::invalid_argument("not a type2 message, invalid prefix");
}

uint32_t pal::type2_message::ssp_flags() const
{
    const std::size_t ssp_flags_offset = 20;
    return pal::read_uint32_from_little_endian(&buffer_[20]);
}

uint64_t pal::type2_message::challenge() const
{
    const std::size_t challenge_offset = 24;
    return pal::read_uint64_from_little_endian(&buffer_[24]);
}

std::vector<uint8_t> pal::type2_message::as_bytes() const
{
    return (buffer_);
}
... page 2 of 2
pal::type2_message::type2_message(const std::vector<uint8_t> & buffer)
    : buffer_(buffer)
{
    const std::size_t min_type2_buffer_size = 32;
    if (buffer.size() < min_type2_buffer_size)
        throw std::invalid_argument("not a type2 message, message too short");
    const uint8_t prefix[12] = {
        'N','T','L','M','S','S','P','0',
        0x02,0x00,0x00,0x00
    };
    if (!std::equal(prefix, prefix + sizeof(prefix), buffer.begin()))
        throw std::invalid_argument("not a type2 message, invalid prefix");
}

uint32_t pal::type2_message::ssp_flags() const
{
    const std::size_t ssp_flags_offset = 20;
    return pal::read_uint32_from_little_endian(&buffer_[20]);
}

uint64_t pal::type2_message::challenge() const
{
    const std::size_t challenge_offset = 24;
    return pal::read_uint64_from_little_endian(&buffer_[24]);
}

std::vector<uint8_t> pal::type2_message::as_bytes() const
{
    return (buffer_);
}
... page 2 of 2
pal::type2_message::type2_message(const std::vector<uint8_t> & buffer)
    : buffer_(buffer)
{
    const std::size_t min_type2_buffer_size = 32;
    if (buffer.size() < min_type2_buffer_size)
        throw std::invalid_argument("not a type2 message, message too short");
    const uint8_t prefix[12] = {
        'N','T','L','M','S','S','P','0',
        0x02,0x00,0x00,0x00
    };
    if (!std::equal(prefix, prefix + sizeof(prefix), buffer.begin()))
        throw std::invalid_argument("not a type2 message, invalid prefix");
}

uint32_t pal::type2_message::ssp_flags() const
{
    const std::size_t ssp_flags_offset = 20;
    return pal::read_uint32_from_little_endian(&buffer_[ssp_flags_offset]);
}

uint64_t pal::type2_message::challenge() const
{
    const std::size_t challenge_offset = 24;
    return pal::read_uint64_from_little_endian(&buffer_[24]);
}

std::vector<uint8_t> pal::type2_message::as_bytes() const
{
    return (buffer_);
}
... page 2 of 2
pal::type2_message::type2_message(const std::vector<uint8_t> & buffer)
    : buffer_(buffer)
{
    const std::size_t min_type2_buffer_size = 32;
    if (buffer.size() < min_type2_buffer_size)
        throw std::invalid_argument("not a type2 message, message too short");
    const uint8_t prefix[12] = {
        'N','T','L','M','S','S','P','0',
        0x02,0x00,0x00,0x00
    };
    if (!std::equal(prefix, prefix + sizeof(prefix), buffer.begin()))
        throw std::invalid_argument("not a type2 message, invalid prefix");
}

uint32_t pal::type2_message::ssp_flags() const
{
    const std::size_t ssp_flags_offset = 20;
    return pal::read_uint32_from_little_endian(&buffer_[ssp_flags_offset]);
}

uint64_t pal::type2_message::challenge() const
{
    const std::size_t challenge_offset = 24;
    return pal::read_uint64_from_little_endian(&buffer_[challenge_offset]);
}

std::vector<uint8_t> pal::type2_message::as_bytes() const
{
    return (buffer_);
}
... page 2 of 2
pal::type2_message::type2_message(const std::vector<uint8_t> & buffer)
    : buffer_(buffer)
{
    const std::size_t min_type2_buffer_size = 32;
    if (buffer.size() < min_type2_buffer_size)
        throw std::invalid_argument("not a type2 message, message too short");
    const uint8_t prefix[12] = {
        'N','T','L','M','S','S','P','0',
        0x02,0x00,0x00,0x00
    };
    if (!std::equal(prefix, prefix + sizeof(prefix), buffer.begin()))
        throw std::invalid_argument("not a type2 message, invalid prefix");
}

uint32_t pal::type2_message::ssp_flags() const
{
    const std::size_t ssp_flags_offset = 20;
    return pal::read_uint32_from_little_endian(&buffer_[ssp_flags_offset]);
}

uint64_t pal::type2_message::challenge() const
{
    const std::size_t challenge_offset = 24;
    return pal::read_uint64_from_little_endian(&buffer_[challenge_offset]);
}

std::vector<uint8_t> pal::type2_message::as_bytes() const
{
    return (buffer_);
}
... page 2 of 2
pal::type2_message::type2_message(const std::vector<uint8_t> & buffer)
    : buffer_(buffer)
{
    const std::size_t min_type2_buffer_size = 32;
    if (buffer.size() < min_type2_buffer_size)
        throw std::invalid_argument("not a type2 message, message too short");
    const uint8_t prefix[12] = {
        'N','T','L','M','S','S','P','0',
        0x02,0x00,0x00,0x00
    };
    if (!std::equal(prefix, prefix + sizeof prefix , buffer.begin()))
        throw std::invalid_argument("not a type2 message, invalid prefix");
}

uint32_t pal::type2_message::ssp_flags() const
{
    const std::size_t ssp_flags_offset = 20;
    return pal::read_uint32_from_little_endian(&buffer_[ssp_flags_offset]);
}

uint64_t pal::type2_message::challenge() const
{
    const std::size_t challenge_offset = 24;
    return pal::read_uint64_from_little_endian(&buffer_[challenge_offset]);
}

std::vector<uint8_t> pal::type2_message::as_bytes() const
{
    return (buffer_);
}
... page 2 of 2
pal::type2_message::type2_message(const std::vector<uint8_t> & buffer)
    : buffer_(buffer)
{
    const std::size_t min_type2_buffer_size = 32;
    if (buffer.size() < min_type2_buffer_size)
        throw std::invalid_argument("not a type2 message, message too short");
    const uint8_t prefix[12] = {
        'N','T','L','M','S','S','P','0',
        0x02,0x00,0x00,0x00
    };
    if (!std::equal(prefix, prefix + sizeof prefix , buffer.begin()))
        throw std::invalid_argument("not a type2 message, invalid prefix");
}

uint32_t pal::type2_message::ssp_flags() const
{
    const std::size_t ssp_flags_offset = 20;
    return pal::read_uint32_from_little_endian(&buffer_[ssp_flags_offset]);
}

uint64_t pal::type2_message::challenge() const
{
    const std::size_t challenge_offset = 24;
    return pal::read_uint64_from_little_endian(&buffer_[challenge_offset]);
}

std::vector<uint8_t> pal::type2_message::as_bytes() const
{
    return (buffer_);
}
... page 2 of 2
pal::type2_message::type2_message(const std::vector<uint8_t> & buffer)
    : buffer_(buffer)
{
    const std::size_t min_type2_buffer_size = 32;
    if (buffer.size() < min_type2_buffer_size)
        throw std::invalid_argument("not a type2 message, message too short");
    const uint8_t prefix[12] = {
        'N','T','L','M','S','S','P','0',
        0x02,0x00,0x00,0x00
    };
    if (!std::equal(prefix, prefix + sizeof prefix , buffer.begin()))
        throw std::invalid_argument("not a type2 message, invalid prefix");
}

uint32_t pal::type2_message::ssp_flags() const
{
    const std::size_t ssp_flags_offset = 20;
    return pal::read_uint32_from_little_endian(&buffer_[ssp_flags_offset]);
}

uint64_t pal::type2_message::challenge() const
{
    const std::size_t challenge_offset = 24;
    return pal::read_uint64_from_little_endian(&buffer_[challenge_offset]);
}

std::vector<uint8_t> pal::type2_message::as_bytes() const
{
    return buffer_ ;
}
... page 2 of 2
pal::type2_message::type2_message(const std::vector<uint8_t> & buffer)
    : buffer_(buffer)
{
    const std::size_t min_type2_buffer_size = 32;
    if (buffer.size() < min_type2_buffer_size)
        throw std::invalid_argument("not a type2 message, message too short");
    const uint8_t prefix[12] = {
        'N','T','L','M','S','S','P','0',
        0x02,0x00,0x00,0x00
    };
    if (!std::equal(prefix, prefix + sizeof prefix, buffer.begin()))
        throw std::invalid_argument("not a type2 message, invalid prefix");
}

uint32_t pal::type2_message::ssp_flags() const
{
    const std::size_t ssp_flags_offset = 20;
    return pal::read_uint32_from_little_endian(&buffer_[ssp_flags_offset]);
}

uint64_t pal::type2_message::challenge() const
{
    const std::size_t challenge_offset = 24;
    return pal::read_uint64_from_little_endian(&buffer_[challenge_offset]);
}

std::vector<uint8_t> pal::type2_message::as_bytes() const
{
    return buffer_;
}
... page 2 of 2
pal::type2_message::type2_message(const std::vector<uint8_t> & buffer)
    : buffer_(buffer)
{
    const std::size_t min_type2_buffer_size = 32;
    if (buffer.size() < min_type2_buffer_size)
        throw std::invalid_argument("not a type2 message, message too short");
    const uint8_t prefix[12] = {
        'N','T','L','M','S','S','P','0',
        0x02,0x00,0x00,0x00
    };
    if (!std::equal(prefix, prefix + sizeof prefix, buffer.begin()))
        throw std::invalid_argument("not a type2 message, invalid prefix");
}

uint32_t pal::type2_message::ssp_flags() const
{
    const std::size_t ssp_flags_offset = 20;
    return pal::read_uint32_from_little_endian(&buffer_[ssp_flags_offset]);
}

uint64_t pal::type2_message::challenge() const
{
    const std::size_t challenge_offset = 24;
    return pal::read_uint64_from_little_endian(&buffer_[challenge_offset]);
}

std::vector<uint8_t> pal::type2_message::as_bytes() const
{
    return buffer_;
}
type3_message.hpp
#ifndef PAL_TYPE3_MESSAGE_HPP_INCLUDED
#define PAL_TYPE3_MESSAGE_HPP_INCLUDED

#include "ntlm_message.hpp"

#include <string>
#include <iostream>

namespace pal {

    class type3_message : public ntlm_message {
    public:
        explicit type3_message(
             const std::vector<uint8_t> & lm_response,
             const std::vector<uint8_t> & nt_response,
             const std::string & user,
             uint32_t ssp_flags = 0x202);
        virtual std::vector<uint8_t> as_bytes() const;
        void debug_print(std::ostream & out) const;
    private:
        const std::vector<uint8_t> lm_response_;
        const std::vector<uint8_t> nt_response_;
        const std::string domain_;
        const std::string user_;
        const std::string workstation_;
        const std::vector<uint8_t> session_key_;
        const uint32_t ssp_flags_;
    };

}

#endif
#ifndef PAL_TYPE3_MESSAGE_HPP_INCLUDED
#define PAL_TYPE3_MESSAGE_HPP_INCLUDED
                                                     Find 3 issues
#include "ntlm_message.hpp"

#include <string>
#include <iostream>

namespace pal {

    class type3_message : public ntlm_message {
    public:
        explicit type3_message(
             const std::vector<uint8_t> & lm_response,
             const std::vector<uint8_t> & nt_response,
             const std::string & user,
             uint32_t ssp_flags = 0x202);
        virtual std::vector<uint8_t> as_bytes() const;
        void debug_print(std::ostream & out) const;
    private:
        const std::vector<uint8_t> lm_response_;
        const std::vector<uint8_t> nt_response_;
        const std::string domain_;
        const std::string user_;
        const std::string workstation_;
        const std::vector<uint8_t> session_key_;
        const uint32_t ssp_flags_;
    };

}

#endif
#ifndef PAL_TYPE3_MESSAGE_HPP_INCLUDED
#define PAL_TYPE3_MESSAGE_HPP_INCLUDED

#include "ntlm_message.hpp"

#include <string>
#include <iostream>

namespace pal {

    class type3_message : public ntlm_message {
    public:
        explicit type3_message(
             const std::vector<uint8_t> & lm_response,
             const std::vector<uint8_t> & nt_response,
             const std::string & user,
             uint32_t ssp_flags = 0x202);
        virtual std::vector<uint8_t> as_bytes() const;
        void debug_print(std::ostream & out) const;
    private:
        const std::vector<uint8_t> lm_response_;
        const std::vector<uint8_t> nt_response_;
        const std::string domain_;
        const std::string user_;
        const std::string workstation_;
        const std::vector<uint8_t> session_key_;
        const uint32_t ssp_flags_;
    };

}

#endif
#ifndef PAL_TYPE3_MESSAGE_HPP_INCLUDED
#define PAL_TYPE3_MESSAGE_HPP_INCLUDED
                       include <iosfwd> instead
#include "ntlm_message.hpp"

#include <string>
#include <iostream>

namespace pal {

    class type3_message : public ntlm_message {
    public:
        explicit type3_message(
             const std::vector<uint8_t> & lm_response,
             const std::vector<uint8_t> & nt_response,
             const std::string & user,
             uint32_t ssp_flags = 0x202);
        virtual std::vector<uint8_t> as_bytes() const;
        void debug_print(std::ostream & out) const;
    private:
        const std::vector<uint8_t> lm_response_;
        const std::vector<uint8_t> nt_response_;
        const std::string domain_;
        const std::string user_;
        const std::string workstation_;
        const std::vector<uint8_t> session_key_;
        const uint32_t ssp_flags_;
    };

}

#endif
#ifndef PAL_TYPE3_MESSAGE_HPP_INCLUDED
#define PAL_TYPE3_MESSAGE_HPP_INCLUDED

#include "ntlm_message.hpp"

#include <string>
#include <iostream>

namespace pal {

    class type3_message : public ntlm_message {
    public:
        explicit type3_message(
             const std::vector<uint8_t> & lm_response,
             const std::vector<uint8_t> & nt_response,
             const std::string & user,
             uint32_t ssp_flags = 0x202);
        virtual std::vector<uint8_t> as_bytes() const;
        void debug_print(std::ostream & out) const;
    private:
        const std::vector<uint8_t> lm_response_;
        const std::vector<uint8_t> nt_response_;
        const std::string domain_;
        const std::string user_;
        const std::string workstation_;
        const std::vector<uint8_t> session_key_;
        const uint32_t ssp_flags_;
    };

}

#endif
#ifndef PAL_TYPE3_MESSAGE_HPP_INCLUDED
                           this default argument is
#define PAL_TYPE3_MESSAGE_HPP_INCLUDED

#include                    probably not needed
           "ntlm_message.hpp"

#include <string>
#include <iostream>

namespace pal {

    class type3_message : public ntlm_message {
    public:
        explicit type3_message(
             const std::vector<uint8_t> & lm_response,
             const std::vector<uint8_t> & nt_response,
             const std::string & user,
             uint32_t ssp_flags = 0x202);
        virtual std::vector<uint8_t> as_bytes() const;
        void debug_print(std::ostream & out) const;
    private:
        const std::vector<uint8_t> lm_response_;
        const std::vector<uint8_t> nt_response_;
        const std::string domain_;
        const std::string user_;
        const std::string workstation_;
        const std::vector<uint8_t> session_key_;
        const uint32_t ssp_flags_;
    };

}

#endif
#ifndef PAL_TYPE3_MESSAGE_HPP_INCLUDED
#define PAL_TYPE3_MESSAGE_HPP_INCLUDED

#include "ntlm_message.hpp"

#include <string>
#include <iostream>

namespace pal {

    class type3_message : public ntlm_message {
    public:
        explicit type3_message(
             const std::vector<uint8_t> & lm_response,
             const std::vector<uint8_t> & nt_response,
             const std::string & user,
             uint32_t ssp_flags = 0x202);
        virtual std::vector<uint8_t> as_bytes() const;
        void debug_print(std::ostream & out) const;
    private:
        const std::vector<uint8_t> lm_response_;
        const std::vector<uint8_t> nt_response_;
        const std::string domain_;
        const std::string user_;
        const std::string workstation_;
        const std::vector<uint8_t> session_key_;
        const uint32_t ssp_flags_;
    };

}

#endif
#ifndef PAL_TYPE3_MESSAGE_HPP_INCLUDED
#define PAL_TYPE3_MESSAGE_HPP_INCLUDED
                        useless explicit specifier
#include "ntlm_message.hpp"

#include <string>
#include <iostream>

namespace pal {

    class type3_message : public ntlm_message {
    public:
        explicit type3_message(
             const std::vector<uint8_t> & lm_response,
             const std::vector<uint8_t> & nt_response,
             const std::string & user,
             uint32_t ssp_flags = 0x202);
        virtual std::vector<uint8_t> as_bytes() const;
        void debug_print(std::ostream & out) const;
    private:
        const std::vector<uint8_t> lm_response_;
        const std::vector<uint8_t> nt_response_;
        const std::string domain_;
        const std::string user_;
        const std::string workstation_;
        const std::vector<uint8_t> session_key_;
        const uint32_t ssp_flags_;
    };

}

#endif
#ifndef PAL_TYPE3_MESSAGE_HPP_INCLUDED
#define PAL_TYPE3_MESSAGE_HPP_INCLUDED

#include "ntlm_message.hpp"

#include <string>
#include <iostream>

namespace pal {

    class type3_message : public ntlm_message {
    public:
        explicit type3_message(
             const std::vector<uint8_t> & lm_response,
             const std::vector<uint8_t> & nt_response,
             const std::string & user,
             uint32_t ssp_flags = 0x202);
        virtual std::vector<uint8_t> as_bytes() const;
        void debug_print(std::ostream & out) const;
    private:
        const std::vector<uint8_t> lm_response_;
        const std::vector<uint8_t> nt_response_;
        const std::string domain_;
        const std::string user_;
        const std::string workstation_;
        const std::vector<uint8_t> session_key_;
        const uint32_t ssp_flags_;
    };

}

#endif
#ifndef PAL_TYPE3_MESSAGE_HPP_INCLUDED
#define PAL_TYPE3_MESSAGE_HPP_INCLUDED

#include "ntlm_message.hpp"

#include <string>
#include <iostream>

namespace pal {

    class type3_message : public ntlm_message {
    public:
        explicit type3_message(
             const std::vector<uint8_t> & lm_response,
             const std::vector<uint8_t> & nt_response,
             const std::string & user,
             uint32_t ssp_flags = 0x202);
        virtual std::vector<uint8_t> as_bytes() const;
        void debug_print(std::ostream & out) const;
    private:
        const std::vector<uint8_t> lm_response_;
        const std::vector<uint8_t> nt_response_;
        const std::string domain_;
        const std::string user_;
        const std::string workstation_;
        const std::vector<uint8_t> session_key_;
        const uint32_t ssp_flags_;
    };

}

#endif
#ifndef PAL_TYPE3_MESSAGE_HPP_INCLUDED
#define PAL_TYPE3_MESSAGE_HPP_INCLUDED

#include "ntlm_message.hpp"

#include <string>
#include <iosfwd>

namespace pal {

    class type3_message : public ntlm_message {
    public:
        explicit type3_message(
             const std::vector<uint8_t> & lm_response,
             const std::vector<uint8_t> & nt_response,
             const std::string & user,
             uint32_t ssp_flags = 0x202);
        virtual std::vector<uint8_t> as_bytes() const;
        void debug_print(std::ostream & out) const;
    private:
        const std::vector<uint8_t> lm_response_;
        const std::vector<uint8_t> nt_response_;
        const std::string domain_;
        const std::string user_;
        const std::string workstation_;
        const std::vector<uint8_t> session_key_;
        const uint32_t ssp_flags_;
    };

}

#endif
#ifndef PAL_TYPE3_MESSAGE_HPP_INCLUDED
#define PAL_TYPE3_MESSAGE_HPP_INCLUDED

#include "ntlm_message.hpp"

#include <string>
#include <iosfwd>

namespace pal {

    class type3_message : public ntlm_message {
    public:
        explicit type3_message(
             const std::vector<uint8_t> & lm_response,
             const std::vector<uint8_t> & nt_response,
             const std::string & user,
             uint32_t ssp_flags = 0x202);
        virtual std::vector<uint8_t> as_bytes() const;
        void debug_print(std::ostream & out) const;
    private:
        const std::vector<uint8_t> lm_response_;
        const std::vector<uint8_t> nt_response_;
        const std::string domain_;
        const std::string user_;
        const std::string workstation_;
        const std::vector<uint8_t> session_key_;
        const uint32_t ssp_flags_;
    };

}

#endif
#ifndef PAL_TYPE3_MESSAGE_HPP_INCLUDED
#define PAL_TYPE3_MESSAGE_HPP_INCLUDED

#include "ntlm_message.hpp"

#include <string>
#include <iosfwd>

namespace pal {

    class type3_message : public ntlm_message {
    public:
        explicit type3_message(
             const std::vector<uint8_t> & lm_response,
             const std::vector<uint8_t> & nt_response,
             const std::string & user,
             uint32_t ssp_flags = 0x202);
        virtual std::vector<uint8_t> as_bytes() const;
        void debug_print(std::ostream & out) const;
    private:
        const std::vector<uint8_t> lm_response_;
        const std::vector<uint8_t> nt_response_;
        const std::string domain_;
        const std::string user_;
        const std::string workstation_;
        const std::vector<uint8_t> session_key_;
        const uint32_t ssp_flags_;
    };

}

#endif
#ifndef PAL_TYPE3_MESSAGE_HPP_INCLUDED
#define PAL_TYPE3_MESSAGE_HPP_INCLUDED

#include "ntlm_message.hpp"

#include <string>
#include <iosfwd>

namespace pal {

    class type3_message : public ntlm_message {
    public:
                  type3_message(
             const std::vector<uint8_t> & lm_response,
             const std::vector<uint8_t> & nt_response,
             const std::string & user,
             uint32_t ssp_flags = 0x202);
        virtual std::vector<uint8_t> as_bytes() const;
        void debug_print(std::ostream & out) const;
    private:
        const std::vector<uint8_t> lm_response_;
        const std::vector<uint8_t> nt_response_;
        const std::string domain_;
        const std::string user_;
        const std::string workstation_;
        const std::vector<uint8_t> session_key_;
        const uint32_t ssp_flags_;
    };

}

#endif
#ifndef PAL_TYPE3_MESSAGE_HPP_INCLUDED
#define PAL_TYPE3_MESSAGE_HPP_INCLUDED

#include "ntlm_message.hpp"

#include <string>
#include <iosfwd>

namespace pal {

    class type3_message : public ntlm_message {
    public:
                  type3_message(
             const std::vector<uint8_t> & lm_response,
             const std::vector<uint8_t> & nt_response,
             const std::string & user,
             uint32_t ssp_flags = 0x202);
        virtual std::vector<uint8_t> as_bytes() const;
        void debug_print(std::ostream & out) const;
    private:
        const std::vector<uint8_t> lm_response_;
        const std::vector<uint8_t> nt_response_;
        const std::string domain_;
        const std::string user_;
        const std::string workstation_;
        const std::vector<uint8_t> session_key_;
        const uint32_t ssp_flags_;
    };

}

#endif
Solid C++ by Example
Solid C++ by Example
Solid C++ by Example
Solid C++ by Example
Solid C++ by Example
Solid C++ by Example
Solid C++ by Example
Solid C++ by Example
Solid C++ by Example
Solid C++ by Example
Solid C++ by Example
Solid C++ by Example
Solid C++ by Example
Solid C++ by Example
Solid C++ by Example
Solid C++ by Example
Solid C++ by Example
Solid C++ by Example
Solid C++ by Example
Solid C++ by Example
Solid C++ by Example
Solid C++ by Example
Solid C++ by Example
Solid C++ by Example
Solid C++ by Example
Solid C++ by Example
Solid C++ by Example
Solid C++ by Example
Solid C++ by Example
Solid C++ by Example
Solid C++ by Example
Solid C++ by Example
Solid C++ by Example
Solid C++ by Example
Solid C++ by Example
Solid C++ by Example
Solid C++ by Example
Solid C++ by Example
Solid C++ by Example
Solid C++ by Example
Solid C++ by Example
Solid C++ by Example
Solid C++ by Example
Solid C++ by Example
Solid C++ by Example
Solid C++ by Example
Solid C++ by Example
Solid C++ by Example
Solid C++ by Example
Solid C++ by Example
Solid C++ by Example
Solid C++ by Example
Solid C++ by Example
Solid C++ by Example
Solid C++ by Example
Solid C++ by Example
Solid C++ by Example
Solid C++ by Example
Solid C++ by Example
Solid C++ by Example
Solid C++ by Example

More Related Content

What's hot

Understand more about C
Understand more about CUnderstand more about C
Understand more about C
Yi-Hsiu Hsu
 
88 c-programs
88 c-programs88 c-programs
88 c-programs
Leandro Schenone
 
C++ programming function
C++ programming functionC++ programming function
C++ programming function
Vishalini Mugunen
 
C, C++ Interview Questions Part - 1
C, C++ Interview Questions Part - 1C, C++ Interview Questions Part - 1
C, C++ Interview Questions Part - 1
ReKruiTIn.com
 
Clean code
Clean codeClean code
Clean code
Arturo Herrero
 
C++ Programming Course
C++ Programming CourseC++ Programming Course
C++ Programming Course
Dennis Chang
 
C Programming Storage classes, Recursion
C Programming Storage classes, RecursionC Programming Storage classes, Recursion
C Programming Storage classes, Recursion
Sreedhar Chowdam
 
Constructors and destructors
Constructors and destructorsConstructors and destructors
Constructors and destructors
Prof. Dr. K. Adisesha
 
Rust vs C++
Rust vs C++Rust vs C++
Rust vs C++
corehard_by
 
Clean code
Clean codeClean code
Clean code
Duc Nguyen Quang
 
Functions in C++
Functions in C++Functions in C++
Functions in C++
Mohammed Sikander
 
Basics of c++
Basics of c++Basics of c++
Basics of c++
Huba Akhtar
 
Function
FunctionFunction
Function
yash patel
 
Deep C Programming
Deep C ProgrammingDeep C Programming
Deep C Programming
Wang Hao Lee
 
Unit 7. Functions
Unit 7. FunctionsUnit 7. Functions
Unit 7. Functions
Ashim Lamichhane
 
Smart Pointers in C++
Smart Pointers in C++Smart Pointers in C++
Smart Pointers in C++
Francesco Casalegno
 
[C++ Korea] Effective Modern C++ Study, Item 27, 29 - 30
[C++ Korea] Effective Modern C++ Study, Item 27, 29 - 30[C++ Korea] Effective Modern C++ Study, Item 27, 29 - 30
[C++ Korea] Effective Modern C++ Study, Item 27, 29 - 30
Chris Ohk
 

What's hot (20)

Understand more about C
Understand more about CUnderstand more about C
Understand more about C
 
88 c-programs
88 c-programs88 c-programs
88 c-programs
 
C++ programming function
C++ programming functionC++ programming function
C++ programming function
 
C, C++ Interview Questions Part - 1
C, C++ Interview Questions Part - 1C, C++ Interview Questions Part - 1
C, C++ Interview Questions Part - 1
 
Functions in c++
Functions in c++Functions in c++
Functions in c++
 
Clean code
Clean codeClean code
Clean code
 
C++ Programming Course
C++ Programming CourseC++ Programming Course
C++ Programming Course
 
C++ file
C++ fileC++ file
C++ file
 
C Programming Storage classes, Recursion
C Programming Storage classes, RecursionC Programming Storage classes, Recursion
C Programming Storage classes, Recursion
 
Constructors and destructors
Constructors and destructorsConstructors and destructors
Constructors and destructors
 
Rust vs C++
Rust vs C++Rust vs C++
Rust vs C++
 
Constructors & destructors
Constructors & destructorsConstructors & destructors
Constructors & destructors
 
Clean code
Clean codeClean code
Clean code
 
Functions in C++
Functions in C++Functions in C++
Functions in C++
 
Basics of c++
Basics of c++Basics of c++
Basics of c++
 
Function
FunctionFunction
Function
 
Deep C Programming
Deep C ProgrammingDeep C Programming
Deep C Programming
 
Unit 7. Functions
Unit 7. FunctionsUnit 7. Functions
Unit 7. Functions
 
Smart Pointers in C++
Smart Pointers in C++Smart Pointers in C++
Smart Pointers in C++
 
[C++ Korea] Effective Modern C++ Study, Item 27, 29 - 30
[C++ Korea] Effective Modern C++ Study, Item 27, 29 - 30[C++ Korea] Effective Modern C++ Study, Item 27, 29 - 30
[C++ Korea] Effective Modern C++ Study, Item 27, 29 - 30
 

Similar to Solid C++ by Example

00 C hello world.pptx
00 C hello world.pptx00 C hello world.pptx
00 C hello world.pptx
Carla227537
 
CPP Programming Homework Help
CPP Programming Homework HelpCPP Programming Homework Help
CPP Programming Homework Help
C++ Homework Help
 
Cpp17 and Beyond
Cpp17 and BeyondCpp17 and Beyond
Cpp17 and Beyond
ComicSansMS
 
What we can learn from Rebol?
What we can learn from Rebol?What we can learn from Rebol?
What we can learn from Rebol?
lichtkind
 
88 c-programs
88 c-programs88 c-programs
88 c-programs
Minh Thắng Trần
 
88 c programs 15184
88 c programs 1518488 c programs 15184
88 c programs 15184
Sumit Saini
 
typemap in Perl/XS
typemap in Perl/XS  typemap in Perl/XS
typemap in Perl/XS
charsbar
 
Oh Crap, I Forgot (Or Never Learned) C! [CodeMash 2010]
Oh Crap, I Forgot (Or Never Learned) C! [CodeMash 2010]Oh Crap, I Forgot (Or Never Learned) C! [CodeMash 2010]
Oh Crap, I Forgot (Or Never Learned) C! [CodeMash 2010]
Chris Adamson
 
Boost.Python: C++ and Python Integration
Boost.Python: C++ and Python IntegrationBoost.Python: C++ and Python Integration
Boost.Python: C++ and Python Integration
GlobalLogic Ukraine
 
PHP Reviewer
PHP ReviewerPHP Reviewer
PHP Reviewer
Cecilia Pamfilo
 
C++aptitude questions and answers
C++aptitude questions and answersC++aptitude questions and answers
C++aptitude questions and answers
sheibansari
 
Hooking signals and dumping the callstack
Hooking signals and dumping the callstackHooking signals and dumping the callstack
Hooking signals and dumping the callstack
Thierry Gayet
 
Computer Science Assignment Help
 Computer Science Assignment Help  Computer Science Assignment Help
Computer Science Assignment Help
Programming Homework Help
 

Similar to Solid C++ by Example (20)

C tutorial
C tutorialC tutorial
C tutorial
 
C tutorial
C tutorialC tutorial
C tutorial
 
C tutorial
C tutorialC tutorial
C tutorial
 
C Tutorials
C TutorialsC Tutorials
C Tutorials
 
00 C hello world.pptx
00 C hello world.pptx00 C hello world.pptx
00 C hello world.pptx
 
CPP Programming Homework Help
CPP Programming Homework HelpCPP Programming Homework Help
CPP Programming Homework Help
 
Cpp17 and Beyond
Cpp17 and BeyondCpp17 and Beyond
Cpp17 and Beyond
 
What we can learn from Rebol?
What we can learn from Rebol?What we can learn from Rebol?
What we can learn from Rebol?
 
88 c-programs
88 c-programs88 c-programs
88 c-programs
 
88 c programs 15184
88 c programs 1518488 c programs 15184
88 c programs 15184
 
typemap in Perl/XS
typemap in Perl/XS  typemap in Perl/XS
typemap in Perl/XS
 
Oh Crap, I Forgot (Or Never Learned) C! [CodeMash 2010]
Oh Crap, I Forgot (Or Never Learned) C! [CodeMash 2010]Oh Crap, I Forgot (Or Never Learned) C! [CodeMash 2010]
Oh Crap, I Forgot (Or Never Learned) C! [CodeMash 2010]
 
Boost.Python: C++ and Python Integration
Boost.Python: C++ and Python IntegrationBoost.Python: C++ and Python Integration
Boost.Python: C++ and Python Integration
 
Csharp4 basics
Csharp4 basicsCsharp4 basics
Csharp4 basics
 
PHP Reviewer
PHP ReviewerPHP Reviewer
PHP Reviewer
 
C++aptitude questions and answers
C++aptitude questions and answersC++aptitude questions and answers
C++aptitude questions and answers
 
Hooking signals and dumping the callstack
Hooking signals and dumping the callstackHooking signals and dumping the callstack
Hooking signals and dumping the callstack
 
Computer Science Assignment Help
 Computer Science Assignment Help  Computer Science Assignment Help
Computer Science Assignment Help
 
lab4_php
lab4_phplab4_php
lab4_php
 
lab4_php
lab4_phplab4_php
lab4_php
 

Recently uploaded

DevOps and Testing slides at DASA Connect
DevOps and Testing slides at DASA ConnectDevOps and Testing slides at DASA Connect
DevOps and Testing slides at DASA Connect
Kari Kakkonen
 
FIDO Alliance Osaka Seminar: The WebAuthn API and Discoverable Credentials.pdf
FIDO Alliance Osaka Seminar: The WebAuthn API and Discoverable Credentials.pdfFIDO Alliance Osaka Seminar: The WebAuthn API and Discoverable Credentials.pdf
FIDO Alliance Osaka Seminar: The WebAuthn API and Discoverable Credentials.pdf
FIDO Alliance
 
The Future of Platform Engineering
The Future of Platform EngineeringThe Future of Platform Engineering
The Future of Platform Engineering
Jemma Hussein Allen
 
UiPath Test Automation using UiPath Test Suite series, part 4
UiPath Test Automation using UiPath Test Suite series, part 4UiPath Test Automation using UiPath Test Suite series, part 4
UiPath Test Automation using UiPath Test Suite series, part 4
DianaGray10
 
Neuro-symbolic is not enough, we need neuro-*semantic*
Neuro-symbolic is not enough, we need neuro-*semantic*Neuro-symbolic is not enough, we need neuro-*semantic*
Neuro-symbolic is not enough, we need neuro-*semantic*
Frank van Harmelen
 
To Graph or Not to Graph Knowledge Graph Architectures and LLMs
To Graph or Not to Graph Knowledge Graph Architectures and LLMsTo Graph or Not to Graph Knowledge Graph Architectures and LLMs
To Graph or Not to Graph Knowledge Graph Architectures and LLMs
Paul Groth
 
Generating a custom Ruby SDK for your web service or Rails API using Smithy
Generating a custom Ruby SDK for your web service or Rails API using SmithyGenerating a custom Ruby SDK for your web service or Rails API using Smithy
Generating a custom Ruby SDK for your web service or Rails API using Smithy
g2nightmarescribd
 
GDG Cloud Southlake #33: Boule & Rebala: Effective AppSec in SDLC using Deplo...
GDG Cloud Southlake #33: Boule & Rebala: Effective AppSec in SDLC using Deplo...GDG Cloud Southlake #33: Boule & Rebala: Effective AppSec in SDLC using Deplo...
GDG Cloud Southlake #33: Boule & Rebala: Effective AppSec in SDLC using Deplo...
James Anderson
 
When stars align: studies in data quality, knowledge graphs, and machine lear...
When stars align: studies in data quality, knowledge graphs, and machine lear...When stars align: studies in data quality, knowledge graphs, and machine lear...
When stars align: studies in data quality, knowledge graphs, and machine lear...
Elena Simperl
 
Software Delivery At the Speed of AI: Inflectra Invests In AI-Powered Quality
Software Delivery At the Speed of AI: Inflectra Invests In AI-Powered QualitySoftware Delivery At the Speed of AI: Inflectra Invests In AI-Powered Quality
Software Delivery At the Speed of AI: Inflectra Invests In AI-Powered Quality
Inflectra
 
Designing Great Products: The Power of Design and Leadership by Chief Designe...
Designing Great Products: The Power of Design and Leadership by Chief Designe...Designing Great Products: The Power of Design and Leadership by Chief Designe...
Designing Great Products: The Power of Design and Leadership by Chief Designe...
Product School
 
FIDO Alliance Osaka Seminar: Passkeys and the Road Ahead.pdf
FIDO Alliance Osaka Seminar: Passkeys and the Road Ahead.pdfFIDO Alliance Osaka Seminar: Passkeys and the Road Ahead.pdf
FIDO Alliance Osaka Seminar: Passkeys and the Road Ahead.pdf
FIDO Alliance
 
JMeter webinar - integration with InfluxDB and Grafana
JMeter webinar - integration with InfluxDB and GrafanaJMeter webinar - integration with InfluxDB and Grafana
JMeter webinar - integration with InfluxDB and Grafana
RTTS
 
Monitoring Java Application Security with JDK Tools and JFR Events
Monitoring Java Application Security with JDK Tools and JFR EventsMonitoring Java Application Security with JDK Tools and JFR Events
Monitoring Java Application Security with JDK Tools and JFR Events
Ana-Maria Mihalceanu
 
Securing your Kubernetes cluster_ a step-by-step guide to success !
Securing your Kubernetes cluster_ a step-by-step guide to success !Securing your Kubernetes cluster_ a step-by-step guide to success !
Securing your Kubernetes cluster_ a step-by-step guide to success !
KatiaHIMEUR1
 
FIDO Alliance Osaka Seminar: Passkeys at Amazon.pdf
FIDO Alliance Osaka Seminar: Passkeys at Amazon.pdfFIDO Alliance Osaka Seminar: Passkeys at Amazon.pdf
FIDO Alliance Osaka Seminar: Passkeys at Amazon.pdf
FIDO Alliance
 
Transcript: Selling digital books in 2024: Insights from industry leaders - T...
Transcript: Selling digital books in 2024: Insights from industry leaders - T...Transcript: Selling digital books in 2024: Insights from industry leaders - T...
Transcript: Selling digital books in 2024: Insights from industry leaders - T...
BookNet Canada
 
How world-class product teams are winning in the AI era by CEO and Founder, P...
How world-class product teams are winning in the AI era by CEO and Founder, P...How world-class product teams are winning in the AI era by CEO and Founder, P...
How world-class product teams are winning in the AI era by CEO and Founder, P...
Product School
 
Epistemic Interaction - tuning interfaces to provide information for AI support
Epistemic Interaction - tuning interfaces to provide information for AI supportEpistemic Interaction - tuning interfaces to provide information for AI support
Epistemic Interaction - tuning interfaces to provide information for AI support
Alan Dix
 
Connector Corner: Automate dynamic content and events by pushing a button
Connector Corner: Automate dynamic content and events by pushing a buttonConnector Corner: Automate dynamic content and events by pushing a button
Connector Corner: Automate dynamic content and events by pushing a button
DianaGray10
 

Recently uploaded (20)

DevOps and Testing slides at DASA Connect
DevOps and Testing slides at DASA ConnectDevOps and Testing slides at DASA Connect
DevOps and Testing slides at DASA Connect
 
FIDO Alliance Osaka Seminar: The WebAuthn API and Discoverable Credentials.pdf
FIDO Alliance Osaka Seminar: The WebAuthn API and Discoverable Credentials.pdfFIDO Alliance Osaka Seminar: The WebAuthn API and Discoverable Credentials.pdf
FIDO Alliance Osaka Seminar: The WebAuthn API and Discoverable Credentials.pdf
 
The Future of Platform Engineering
The Future of Platform EngineeringThe Future of Platform Engineering
The Future of Platform Engineering
 
UiPath Test Automation using UiPath Test Suite series, part 4
UiPath Test Automation using UiPath Test Suite series, part 4UiPath Test Automation using UiPath Test Suite series, part 4
UiPath Test Automation using UiPath Test Suite series, part 4
 
Neuro-symbolic is not enough, we need neuro-*semantic*
Neuro-symbolic is not enough, we need neuro-*semantic*Neuro-symbolic is not enough, we need neuro-*semantic*
Neuro-symbolic is not enough, we need neuro-*semantic*
 
To Graph or Not to Graph Knowledge Graph Architectures and LLMs
To Graph or Not to Graph Knowledge Graph Architectures and LLMsTo Graph or Not to Graph Knowledge Graph Architectures and LLMs
To Graph or Not to Graph Knowledge Graph Architectures and LLMs
 
Generating a custom Ruby SDK for your web service or Rails API using Smithy
Generating a custom Ruby SDK for your web service or Rails API using SmithyGenerating a custom Ruby SDK for your web service or Rails API using Smithy
Generating a custom Ruby SDK for your web service or Rails API using Smithy
 
GDG Cloud Southlake #33: Boule & Rebala: Effective AppSec in SDLC using Deplo...
GDG Cloud Southlake #33: Boule & Rebala: Effective AppSec in SDLC using Deplo...GDG Cloud Southlake #33: Boule & Rebala: Effective AppSec in SDLC using Deplo...
GDG Cloud Southlake #33: Boule & Rebala: Effective AppSec in SDLC using Deplo...
 
When stars align: studies in data quality, knowledge graphs, and machine lear...
When stars align: studies in data quality, knowledge graphs, and machine lear...When stars align: studies in data quality, knowledge graphs, and machine lear...
When stars align: studies in data quality, knowledge graphs, and machine lear...
 
Software Delivery At the Speed of AI: Inflectra Invests In AI-Powered Quality
Software Delivery At the Speed of AI: Inflectra Invests In AI-Powered QualitySoftware Delivery At the Speed of AI: Inflectra Invests In AI-Powered Quality
Software Delivery At the Speed of AI: Inflectra Invests In AI-Powered Quality
 
Designing Great Products: The Power of Design and Leadership by Chief Designe...
Designing Great Products: The Power of Design and Leadership by Chief Designe...Designing Great Products: The Power of Design and Leadership by Chief Designe...
Designing Great Products: The Power of Design and Leadership by Chief Designe...
 
FIDO Alliance Osaka Seminar: Passkeys and the Road Ahead.pdf
FIDO Alliance Osaka Seminar: Passkeys and the Road Ahead.pdfFIDO Alliance Osaka Seminar: Passkeys and the Road Ahead.pdf
FIDO Alliance Osaka Seminar: Passkeys and the Road Ahead.pdf
 
JMeter webinar - integration with InfluxDB and Grafana
JMeter webinar - integration with InfluxDB and GrafanaJMeter webinar - integration with InfluxDB and Grafana
JMeter webinar - integration with InfluxDB and Grafana
 
Monitoring Java Application Security with JDK Tools and JFR Events
Monitoring Java Application Security with JDK Tools and JFR EventsMonitoring Java Application Security with JDK Tools and JFR Events
Monitoring Java Application Security with JDK Tools and JFR Events
 
Securing your Kubernetes cluster_ a step-by-step guide to success !
Securing your Kubernetes cluster_ a step-by-step guide to success !Securing your Kubernetes cluster_ a step-by-step guide to success !
Securing your Kubernetes cluster_ a step-by-step guide to success !
 
FIDO Alliance Osaka Seminar: Passkeys at Amazon.pdf
FIDO Alliance Osaka Seminar: Passkeys at Amazon.pdfFIDO Alliance Osaka Seminar: Passkeys at Amazon.pdf
FIDO Alliance Osaka Seminar: Passkeys at Amazon.pdf
 
Transcript: Selling digital books in 2024: Insights from industry leaders - T...
Transcript: Selling digital books in 2024: Insights from industry leaders - T...Transcript: Selling digital books in 2024: Insights from industry leaders - T...
Transcript: Selling digital books in 2024: Insights from industry leaders - T...
 
How world-class product teams are winning in the AI era by CEO and Founder, P...
How world-class product teams are winning in the AI era by CEO and Founder, P...How world-class product teams are winning in the AI era by CEO and Founder, P...
How world-class product teams are winning in the AI era by CEO and Founder, P...
 
Epistemic Interaction - tuning interfaces to provide information for AI support
Epistemic Interaction - tuning interfaces to provide information for AI supportEpistemic Interaction - tuning interfaces to provide information for AI support
Epistemic Interaction - tuning interfaces to provide information for AI support
 
Connector Corner: Automate dynamic content and events by pushing a button
Connector Corner: Automate dynamic content and events by pushing a buttonConnector Corner: Automate dynamic content and events by pushing a button
Connector Corner: Automate dynamic content and events by pushing a button
 

Solid C++ by Example

  • 1. Solid C++ code by example olve.maudal@tandberg.com Sometimes you see code that is perfectly OK according to the definition of the language, but which is flawed because it breaks too many established idioms and conventions. On the other hand, a solid piece of code is something that looks like it is written by an experienced person who cares about professionalism in programming. This will be an interactive discussion about good vs bad C++ code. We will discuss simple C++ idioms and coding conventions, but we will also touch upon best practices when working with C++ in large codebases with lots of developers with mixed skills. A presentation at Norwegian Developer Conference 2010 Track 7 (1140-1240) June 17, 2010 Disclaimer: there are some issues that we do not address properly here (at least 3). They are left as an exercise for the reader. Email me if you find them, or if you want to know more!
  • 2. ~/myprog/foo.hpp namespace bar { class Foo { int _value; int my_magic(int a, int b); public: Foo(int seed); int calc(int number = 7); int getValue() { return _value; } void print(char* prefix); }; }
  • 3. ~/myprog/foo.hpp namespace bar { class Foo { int _value; int my_magic(int a, int b); public: Foo(int seed); int calc(int number = 7); int getValue() { return _value; } void print(char* prefix); }; }
  • 4. ~/myprog/foo.hpp namespace bar { class Foo { Solid code? int _value; int my_magic(int a, int b); public: Foo(int seed); int calc(int number = 7); int getValue() { return _value; } void print(char* prefix); }; }
  • 5. ~/myprog/foo.hpp namespace bar { class Foo { int _value; int my_magic(int a, int b); public: Foo(int seed); int calc(int number = 7); int getValue() { return _value; } void print(char* prefix); }; }
  • 6. ~/myprog/foo.hpp namespace bar { class Foo { Bad code? int _value; int my_magic(int a, int b); public: Foo(int seed); int calc(int number = 7); int getValue() { return _value; } void print(char* prefix); }; }
  • 7. ~/myprog/foo.hpp namespace bar { class Foo { int _value; int my_magic(int a, int b); public: Foo(int seed); int calc(int number = 7); int getValue() { return _value; } void print(char* prefix); }; }
  • 8. PAL - a Primitive Authentication Library in C++ for educational purposes http://github.com/olvemaudal/pal (from the README file) Here is the main "use story": As a client, when prompted for ntlm authentication by the server, I want a tool/library that can help me to create the initial ntlm request (type 1 message) that I can send to the server to receive a challenge (type 2 message) that needs to be solved by applying my username and password to create an ntlm response that I can send to the server. (phew...) Here are some (imaginary) additional requirements: - must be in C or C++, since embeeded - it should be possible and convenient to create a <100kb client using the PAL library - must use C++ (due to PHB decision) - must use nothing but C++ 1998 (due to compiler support, eg tr1 or boost can not be used) - initally the library will only be used to communicate HTTP with a Windows 2003 Server SP2, currently no need to support other servers
  • 9. Issues discussed here 1. base classes should have virtual destructors 2. header files should have header guards 3. make sure you include the proper header files, especially in header files 4. no need to include files included by the base class declaration 5. single argument constructors should be specified as explicit 6. focus on usage of class; public stuff first, then private stuff 7. always focus on readability, you spend more time reading code than writing it 8. importing a namespace in implementation files is usually not a good idea 9. "never" import a namespace in a header file 10. initialize objects properly, use the initialization list 11. prefer std::size_t when working with memory indexing and offsets 12. for non-trivial objects, prefer pass by const over pass by copy 13. query methods should be specified as const 14. order the include files like this; own, project/platform, standard 15. avoid magic numbers, use explaination variables 16. avoid superfluous use of () 17. prefer forward declarations when you can 18. do not use explicit on multi argument constructors 19. consider explainability, don't do things that needs elaborate explainations 20. avoid default arguments (they are often not used anyway) 21. do not throw pointers to exceptions (eg, not "throw new ...") 22. treat warnings like errors (-Werror) and compile with high warning levels (-Wall -Wextra) 23. consider using -Weffc++ and -pedantic as well 24. do not mess with borrowed things 25. always consider the sideeffects of what you do
  • 10.
  • 11.
  • 13. #include <vector> namespace pal { class ntlm_message { public: virtual std::vector<uint8_t> as_bytes() const = 0; }; }
  • 14. Find 3 issues #include <vector> namespace pal { class ntlm_message { public: virtual std::vector<uint8_t> as_bytes() const = 0; }; }
  • 15. #include <vector> namespace pal { class ntlm_message { public: virtual std::vector<uint8_t> as_bytes() const = 0; }; }
  • 16. #include <vector> namespace pal { class ntlm_message { public: virtual std::vector<uint8_t> as_bytes() const = 0; }; } WTF? This class must have a virtual destructor!
  • 17. #include <vector> namespace pal { class ntlm_message { public: virtual std::vector<uint8_t> as_bytes() const = 0; }; }
  • 18. #include <vector> namespace pal { class ntlm_message { public: virtual std::vector<uint8_t> as_bytes() const = 0; }; } missing header guard
  • 19. #include <vector> namespace pal { class ntlm_message { public: virtual std::vector<uint8_t> as_bytes() const = 0; }; }
  • 20. #include <vector> namespace pal { class ntlm_message { public: virtual std::vector<uint8_t> as_bytes() const = 0; }; } should include <stdint.h>
  • 21. #include <vector> namespace pal { class ntlm_message { public: virtual std::vector<uint8_t> as_bytes() const = 0; }; }
  • 22. #ifndef PAL_NTLM_MESSAGE_HPP_INCLUDED #define PAL_NTLM_MESSAGE_HPP_INCLUDED #include <vector> namespace pal { class ntlm_message { public: virtual std::vector<uint8_t> as_bytes() const = 0; }; } #endif
  • 23. #ifndef PAL_NTLM_MESSAGE_HPP_INCLUDED #define PAL_NTLM_MESSAGE_HPP_INCLUDED #include <vector> namespace pal { class ntlm_message { public: virtual std::vector<uint8_t> as_bytes() const = 0; }; } #endif
  • 24. #ifndef PAL_NTLM_MESSAGE_HPP_INCLUDED #define PAL_NTLM_MESSAGE_HPP_INCLUDED #include <vector> namespace pal { class ntlm_message { public: virtual ~ntlm_message() {} virtual std::vector<uint8_t> as_bytes() const = 0; }; } #endif
  • 25. #ifndef PAL_NTLM_MESSAGE_HPP_INCLUDED #define PAL_NTLM_MESSAGE_HPP_INCLUDED #include <vector> namespace pal { class ntlm_message { public: virtual ~ntlm_message() {} virtual std::vector<uint8_t> as_bytes() const = 0; }; } #endif
  • 26. #ifndef PAL_NTLM_MESSAGE_HPP_INCLUDED #define PAL_NTLM_MESSAGE_HPP_INCLUDED #include <stdint.h> #include <vector> namespace pal { class ntlm_message { public: virtual ~ntlm_message() {} virtual std::vector<uint8_t> as_bytes() const = 0; }; } #endif
  • 27. #ifndef PAL_NTLM_MESSAGE_HPP_INCLUDED #define PAL_NTLM_MESSAGE_HPP_INCLUDED #include <stdint.h> #include <vector> namespace pal { class ntlm_message { public: virtual ~ntlm_message() {} virtual std::vector<uint8_t> as_bytes() const = 0; }; } #endif
  • 28. #ifndef PAL_NTLM_MESSAGE_HPP_INCLUDED #define PAL_NTLM_MESSAGE_HPP_INCLUDED #include <stdint.h> #include <vector> namespace pal { class ntlm_message { public: virtual ~ntlm_message() {} virtual std::vector<uint8_t> as_bytes() const = 0; }; } #endif This is Solid C++!
  • 30. #ifndef PAL_TYPE1_MESSAGE_HPP_INCLUDED #define PAL_TYPE1_MESSAGE_HPP_INCLUDED #include "ntlm_message.hpp" #include <vector> namespace pal { class type1_message : public ntlm_message { uint32_t ssp_flags_; public: type1_message(uint32_t ssp_flags); virtual std::vector<uint8_t> as_bytes() const; }; } #endif
  • 31. #ifndef PAL_TYPE1_MESSAGE_HPP_INCLUDED #define PAL_TYPE1_MESSAGE_HPP_INCLUDED #include "ntlm_message.hpp" #include <vector> namespace pal { class type1_message : public ntlm_message { uint32_t ssp_flags_; public: type1_message(uint32_t ssp_flags); virtual std::vector<uint8_t> as_bytes() const; }; } #endif Find 3 issues
  • 32. #ifndef PAL_TYPE1_MESSAGE_HPP_INCLUDED #define PAL_TYPE1_MESSAGE_HPP_INCLUDED #include "ntlm_message.hpp" #include <vector> namespace pal { class type1_message : public ntlm_message { uint32_t ssp_flags_; public: type1_message(uint32_t ssp_flags); virtual std::vector<uint8_t> as_bytes() const; }; } #endif
  • 33. #ifndef PAL_TYPE1_MESSAGE_HPP_INCLUDED #define PAL_TYPE1_MESSAGE_HPP_INCLUDED #include "ntlm_message.hpp" #include <vector> namespace pal { class type1_message : public ntlm_message { uint32_t ssp_flags_; public: type1_message(uint32_t ssp_flags); virtual std::vector<uint8_t> as_bytes() const; }; } #endif no need to include <vector> again
  • 34. #ifndef PAL_TYPE1_MESSAGE_HPP_INCLUDED #define PAL_TYPE1_MESSAGE_HPP_INCLUDED #include "ntlm_message.hpp" #include <vector> namespace pal { class type1_message : public ntlm_message { uint32_t ssp_flags_; public: type1_message(uint32_t ssp_flags); virtual std::vector<uint8_t> as_bytes() const; }; } #endif
  • 35. #ifndef PAL_TYPE1_MESSAGE_HPP_INCLUDED #define PAL_TYPE1_MESSAGE_HPP_INCLUDED #include "ntlm_message.hpp" #include <vector> namespace pal { class type1_message : public ntlm_message { uint32_t ssp_flags_; public: type1_message(uint32_t ssp_flags); virtual std::vector<uint8_t> as_bytes() const; }; } focus on usage; #endif public stuff first, then private stuff
  • 36. #ifndef PAL_TYPE1_MESSAGE_HPP_INCLUDED #define PAL_TYPE1_MESSAGE_HPP_INCLUDED #include "ntlm_message.hpp" #include <vector> namespace pal { class type1_message : public ntlm_message { uint32_t ssp_flags_; public: type1_message(uint32_t ssp_flags); virtual std::vector<uint8_t> as_bytes() const; }; } #endif
  • 37. #ifndef PAL_TYPE1_MESSAGE_HPP_INCLUDED #define PAL_TYPE1_MESSAGE_HPP_INCLUDED #include "ntlm_message.hpp" #include <vector> namespace pal { class type1_message : public ntlm_message { uint32_t ssp_flags_; public: type1_message(uint32_t ssp_flags); virtual std::vector<uint8_t> as_bytes() const; }; } single argument #endif constructors should nearly always have the explicit specifier
  • 38. #ifndef PAL_TYPE1_MESSAGE_HPP_INCLUDED #define PAL_TYPE1_MESSAGE_HPP_INCLUDED #include "ntlm_message.hpp" #include <vector> namespace pal { class type1_message : public ntlm_message { uint32_t ssp_flags_; public: type1_message(uint32_t ssp_flags); virtual std::vector<uint8_t> as_bytes() const; }; } #endif
  • 39. #ifndef PAL_TYPE1_MESSAGE_HPP_INCLUDED #define PAL_TYPE1_MESSAGE_HPP_INCLUDED #include "ntlm_message.hpp" namespace pal { class type1_message : public ntlm_message { uint32_t ssp_flags_; public: type1_message(uint32_t ssp_flags); virtual std::vector<uint8_t> as_bytes() const; }; } #endif
  • 40. #ifndef PAL_TYPE1_MESSAGE_HPP_INCLUDED #define PAL_TYPE1_MESSAGE_HPP_INCLUDED #include "ntlm_message.hpp" namespace pal { class type1_message : public ntlm_message { uint32_t ssp_flags_; public: type1_message(uint32_t ssp_flags); virtual std::vector<uint8_t> as_bytes() const; }; } #endif
  • 41. #ifndef PAL_TYPE1_MESSAGE_HPP_INCLUDED #define PAL_TYPE1_MESSAGE_HPP_INCLUDED #include "ntlm_message.hpp" namespace pal { class type1_message : public ntlm_message { private: uint32_t ssp_flags_; public: type1_message(uint32_t ssp_flags); virtual std::vector<uint8_t> as_bytes() const; }; } #endif
  • 42. #ifndef PAL_TYPE1_MESSAGE_HPP_INCLUDED #define PAL_TYPE1_MESSAGE_HPP_INCLUDED #include "ntlm_message.hpp" namespace pal { class type1_message : public ntlm_message { private: uint32_t ssp_flags_; public: type1_message(uint32_t ssp_flags); virtual std::vector<uint8_t> as_bytes() const; }; } #endif
  • 43. #ifndef PAL_TYPE1_MESSAGE_HPP_INCLUDED #define PAL_TYPE1_MESSAGE_HPP_INCLUDED #include "ntlm_message.hpp" namespace pal { class type1_message : public ntlm_message { public: type1_message(uint32_t ssp_flags); virtual std::vector<uint8_t> as_bytes() const; private: uint32_t ssp_flags_; }; } #endif
  • 44. #ifndef PAL_TYPE1_MESSAGE_HPP_INCLUDED #define PAL_TYPE1_MESSAGE_HPP_INCLUDED #include "ntlm_message.hpp" namespace pal { class type1_message : public ntlm_message { public: type1_message(uint32_t ssp_flags); virtual std::vector<uint8_t> as_bytes() const; private: uint32_t ssp_flags_; }; } #endif
  • 45. #ifndef PAL_TYPE1_MESSAGE_HPP_INCLUDED #define PAL_TYPE1_MESSAGE_HPP_INCLUDED #include "ntlm_message.hpp" namespace pal { class type1_message : public ntlm_message { public: explicit type1_message(uint32_t ssp_flags); virtual std::vector<uint8_t> as_bytes() const; private: uint32_t ssp_flags_; }; } #endif
  • 46. #ifndef PAL_TYPE1_MESSAGE_HPP_INCLUDED #define PAL_TYPE1_MESSAGE_HPP_INCLUDED #include "ntlm_message.hpp" namespace pal { class type1_message : public ntlm_message { public: explicit type1_message(uint32_t ssp_flags); virtual std::vector<uint8_t> as_bytes() const; private: uint32_t ssp_flags_; }; } #endif
  • 47. #ifndef PAL_TYPE1_MESSAGE_HPP_INCLUDED #define PAL_TYPE1_MESSAGE_HPP_INCLUDED #include "ntlm_message.hpp" namespace pal { class type1_message : public ntlm_message { public: explicit type1_message(uint32_t ssp_flags); virtual std::vector<uint8_t> as_bytes() const; private: uint32_t ssp_flags_; }; } #endif Looks good!
  • 49. #include "type1_message.hpp" #include "tools.hpp" /* * See http://davenport.sourceforge.net/ntlm.html * * Type 1 Message * * 0 NTLMSSP Signature "NTLMSSP0" * 8 NTLM Message Type {0x01,0x00,0x00,0x00} * 12 Flags uint32 as little endian * (16) Supplied Domain (optional) (security buffer) * (24) Supplied Workstation (optional) (security buffer) * (32) (start of datablock) if required */ using namespace std; pal::type1_message::type1_message(uint32_t ssp_flags) { ssp_flags_ = ssp_flags; } vector<uint8_t> pal::type1_message::as_bytes() const { uint8_t message[16] = { 'N', 'T', 'L', 'M', 'S', 'S', 'P', '0', 0x01, 0x00, 0x00, 0x00, 0, 0, 0, 0 }; const int ssp_flags_offset = 12; pal::write_little_endian_from_uint32(&message[ssp_flags_offset], ssp_flags_); return vector<uint8_t>(message, message + sizeof message); }
  • 50. #include "type1_message.hpp" #include "tools.hpp" Find at least 3 /* issues here * See http://davenport.sourceforge.net/ntlm.html * * Type 1 Message * * 0 NTLMSSP Signature "NTLMSSP0" * 8 NTLM Message Type {0x01,0x00,0x00,0x00} * 12 Flags uint32 as little endian * (16) Supplied Domain (optional) (security buffer) * (24) Supplied Workstation (optional) (security buffer) * (32) (start of datablock) if required */ using namespace std; pal::type1_message::type1_message(uint32_t ssp_flags) { ssp_flags_ = ssp_flags; } vector<uint8_t> pal::type1_message::as_bytes() const { uint8_t message[16] = { 'N', 'T', 'L', 'M', 'S', 'S', 'P', '0', 0x01, 0x00, 0x00, 0x00, 0, 0, 0, 0 }; const int ssp_flags_offset = 12; pal::write_little_endian_from_uint32(&message[ssp_flags_offset], ssp_flags_); return vector<uint8_t>(message, message + sizeof message); }
  • 51. #include "type1_message.hpp" #include "tools.hpp" /* * See http://davenport.sourceforge.net/ntlm.html * * Type 1 Message * * 0 NTLMSSP Signature "NTLMSSP0" * 8 NTLM Message Type {0x01,0x00,0x00,0x00} * 12 Flags uint32 as little endian * (16) Supplied Domain (optional) (security buffer) * (24) Supplied Workstation (optional) (security buffer) * (32) (start of datablock) if required */ using namespace std; pal::type1_message::type1_message(uint32_t ssp_flags) { ssp_flags_ = ssp_flags; } vector<uint8_t> pal::type1_message::as_bytes() const { uint8_t message[16] = { 'N', 'T', 'L', 'M', 'S', 'S', 'P', '0', 0x01, 0x00, 0x00, 0x00, 0, 0, 0, 0 }; const int ssp_flags_offset = 12; pal::write_little_endian_from_uint32(&message[ssp_flags_offset], ssp_flags_); return vector<uint8_t>(message, message + sizeof message); }
  • 52. #include "type1_message.hpp" #include "tools.hpp" /*focus on readability; * See http://davenport.sourceforge.net/ntlm.html importing a namespace might * * Type 1 Message save some keystrokes, but often * * 0 NTLMSSP Signature "NTLMSSP0" it does not increase readability * 8 NTLM Message Type * 12 Flags {0x01,0x00,0x00,0x00} uint32 as little endian * (16) Supplied Domain (optional) (security buffer) * (24) Supplied Workstation (optional) (security buffer) * (32) (start of datablock) if required */ using namespace std; pal::type1_message::type1_message(uint32_t ssp_flags) { ssp_flags_ = ssp_flags; } vector<uint8_t> pal::type1_message::as_bytes() const { uint8_t message[16] = { 'N', 'T', 'L', 'M', 'S', 'S', 'P', '0', 0x01, 0x00, 0x00, 0x00, 0, 0, 0, 0 }; const int ssp_flags_offset = 12; pal::write_little_endian_from_uint32(&message[ssp_flags_offset], ssp_flags_); return vector<uint8_t>(message, message + sizeof message); }
  • 53. #include "type1_message.hpp" #include "tools.hpp" /* * See http://davenport.sourceforge.net/ntlm.html * * Type 1 Message * * 0 NTLMSSP Signature "NTLMSSP0" * 8 NTLM Message Type {0x01,0x00,0x00,0x00} * 12 Flags uint32 as little endian * (16) Supplied Domain (optional) (security buffer) * (24) Supplied Workstation (optional) (security buffer) * (32) (start of datablock) if required */ using namespace std; pal::type1_message::type1_message(uint32_t ssp_flags) { ssp_flags_ = ssp_flags; } vector<uint8_t> pal::type1_message::as_bytes() const { uint8_t message[16] = { 'N', 'T', 'L', 'M', 'S', 'S', 'P', '0', 0x01, 0x00, 0x00, 0x00, 0, 0, 0, 0 }; const int ssp_flags_offset = 12; pal::write_little_endian_from_uint32(&message[ssp_flags_offset], ssp_flags_); return vector<uint8_t>(message, message + sizeof message); }
  • 54. #include "type1_message.hpp" #include "tools.hpp" use the initializer list /* * See http://davenport.sourceforge.net/ntlm.html * * Type 1 Message * * 0 NTLMSSP Signature "NTLMSSP0" * 8 NTLM Message Type {0x01,0x00,0x00,0x00} * 12 Flags uint32 as little endian * (16) Supplied Domain (optional) (security buffer) * (24) Supplied Workstation (optional) (security buffer) * (32) (start of datablock) if required */ using namespace std; pal::type1_message::type1_message(uint32_t ssp_flags) { ssp_flags_ = ssp_flags; } vector<uint8_t> pal::type1_message::as_bytes() const { uint8_t message[16] = { 'N', 'T', 'L', 'M', 'S', 'S', 'P', '0', 0x01, 0x00, 0x00, 0x00, 0, 0, 0, 0 }; const int ssp_flags_offset = 12; pal::write_little_endian_from_uint32(&message[ssp_flags_offset], ssp_flags_); return vector<uint8_t>(message, message + sizeof message); }
  • 55. #include "type1_message.hpp" #include "tools.hpp" /* * See http://davenport.sourceforge.net/ntlm.html * * Type 1 Message * * 0 NTLMSSP Signature "NTLMSSP0" * 8 NTLM Message Type {0x01,0x00,0x00,0x00} * 12 Flags uint32 as little endian * (16) Supplied Domain (optional) (security buffer) * (24) Supplied Workstation (optional) (security buffer) * (32) (start of datablock) if required */ using namespace std; pal::type1_message::type1_message(uint32_t ssp_flags) { ssp_flags_ = ssp_flags; } vector<uint8_t> pal::type1_message::as_bytes() const { uint8_t message[16] = { 'N', 'T', 'L', 'M', 'S', 'S', 'P', '0', 0x01, 0x00, 0x00, 0x00, 0, 0, 0, 0 }; const int ssp_flags_offset = 12; pal::write_little_endian_from_uint32(&message[ssp_flags_offset], ssp_flags_); return vector<uint8_t>(message, message + sizeof message); }
  • 56. #include "type1_message.hpp" #include "tools.hpp" use std::size_t when /* * See appropriate http://davenport.sourceforge.net/ntlm.html * * Type 1 Message * * 0 NTLMSSP Signature "NTLMSSP0" * 8 NTLM Message Type {0x01,0x00,0x00,0x00} * 12 Flags uint32 as little endian * (16) Supplied Domain (optional) (security buffer) * (24) Supplied Workstation (optional) (security buffer) * (32) (start of datablock) if required */ using namespace std; pal::type1_message::type1_message(uint32_t ssp_flags) { ssp_flags_ = ssp_flags; } vector<uint8_t> pal::type1_message::as_bytes() const { uint8_t message[16] = { 'N', 'T', 'L', 'M', 'S', 'S', 'P', '0', 0x01, 0x00, 0x00, 0x00, 0, 0, 0, 0 }; const int ssp_flags_offset = 12; pal::write_little_endian_from_uint32(&message[ssp_flags_offset], ssp_flags_); return vector<uint8_t>(message, message + sizeof message); }
  • 57. #include "type1_message.hpp" #include "tools.hpp" /* * See http://davenport.sourceforge.net/ntlm.html * * Type 1 Message * * 0 NTLMSSP Signature "NTLMSSP0" * 8 NTLM Message Type {0x01,0x00,0x00,0x00} * 12 Flags uint32 as little endian * (16) Supplied Domain (optional) (security buffer) * (24) Supplied Workstation (optional) (security buffer) * (32) (start of datablock) if required */ using namespace std; pal::type1_message::type1_message(uint32_t ssp_flags) { ssp_flags_ = ssp_flags; } vector<uint8_t> pal::type1_message::as_bytes() const { uint8_t message[16] = { 'N', 'T', 'L', 'M', 'S', 'S', 'P', '0', 0x01, 0x00, 0x00, 0x00, 0, 0, 0, 0 }; const int ssp_flags_offset = 12; pal::write_little_endian_from_uint32(&message[ssp_flags_offset], ssp_flags_); return vector<uint8_t>(message, message + sizeof message); }
  • 58. #include "type1_message.hpp" #include "tools.hpp" /* * See http://davenport.sourceforge.net/ntlm.html * * Type 1 Message * * 0 NTLMSSP Signature "NTLMSSP0" * 8 NTLM Message Type {0x01,0x00,0x00,0x00} * 12 Flags uint32 as little endian * (16) Supplied Domain (optional) (security buffer) * (24) Supplied Workstation (optional) (security buffer) * (32) (start of datablock) if required */ using namespace std; pal::type1_message::type1_message(uint32_t ssp_flags) { ssp_flags_ = ssp_flags; } vector<uint8_t> pal::type1_message::as_bytes() const { uint8_t message[16] = { 'N', 'T', 'L', 'M', 'S', 'S', 'P', '0', 0x01, 0x00, 0x00, 0x00, 0, 0, 0, 0 }; const int ssp_flags_offset = 12; pal::write_little_endian_from_uint32(&message[ssp_flags_offset], ssp_flags_); return vector<uint8_t>(message, message + sizeof message); }
  • 59. #include "type1_message.hpp" #include "tools.hpp" /* * See http://davenport.sourceforge.net/ntlm.html * * Type 1 Message * * 0 NTLMSSP Signature "NTLMSSP0" * 8 NTLM Message Type {0x01,0x00,0x00,0x00} * 12 Flags uint32 as little endian * (16) Supplied Domain (optional) (security buffer) * (24) Supplied Workstation (optional) (security buffer) * (32) (start of datablock) if required */ pal::type1_message::type1_message(uint32_t ssp_flags) { ssp_flags_ = ssp_flags; } vector<uint8_t> pal::type1_message::as_bytes() const { uint8_t message[16] = { 'N', 'T', 'L', 'M', 'S', 'S', 'P', '0', 0x01, 0x00, 0x00, 0x00, 0, 0, 0, 0 }; const int ssp_flags_offset = 12; pal::write_little_endian_from_uint32(&message[ssp_flags_offset], ssp_flags_); return vector<uint8_t>(message, message + sizeof message); }
  • 60. #include "type1_message.hpp" #include "tools.hpp" /* * See http://davenport.sourceforge.net/ntlm.html * * Type 1 Message * * 0 NTLMSSP Signature "NTLMSSP0" * 8 NTLM Message Type {0x01,0x00,0x00,0x00} * 12 Flags uint32 as little endian * (16) Supplied Domain (optional) (security buffer) * (24) Supplied Workstation (optional) (security buffer) * (32) (start of datablock) if required */ pal::type1_message::type1_message(uint32_t ssp_flags) { ssp_flags_ = ssp_flags; } vector<uint8_t> pal::type1_message::as_bytes() const { uint8_t message[16] = { 'N', 'T', 'L', 'M', 'S', 'S', 'P', '0', 0x01, 0x00, 0x00, 0x00, 0, 0, 0, 0 }; const int ssp_flags_offset = 12; pal::write_little_endian_from_uint32(&message[ssp_flags_offset], ssp_flags_); return vector<uint8_t>(message, message + sizeof message); }
  • 61. #include "type1_message.hpp" #include "tools.hpp" /* * See http://davenport.sourceforge.net/ntlm.html * * Type 1 Message * * 0 NTLMSSP Signature "NTLMSSP0" * 8 NTLM Message Type {0x01,0x00,0x00,0x00} * 12 Flags uint32 as little endian * (16) Supplied Domain (optional) (security buffer) * (24) Supplied Workstation (optional) (security buffer) * (32) (start of datablock) if required */ pal::type1_message::type1_message(uint32_t ssp_flags) { ssp_flags_ = ssp_flags; } std::vector<uint8_t> pal::type1_message::as_bytes() const { uint8_t message[16] = { 'N', 'T', 'L', 'M', 'S', 'S', 'P', '0', 0x01, 0x00, 0x00, 0x00, 0, 0, 0, 0 }; const int ssp_flags_offset = 12; pal::write_little_endian_from_uint32(&message[ssp_flags_offset], ssp_flags_); return vector<uint8_t>(message, message + sizeof message); }
  • 62. #include "type1_message.hpp" #include "tools.hpp" /* * See http://davenport.sourceforge.net/ntlm.html * * Type 1 Message * * 0 NTLMSSP Signature "NTLMSSP0" * 8 NTLM Message Type {0x01,0x00,0x00,0x00} * 12 Flags uint32 as little endian * (16) Supplied Domain (optional) (security buffer) * (24) Supplied Workstation (optional) (security buffer) * (32) (start of datablock) if required */ pal::type1_message::type1_message(uint32_t ssp_flags) { ssp_flags_ = ssp_flags; } std::vector<uint8_t> pal::type1_message::as_bytes() const { uint8_t message[16] = { 'N', 'T', 'L', 'M', 'S', 'S', 'P', '0', 0x01, 0x00, 0x00, 0x00, 0, 0, 0, 0 }; const int ssp_flags_offset = 12; pal::write_little_endian_from_uint32(&message[ssp_flags_offset], ssp_flags_); return vector<uint8_t>(message, message + sizeof message); }
  • 63. #include "type1_message.hpp" #include "tools.hpp" /* * See http://davenport.sourceforge.net/ntlm.html * * Type 1 Message * * 0 NTLMSSP Signature "NTLMSSP0" * 8 NTLM Message Type {0x01,0x00,0x00,0x00} * 12 Flags uint32 as little endian * (16) Supplied Domain (optional) (security buffer) * (24) Supplied Workstation (optional) (security buffer) * (32) (start of datablock) if required */ pal::type1_message::type1_message(uint32_t ssp_flags) { ssp_flags_ = ssp_flags; } std::vector<uint8_t> pal::type1_message::as_bytes() const { uint8_t message[16] = { 'N', 'T', 'L', 'M', 'S', 'S', 'P', '0', 0x01, 0x00, 0x00, 0x00, 0, 0, 0, 0 }; const int ssp_flags_offset = 12; pal::write_little_endian_from_uint32(&message[ssp_flags_offset], ssp_flags_); return std::vector<uint8_t>(message, message + sizeof message); }
  • 64. #include "type1_message.hpp" #include "tools.hpp" /* * See http://davenport.sourceforge.net/ntlm.html * * Type 1 Message * * 0 NTLMSSP Signature "NTLMSSP0" * 8 NTLM Message Type {0x01,0x00,0x00,0x00} * 12 Flags uint32 as little endian * (16) Supplied Domain (optional) (security buffer) * (24) Supplied Workstation (optional) (security buffer) * (32) (start of datablock) if required */ pal::type1_message::type1_message(uint32_t ssp_flags) { ssp_flags_ = ssp_flags; } std::vector<uint8_t> pal::type1_message::as_bytes() const { uint8_t message[16] = { 'N', 'T', 'L', 'M', 'S', 'S', 'P', '0', 0x01, 0x00, 0x00, 0x00, 0, 0, 0, 0 }; const int ssp_flags_offset = 12; pal::write_little_endian_from_uint32(&message[ssp_flags_offset], ssp_flags_); return std::vector<uint8_t>(message, message + sizeof message); }
  • 65. #include "type1_message.hpp" #include "tools.hpp" /* * See http://davenport.sourceforge.net/ntlm.html * * Type 1 Message * * 0 NTLMSSP Signature "NTLMSSP0" * 8 NTLM Message Type {0x01,0x00,0x00,0x00} * 12 Flags uint32 as little endian * (16) Supplied Domain (optional) (security buffer) * (24) Supplied Workstation (optional) (security buffer) * (32) (start of datablock) if required */ pal::type1_message::type1_message(uint32_t ssp_flags) { ssp_flags_ = ssp_flags; } std::vector<uint8_t> pal::type1_message::as_bytes() const { uint8_t message[16] = { 'N', 'T', 'L', 'M', 'S', 'S', 'P', '0', 0x01, 0x00, 0x00, 0x00, 0, 0, 0, 0 }; const int ssp_flags_offset = 12; pal::write_little_endian_from_uint32(&message[ssp_flags_offset], ssp_flags_); return std::vector<uint8_t>(message, message + sizeof message); }
  • 66. #include "type1_message.hpp" #include "tools.hpp" /* * See http://davenport.sourceforge.net/ntlm.html * * Type 1 Message * * 0 NTLMSSP Signature "NTLMSSP0" * 8 NTLM Message Type {0x01,0x00,0x00,0x00} * 12 Flags uint32 as little endian * (16) Supplied Domain (optional) (security buffer) * (24) Supplied Workstation (optional) (security buffer) * (32) (start of datablock) if required */ pal::type1_message::type1_message(uint32_t ssp_flags) { ssp_flags_ = ssp_flags; } std::vector<uint8_t> pal::type1_message::as_bytes() const { uint8_t message[16] = { 'N', 'T', 'L', 'M', 'S', 'S', 'P', '0', 0x01, 0x00, 0x00, 0x00, 0, 0, 0, 0 }; const std::size_t ssp_flags_offset = 12; pal::write_little_endian_from_uint32(&message[ssp_flags_offset], ssp_flags_); return std::vector<uint8_t>(message, message + sizeof message); }
  • 67. #include "type1_message.hpp" #include "tools.hpp" /* * See http://davenport.sourceforge.net/ntlm.html * * Type 1 Message * * 0 NTLMSSP Signature "NTLMSSP0" * 8 NTLM Message Type {0x01,0x00,0x00,0x00} * 12 Flags uint32 as little endian * (16) Supplied Domain (optional) (security buffer) * (24) Supplied Workstation (optional) (security buffer) * (32) (start of datablock) if required */ pal::type1_message::type1_message(uint32_t ssp_flags) { ssp_flags_ = ssp_flags; } std::vector<uint8_t> pal::type1_message::as_bytes() const { uint8_t message[16] = { 'N', 'T', 'L', 'M', 'S', 'S', 'P', '0', 0x01, 0x00, 0x00, 0x00, 0, 0, 0, 0 }; const std::size_t ssp_flags_offset = 12; pal::write_little_endian_from_uint32(&message[ssp_flags_offset], ssp_flags_); return std::vector<uint8_t>(message, message + sizeof message); }
  • 68. #include "type1_message.hpp" #include "tools.hpp" /* * See http://davenport.sourceforge.net/ntlm.html * * Type 1 Message * * 0 NTLMSSP Signature "NTLMSSP0" * 8 NTLM Message Type {0x01,0x00,0x00,0x00} * 12 Flags uint32 as little endian * (16) Supplied Domain (optional) (security buffer) * (24) Supplied Workstation (optional) (security buffer) * (32) (start of datablock) if required */ pal::type1_message::type1_message(uint32_t ssp_flags) { ssp_flags_ = ssp_flags; } std::vector<uint8_t> pal::type1_message::as_bytes() const { uint8_t message[16] = { 'N', 'T', 'L', 'M', 'S', 'S', 'P', '0', 0x01, 0x00, 0x00, 0x00, 0, 0, 0, 0 }; const std::size_t ssp_flags_offset = 12; pal::write_little_endian_from_uint32(&message[ssp_flags_offset], ssp_flags_); return std::vector<uint8_t>(message, message + sizeof message); }
  • 69. #include "type1_message.hpp" #include "tools.hpp" /* * See http://davenport.sourceforge.net/ntlm.html * * Type 1 Message * * 0 NTLMSSP Signature "NTLMSSP0" * 8 NTLM Message Type {0x01,0x00,0x00,0x00} * 12 Flags uint32 as little endian * (16) Supplied Domain (optional) (security buffer) * (24) Supplied Workstation (optional) (security buffer) * (32) (start of datablock) if required */ pal::type1_message::type1_message(uint32_t ssp_flags) : ssp_flags_(ssp_flags) { } std::vector<uint8_t> pal::type1_message::as_bytes() const { uint8_t message[16] = { 'N', 'T', 'L', 'M', 'S', 'S', 'P', '0', 0x01, 0x00, 0x00, 0x00, 0, 0, 0, 0 }; const std::size_t ssp_flags_offset = 12; pal::write_little_endian_from_uint32(&message[ssp_flags_offset], ssp_flags_); return std::vector<uint8_t>(message, message + sizeof message); }
  • 70. #include "type1_message.hpp" #include "tools.hpp" /* * See http://davenport.sourceforge.net/ntlm.html * * Type 1 Message * * 0 NTLMSSP Signature "NTLMSSP0" * 8 NTLM Message Type {0x01,0x00,0x00,0x00} * 12 Flags uint32 as little endian * (16) Supplied Domain (optional) (security buffer) * (24) Supplied Workstation (optional) (security buffer) * (32) (start of datablock) if required */ pal::type1_message::type1_message(uint32_t ssp_flags) : ssp_flags_(ssp_flags) { } std::vector<uint8_t> pal::type1_message::as_bytes() const { uint8_t message[16] = { 'N', 'T', 'L', 'M', 'S', 'S', 'P', '0', 0x01, 0x00, 0x00, 0x00, 0, 0, 0, 0 }; const std::size_t ssp_flags_offset = 12; pal::write_little_endian_from_uint32(&message[ssp_flags_offset], ssp_flags_); return std::vector<uint8_t>(message, message + sizeof message); }
  • 71. #include "type1_message.hpp" #include "tools.hpp" /* * See http://davenport.sourceforge.net/ntlm.html * * Type 1 Message * * 0 NTLMSSP Signature "NTLMSSP0" * 8 NTLM Message Type {0x01,0x00,0x00,0x00} * 12 Flags uint32 as little endian * (16) Supplied Domain (optional) (security buffer) * (24) Supplied Workstation (optional) (security buffer) * (32) (start of datablock) if required */ pal::type1_message::type1_message(uint32_t ssp_flags) : ssp_flags_(ssp_flags) { } std::vector<uint8_t> pal::type1_message::as_bytes() const { uint8_t message[16] = { 'N', 'T', 'L', 'M', 'S', 'S', 'P', '0', 0x01, 0x00, 0x00, 0x00, 0, 0, 0, 0 }; const std::size_t ssp_flags_offset = 12; pal::write_little_endian_from_uint32(&message[ssp_flags_offset], ssp_flags_); return std::vector<uint8_t>(message, message + sizeof message); }
  • 72. #include "type1_message.hpp" #include "tools.hpp" /* * See http://davenport.sourceforge.net/ntlm.html * * Type 1 Message * * 0 NTLMSSP Signature "NTLMSSP0" * 8 NTLM Message Type {0x01,0x00,0x00,0x00} * 12 Flags uint32 as little endian * (16) Supplied Domain (optional) (security buffer) * (24) Supplied Workstation (optional) (security buffer) * (32) (start of datablock) if required */ pal::type1_message::type1_message(uint32_t ssp_flags) : ssp_flags_(ssp_flags) { } std::vector<uint8_t> pal::type1_message::as_bytes() const { uint8_t message[16] = { 'N', 'T', 'L', 'M', 'S', 'S', 'P', '0', 0x01, 0x00, 0x00, 0x00, 0, 0, 0, 0 }; const std::size_t ssp_flags_offset = 12; pal::write_little_endian_from_uint32(&message[ssp_flags_offset], ssp_flags_); return std::vector<uint8_t>(message, message + sizeof message); }
  • 73. #include "type1_message.hpp" #include "tools.hpp" /* This is better * See http://davenport.sourceforge.net/ntlm.html * * Type 1 Message * * 0 NTLMSSP Signature "NTLMSSP0" * 8 NTLM Message Type {0x01,0x00,0x00,0x00} * 12 Flags uint32 as little endian * (16) Supplied Domain (optional) (security buffer) * (24) Supplied Workstation (optional) (security buffer) * (32) (start of datablock) if required */ pal::type1_message::type1_message(uint32_t ssp_flags) : ssp_flags_(ssp_flags) { } std::vector<uint8_t> pal::type1_message::as_bytes() const { uint8_t message[16] = { 'N', 'T', 'L', 'M', 'S', 'S', 'P', '0', 0x01, 0x00, 0x00, 0x00, 0, 0, 0, 0 }; const std::size_t ssp_flags_offset = 12; pal::write_little_endian_from_uint32(&message[ssp_flags_offset], ssp_flags_); return std::vector<uint8_t>(message, message + sizeof message); }
  • 75. #ifndef PAL_TYPE2_MESSAGE_HPP_INCLUDED #define PAL_TYPE2_MESSAGE_HPP_INCLUDED #include "ntlm_message.hpp" using namespace std; namespace pal { class type2_message : public ntlm_message { public: explicit type2_message(vector<uint8_t> buffer); virtual vector<uint8_t> as_bytes() const; uint32_t ssp_flags(); uint64_t challenge(); private: const vector<uint8_t> buffer_; }; } #endif
  • 76. Find 3 issues #ifndef PAL_TYPE2_MESSAGE_HPP_INCLUDED #define PAL_TYPE2_MESSAGE_HPP_INCLUDED #include "ntlm_message.hpp" using namespace std; namespace pal { class type2_message : public ntlm_message { public: explicit type2_message(vector<uint8_t> buffer); virtual vector<uint8_t> as_bytes() const; uint32_t ssp_flags(); uint64_t challenge(); private: const vector<uint8_t> buffer_; }; } #endif
  • 77. #ifndef PAL_TYPE2_MESSAGE_HPP_INCLUDED #define PAL_TYPE2_MESSAGE_HPP_INCLUDED #include "ntlm_message.hpp" using namespace std; namespace pal { class type2_message : public ntlm_message { public: explicit type2_message(vector<uint8_t> buffer); virtual vector<uint8_t> as_bytes() const; uint32_t ssp_flags(); uint64_t challenge(); private: const vector<uint8_t> buffer_; }; } #endif
  • 78. Ouch, do not import namespaces in header files! #ifndef PAL_TYPE2_MESSAGE_HPP_INCLUDED #define PAL_TYPE2_MESSAGE_HPP_INCLUDED #include "ntlm_message.hpp" using namespace std; namespace pal { class type2_message : public ntlm_message { public: explicit type2_message(vector<uint8_t> buffer); virtual vector<uint8_t> as_bytes() const; uint32_t ssp_flags(); uint64_t challenge(); private: const vector<uint8_t> buffer_; }; } #endif
  • 79. #ifndef PAL_TYPE2_MESSAGE_HPP_INCLUDED #define PAL_TYPE2_MESSAGE_HPP_INCLUDED #include "ntlm_message.hpp" using namespace std; namespace pal { class type2_message : public ntlm_message { public: explicit type2_message(vector<uint8_t> buffer); virtual vector<uint8_t> as_bytes() const; uint32_t ssp_flags(); uint64_t challenge(); private: const vector<uint8_t> buffer_; }; } #endif
  • 80. pass this vector as const & #ifndef PAL_TYPE2_MESSAGE_HPP_INCLUDED #define PAL_TYPE2_MESSAGE_HPP_INCLUDED #include "ntlm_message.hpp" using namespace std; namespace pal { class type2_message : public ntlm_message { public: explicit type2_message(vector<uint8_t> buffer); virtual vector<uint8_t> as_bytes() const; uint32_t ssp_flags(); uint64_t challenge(); private: const vector<uint8_t> buffer_; }; } #endif
  • 81. #ifndef PAL_TYPE2_MESSAGE_HPP_INCLUDED #define PAL_TYPE2_MESSAGE_HPP_INCLUDED #include "ntlm_message.hpp" using namespace std; namespace pal { class type2_message : public ntlm_message { public: explicit type2_message(vector<uint8_t> buffer); virtual vector<uint8_t> as_bytes() const; uint32_t ssp_flags(); uint64_t challenge(); private: const vector<uint8_t> buffer_; }; } #endif
  • 82. this looks like query methods, they should probably be const #ifndef PAL_TYPE2_MESSAGE_HPP_INCLUDED #define PAL_TYPE2_MESSAGE_HPP_INCLUDED #include "ntlm_message.hpp" using namespace std; namespace pal { class type2_message : public ntlm_message { public: explicit type2_message(vector<uint8_t> buffer); virtual vector<uint8_t> as_bytes() const; uint32_t ssp_flags(); uint64_t challenge(); private: const vector<uint8_t> buffer_; }; } #endif
  • 83. #ifndef PAL_TYPE2_MESSAGE_HPP_INCLUDED #define PAL_TYPE2_MESSAGE_HPP_INCLUDED #include "ntlm_message.hpp" using namespace std; namespace pal { class type2_message : public ntlm_message { public: explicit type2_message(vector<uint8_t> buffer); virtual vector<uint8_t> as_bytes() const; uint32_t ssp_flags(); uint64_t challenge(); private: const vector<uint8_t> buffer_; }; } #endif
  • 84. #ifndef PAL_TYPE2_MESSAGE_HPP_INCLUDED #define PAL_TYPE2_MESSAGE_HPP_INCLUDED #include "ntlm_message.hpp" namespace pal { class type2_message : public ntlm_message { public: explicit type2_message(vector<uint8_t> buffer); virtual vector<uint8_t> as_bytes() const; uint32_t ssp_flags(); uint64_t challenge(); private: const vector<uint8_t> buffer_; }; } #endif
  • 85. #ifndef PAL_TYPE2_MESSAGE_HPP_INCLUDED #define PAL_TYPE2_MESSAGE_HPP_INCLUDED #include "ntlm_message.hpp" namespace pal { class type2_message : public ntlm_message { public: explicit type2_message(vector<uint8_t> buffer); virtual vector<uint8_t> as_bytes() const; uint32_t ssp_flags(); uint64_t challenge(); private: const vector<uint8_t> buffer_; }; } #endif
  • 86. #ifndef PAL_TYPE2_MESSAGE_HPP_INCLUDED #define PAL_TYPE2_MESSAGE_HPP_INCLUDED #include "ntlm_message.hpp" namespace pal { class type2_message : public ntlm_message { public: explicit type2_message( vector<uint8_t> buffer); virtual vector<uint8_t> as_bytes() const; uint32_t ssp_flags(); uint64_t challenge(); private: const vector<uint8_t> buffer_; }; } #endif
  • 87. #ifndef PAL_TYPE2_MESSAGE_HPP_INCLUDED #define PAL_TYPE2_MESSAGE_HPP_INCLUDED #include "ntlm_message.hpp" namespace pal { class type2_message : public ntlm_message { public: explicit type2_message(std::vector<uint8_t> buffer); virtual std::vector<uint8_t> as_bytes() const; uint32_t ssp_flags(); uint64_t challenge(); private: const std::vector<uint8_t> buffer_; }; } #endif
  • 88. #ifndef PAL_TYPE2_MESSAGE_HPP_INCLUDED #define PAL_TYPE2_MESSAGE_HPP_INCLUDED #include "ntlm_message.hpp" namespace pal { class type2_message : public ntlm_message { public: explicit type2_message(std::vector<uint8_t> buffer); virtual std::vector<uint8_t> as_bytes() const; uint32_t ssp_flags(); uint64_t challenge(); private: const std::vector<uint8_t> buffer_; }; } #endif
  • 89. #ifndef PAL_TYPE2_MESSAGE_HPP_INCLUDED #define PAL_TYPE2_MESSAGE_HPP_INCLUDED #include "ntlm_message.hpp" namespace pal { class type2_message : public ntlm_message { public: explicit type2_message(std::vector<uint8_t> buffer); virtual std::vector<uint8_t> as_bytes() const; uint32_t ssp_flags(); uint64_t challenge(); private: const std::vector<uint8_t> buffer_; }; } #endif
  • 90. #ifndef PAL_TYPE2_MESSAGE_HPP_INCLUDED #define PAL_TYPE2_MESSAGE_HPP_INCLUDED #include "ntlm_message.hpp" namespace pal { class type2_message : public ntlm_message { public: explicit type2_message(std::vector<uint8_t> buffer); virtual std::vector<uint8_t> as_bytes() const; uint32_t ssp_flags(); uint64_t challenge(); private: const std::vector<uint8_t> buffer_; }; } #endif
  • 91. #ifndef PAL_TYPE2_MESSAGE_HPP_INCLUDED #define PAL_TYPE2_MESSAGE_HPP_INCLUDED #include "ntlm_message.hpp" namespace pal { class type2_message : public ntlm_message { public: explicit type2_message( std::vector<uint8_t> buffer); virtual std::vector<uint8_t> as_bytes() const; uint32_t ssp_flags(); uint64_t challenge(); private: const std::vector<uint8_t> buffer_; }; } #endif
  • 92. #ifndef PAL_TYPE2_MESSAGE_HPP_INCLUDED #define PAL_TYPE2_MESSAGE_HPP_INCLUDED #include "ntlm_message.hpp" namespace pal { class type2_message : public ntlm_message { public: explicit type2_message(const std::vector<uint8_t> & buffer); virtual std::vector<uint8_t> as_bytes() const; uint32_t ssp_flags(); uint64_t challenge(); private: const std::vector<uint8_t> buffer_; }; } #endif
  • 93. #ifndef PAL_TYPE2_MESSAGE_HPP_INCLUDED #define PAL_TYPE2_MESSAGE_HPP_INCLUDED #include "ntlm_message.hpp" namespace pal { class type2_message : public ntlm_message { public: explicit type2_message(const std::vector<uint8_t> & buffer); virtual std::vector<uint8_t> as_bytes() const; uint32_t ssp_flags(); uint64_t challenge(); private: const std::vector<uint8_t> buffer_; }; } #endif
  • 94. #ifndef PAL_TYPE2_MESSAGE_HPP_INCLUDED #define PAL_TYPE2_MESSAGE_HPP_INCLUDED #include "ntlm_message.hpp" namespace pal { class type2_message : public ntlm_message { public: explicit type2_message(const std::vector<uint8_t> & buffer); virtual std::vector<uint8_t> as_bytes() const; uint32_t ssp_flags() const; uint64_t challenge() const; private: const std::vector<uint8_t> buffer_; }; } #endif
  • 95. #ifndef PAL_TYPE2_MESSAGE_HPP_INCLUDED #define PAL_TYPE2_MESSAGE_HPP_INCLUDED #include "ntlm_message.hpp" namespace pal { class type2_message : public ntlm_message { public: explicit type2_message(const std::vector<uint8_t> & buffer); virtual std::vector<uint8_t> as_bytes() const; uint32_t ssp_flags() const; uint64_t challenge() const; private: const std::vector<uint8_t> buffer_; }; } #endif
  • 96. This looks like Solid C++ #ifndef PAL_TYPE2_MESSAGE_HPP_INCLUDED #define PAL_TYPE2_MESSAGE_HPP_INCLUDED #include "ntlm_message.hpp" namespace pal { class type2_message : public ntlm_message { public: explicit type2_message(const std::vector<uint8_t> & buffer); virtual std::vector<uint8_t> as_bytes() const; uint32_t ssp_flags() const; uint64_t challenge() const; private: const std::vector<uint8_t> buffer_; }; } #endif
  • 98. ... page 1 of 2 #include <cstddef> #include <algorithm> #include <stdexcept> #include "tools.hpp" #include "type2_message.hpp" /* * See http://davenport.sourceforge.net/ntlm.html * * Type 2 Message * * 0 NTLMSSP Signature {'N','T','L','M','S','S','P','0'} * 8 NTLM Message Type {0x02,0x00,0x00,0x00} * 12 Target Name (security buffer) * 20 Flags uint32 as little endian * 24 Challenge 8 bytes / uint64 as little endian * (32) Context (optional) 8 bytes (2xlong) * (40) Target Information (security buffer) * (48) (start of datablock) * targetname * targetinfo * server (type=0x0100, len, data) * domain (type=0x0200, len, data) * dnsserver (type=0x0300, len, data) * dnsdomain (type=0x0400, len, data) * type5 (type=0x0500, len, data) // unknown role * <terminator> (type=0,len=0) */ ...
  • 99. ... page 1 of 2 #include <cstddef> Find one issue #include <algorithm> #include <stdexcept> #include "tools.hpp" #include "type2_message.hpp" /* * See http://davenport.sourceforge.net/ntlm.html * * Type 2 Message * * 0 NTLMSSP Signature {'N','T','L','M','S','S','P','0'} * 8 NTLM Message Type {0x02,0x00,0x00,0x00} * 12 Target Name (security buffer) * 20 Flags uint32 as little endian * 24 Challenge 8 bytes / uint64 as little endian * (32) Context (optional) 8 bytes (2xlong) * (40) Target Information (security buffer) * (48) (start of datablock) * targetname * targetinfo * server (type=0x0100, len, data) * domain (type=0x0200, len, data) * dnsserver (type=0x0300, len, data) * dnsdomain (type=0x0400, len, data) * type5 (type=0x0500, len, data) // unknown role * <terminator> (type=0,len=0) */ ...
  • 100. ... page 1 of 2 #include <cstddef> #include <algorithm> #include <stdexcept> #include "tools.hpp" #include "type2_message.hpp" /* * See http://davenport.sourceforge.net/ntlm.html * * Type 2 Message * * 0 NTLMSSP Signature {'N','T','L','M','S','S','P','0'} * 8 NTLM Message Type {0x02,0x00,0x00,0x00} * 12 Target Name (security buffer) * 20 Flags uint32 as little endian * 24 Challenge 8 bytes / uint64 as little endian * (32) Context (optional) 8 bytes (2xlong) * (40) Target Information (security buffer) * (48) (start of datablock) * targetname * targetinfo * server (type=0x0100, len, data) * domain (type=0x0200, len, data) * dnsserver (type=0x0300, len, data) * dnsdomain (type=0x0400, len, data) * type5 (type=0x0500, len, data) // unknown role * <terminator> (type=0,len=0) */ ...
  • 101. ... page 1 of 2 this is not a good way #include <cstddef> #include <algorithm> to order the include files #include <stdexcept> #include "tools.hpp" #include "type2_message.hpp" /* * See http://davenport.sourceforge.net/ntlm.html * * Type 2 Message * * 0 NTLMSSP Signature {'N','T','L','M','S','S','P','0'} * 8 NTLM Message Type {0x02,0x00,0x00,0x00} * 12 Target Name (security buffer) * 20 Flags uint32 as little endian * 24 Challenge 8 bytes / uint64 as little endian * (32) Context (optional) 8 bytes (2xlong) * (40) Target Information (security buffer) * (48) (start of datablock) * targetname * targetinfo * server (type=0x0100, len, data) * domain (type=0x0200, len, data) * dnsserver (type=0x0300, len, data) * dnsdomain (type=0x0400, len, data) * type5 (type=0x0500, len, data) // unknown role * <terminator> (type=0,len=0) */ ...
  • 102. ... page 1 of 2 #include <cstddef> #include <algorithm> #include <stdexcept> #include "tools.hpp" #include "type2_message.hpp" /* * See http://davenport.sourceforge.net/ntlm.html * * Type 2 Message * * 0 NTLMSSP Signature {'N','T','L','M','S','S','P','0'} * 8 NTLM Message Type {0x02,0x00,0x00,0x00} * 12 Target Name (security buffer) * 20 Flags uint32 as little endian * 24 Challenge 8 bytes / uint64 as little endian * (32) Context (optional) 8 bytes (2xlong) * (40) Target Information (security buffer) * (48) (start of datablock) * targetname * targetinfo * server (type=0x0100, len, data) * domain (type=0x0200, len, data) * dnsserver (type=0x0300, len, data) * dnsdomain (type=0x0400, len, data) * type5 (type=0x0500, len, data) // unknown role * <terminator> (type=0,len=0) */ ...
  • 103. ... page 1 of 2 #include <cstddef> #include <algorithm> #include <stdexcept> #include "tools.hpp" #include "type2_message.hpp" /* * See http://davenport.sourceforge.net/ntlm.html * * Type 2 Message * * 0 NTLMSSP Signature {'N','T','L','M','S','S','P','0'} * 8 NTLM Message Type {0x02,0x00,0x00,0x00} * 12 Target Name (security buffer) * 20 Flags uint32 as little endian * 24 Challenge 8 bytes / uint64 as little endian * (32) Context (optional) 8 bytes (2xlong) * (40) Target Information (security buffer) * (48) (start of datablock) * targetname * targetinfo * server (type=0x0100, len, data) * domain (type=0x0200, len, data) * dnsserver (type=0x0300, len, data) * dnsdomain (type=0x0400, len, data) * type5 (type=0x0500, len, data) // unknown role * <terminator> (type=0,len=0) */ ...
  • 104. ... page 1 of 2 #include "type2_message.hpp" #include "tools.hpp" #include <cstddef> #include <algorithm> #include <stdexcept> /* * See http://davenport.sourceforge.net/ntlm.html * * Type 2 Message * * 0 NTLMSSP Signature {'N','T','L','M','S','S','P','0'} * 8 NTLM Message Type {0x02,0x00,0x00,0x00} * 12 Target Name (security buffer) * 20 Flags uint32 as little endian * 24 Challenge 8 bytes / uint64 as little endian * (32) Context (optional) 8 bytes (2xlong) * (40) Target Information (security buffer) * (48) (start of datablock) * targetname * targetinfo * server (type=0x0100, len, data) * domain (type=0x0200, len, data) * dnsserver (type=0x0300, len, data) * dnsdomain (type=0x0400, len, data) * type5 (type=0x0500, len, data) // unknown role * <terminator> (type=0,len=0) */ ...
  • 105. ... page 2 of 2 pal::type2_message::type2_message(const std::vector<uint8_t> & buffer) : buffer_(buffer) { const std::size_t min_type2_buffer_size = 32; if (buffer.size() < min_type2_buffer_size) throw std::invalid_argument("not a type2 message, message too short"); const uint8_t prefix[12] = { 'N','T','L','M','S','S','P','0', 0x02,0x00,0x00,0x00 }; if (!std::equal(prefix, prefix + sizeof(prefix), buffer.begin())) throw std::invalid_argument("not a type2 message, invalid prefix"); } uint32_t pal::type2_message::ssp_flags() const { return pal::read_uint32_from_little_endian(&buffer_[20]); } uint64_t pal::type2_message::challenge() const { return pal::read_uint64_from_little_endian(&buffer_[24]); } std::vector<uint8_t> pal::type2_message::as_bytes() const { return (buffer_); }
  • 106. ... page 2 of 2 pal::type2_message::type2_message(const std::vector<uint8_t> & buffer) : buffer_(buffer) { const std::size_t min_type2_buffer_size = 32; if (buffer.size() < min_type2_buffer_size) throw std::invalid_argument("not a type2 message, message too short"); const uint8_t prefix[12] = { 'N','T','L','M','S','S','P','0', 0x02,0x00,0x00,0x00 }; if (!std::equal(prefix, prefix + sizeof(prefix), buffer.begin())) throw std::invalid_argument("not a type2 message, invalid prefix"); } uint32_t pal::type2_message::ssp_flags() const { return pal::read_uint32_from_little_endian(&buffer_[20]); } uint64_t pal::type2_message::challenge() const { return pal::read_uint64_from_little_endian(&buffer_[24]); } std::vector<uint8_t> pal::type2_message::as_bytes() const { return (buffer_); } Any issues here?
  • 107. ... page 2 of 2 pal::type2_message::type2_message(const std::vector<uint8_t> & buffer) : buffer_(buffer) { const std::size_t min_type2_buffer_size = 32; if (buffer.size() < min_type2_buffer_size) throw std::invalid_argument("not a type2 message, message too short"); const uint8_t prefix[12] = { 'N','T','L','M','S','S','P','0', 0x02,0x00,0x00,0x00 }; if (!std::equal(prefix, prefix + sizeof(prefix), buffer.begin())) throw std::invalid_argument("not a type2 message, invalid prefix"); } uint32_t pal::type2_message::ssp_flags() const { return pal::read_uint32_from_little_endian(&buffer_[20]); } uint64_t pal::type2_message::challenge() const { return pal::read_uint64_from_little_endian(&buffer_[24]); } std::vector<uint8_t> pal::type2_message::as_bytes() const { return (buffer_); }
  • 108. ... page 2 of 2 magic numbers pal::type2_message::type2_message(const std::vector<uint8_t> & buffer) : buffer_(buffer) { const std::size_t min_type2_buffer_size = 32; if (buffer.size() < min_type2_buffer_size) throw std::invalid_argument("not a type2 message, message too short"); const uint8_t prefix[12] = { 'N','T','L','M','S','S','P','0', 0x02,0x00,0x00,0x00 }; if (!std::equal(prefix, prefix + sizeof(prefix), buffer.begin())) throw std::invalid_argument("not a type2 message, invalid prefix"); } uint32_t pal::type2_message::ssp_flags() const { return pal::read_uint32_from_little_endian(&buffer_[20]); } uint64_t pal::type2_message::challenge() const { return pal::read_uint64_from_little_endian(&buffer_[24]); } std::vector<uint8_t> pal::type2_message::as_bytes() const { return (buffer_); }
  • 109. ... page 2 of 2 pal::type2_message::type2_message(const std::vector<uint8_t> & buffer) : buffer_(buffer) { const std::size_t min_type2_buffer_size = 32; if (buffer.size() < min_type2_buffer_size) throw std::invalid_argument("not a type2 message, message too short"); const uint8_t prefix[12] = { 'N','T','L','M','S','S','P','0', 0x02,0x00,0x00,0x00 }; if (!std::equal(prefix, prefix + sizeof(prefix), buffer.begin())) throw std::invalid_argument("not a type2 message, invalid prefix"); } uint32_t pal::type2_message::ssp_flags() const { return pal::read_uint32_from_little_endian(&buffer_[20]); } uint64_t pal::type2_message::challenge() const { return pal::read_uint64_from_little_endian(&buffer_[24]); } std::vector<uint8_t> pal::type2_message::as_bytes() const { return (buffer_); }
  • 110. ... page 2 of 2 pal::type2_message::type2_message(const std::vector<uint8_t> & buffer) : buffer_(buffer) { const std::size_t min_type2_buffer_size = 32; if (buffer.size() < min_type2_buffer_size) throw std::invalid_argument("not a type2 message, message too short"); const uint8_t prefix[12] = { 'N','T','L','M','S','S','P','0', 0x02,0x00,0x00,0x00 }; if (!std::equal(prefix, prefix + sizeof(prefix), buffer.begin())) throw std::invalid_argument("not a type2 message, invalid prefix"); } uint32_t pal::type2_message::ssp_flags() const { return pal::read_uint32_from_little_endian(&buffer_[20]); } superfluous use of () uint64_t pal::type2_message::challenge() const { return pal::read_uint64_from_little_endian(&buffer_[24]); } std::vector<uint8_t> pal::type2_message::as_bytes() const { return (buffer_); }
  • 111. ... page 2 of 2 pal::type2_message::type2_message(const std::vector<uint8_t> & buffer) : buffer_(buffer) { const std::size_t min_type2_buffer_size = 32; if (buffer.size() < min_type2_buffer_size) throw std::invalid_argument("not a type2 message, message too short"); const uint8_t prefix[12] = { 'N','T','L','M','S','S','P','0', 0x02,0x00,0x00,0x00 }; if (!std::equal(prefix, prefix + sizeof(prefix), buffer.begin())) throw std::invalid_argument("not a type2 message, invalid prefix"); } uint32_t pal::type2_message::ssp_flags() const { return pal::read_uint32_from_little_endian(&buffer_[20]); } superfluous use of () uint64_t pal::type2_message::challenge() const { return pal::read_uint64_from_little_endian(&buffer_[24]); } std::vector<uint8_t> pal::type2_message::as_bytes() const { return (buffer_); }
  • 112. ... page 2 of 2 pal::type2_message::type2_message(const std::vector<uint8_t> & buffer) : buffer_(buffer) { const std::size_t min_type2_buffer_size = 32; if (buffer.size() < min_type2_buffer_size) throw std::invalid_argument("not a type2 message, message too short"); const uint8_t prefix[12] = { 'N','T','L','M','S','S','P','0', 0x02,0x00,0x00,0x00 }; if (!std::equal(prefix, prefix + sizeof((prefix)), buffer.begin())) throw std::invalid_argument("not a type2 message, invalid prefix"); } uint32_t pal::type2_message::ssp_flags() const { } so you really like () do you? return pal::read_uint32_from_little_endian(&buffer_[20]); uint64_t Why not add a few more? pal::type2_message::challenge() const { return pal::read_uint64_from_little_endian(&buffer_[24]); } std::vector<uint8_t> pal::type2_message::as_bytes() const { return (((buffer_))); }
  • 113. ... page 2 of 2 pal::type2_message::type2_message(const std::vector<uint8_t> & buffer) : buffer_(buffer) { const std::size_t min_type2_buffer_size = (32); if (buffer.size() < min_type2_buffer_size) throw std::invalid_argument("not a type2 message, message too short"); const uint8_t prefix[12] = { 'N','T','L','M','S','S','P','0', 0x02,0x00,0x00,0x00 }; if (!std::equal(prefix, prefix + sizeof((prefix)), buffer.begin())) throw std::invalid_argument("not a type2 message, invalid prefix"); } uint32_t pal::type2_message::ssp_flags() const { } so you really like () do you? return pal::read_uint32_from_little_endian(&buffer_[20]); uint64_t Why not add a few more? pal::type2_message::challenge() const { return pal::read_uint64_from_little_endian(&buffer_[24]); } std::vector<uint8_t> pal::type2_message::as_bytes() const { return (((buffer_))); }
  • 114. ... page 2 of 2 pal::type2_message::type2_message(const std::vector<uint8_t> & buffer) : buffer_(buffer) { const std::size_t min_type2_buffer_size = 32; if (buffer.size() < min_type2_buffer_size) throw std::invalid_argument("not a type2 message, message too short"); const uint8_t prefix[12] = { 'N','T','L','M','S','S','P','0', 0x02,0x00,0x00,0x00 }; if (!std::equal(prefix, prefix + sizeof(prefix), buffer.begin())) throw std::invalid_argument("not a type2 message, invalid prefix"); } uint32_t pal::type2_message::ssp_flags() const { return pal::read_uint32_from_little_endian(&buffer_[20]); } uint64_t pal::type2_message::challenge() const { return pal::read_uint64_from_little_endian(&buffer_[24]); } std::vector<uint8_t> pal::type2_message::as_bytes() const { return (buffer_); }
  • 115. ... page 2 of 2 pal::type2_message::type2_message(const std::vector<uint8_t> & buffer) : buffer_(buffer) { const std::size_t min_type2_buffer_size = 32; if (buffer.size() < min_type2_buffer_size) throw std::invalid_argument("not a type2 message, message too short"); const uint8_t prefix[12] = { 'N','T','L','M','S','S','P','0', 0x02,0x00,0x00,0x00 }; if (!std::equal(prefix, prefix + sizeof(prefix), buffer.begin())) throw std::invalid_argument("not a type2 message, invalid prefix"); } uint32_t pal::type2_message::ssp_flags() const { return pal::read_uint32_from_little_endian(&buffer_[20]); } uint64_t pal::type2_message::challenge() const { return pal::read_uint64_from_little_endian(&buffer_[24]); } std::vector<uint8_t> pal::type2_message::as_bytes() const { return (buffer_); }
  • 116. ... page 2 of 2 pal::type2_message::type2_message(const std::vector<uint8_t> & buffer) : buffer_(buffer) { const std::size_t min_type2_buffer_size = 32; if (buffer.size() < min_type2_buffer_size) throw std::invalid_argument("not a type2 message, message too short"); const uint8_t prefix[12] = { 'N','T','L','M','S','S','P','0', 0x02,0x00,0x00,0x00 }; if (!std::equal(prefix, prefix + sizeof(prefix), buffer.begin())) throw std::invalid_argument("not a type2 message, invalid prefix"); } uint32_t pal::type2_message::ssp_flags() const { return pal::read_uint32_from_little_endian(&buffer_[20]); } uint64_t pal::type2_message::challenge() const { return pal::read_uint64_from_little_endian(&buffer_[24]); } std::vector<uint8_t> pal::type2_message::as_bytes() const { return (buffer_); }
  • 117. ... page 2 of 2 pal::type2_message::type2_message(const std::vector<uint8_t> & buffer) : buffer_(buffer) { const std::size_t min_type2_buffer_size = 32; if (buffer.size() < min_type2_buffer_size) throw std::invalid_argument("not a type2 message, message too short"); const uint8_t prefix[12] = { 'N','T','L','M','S','S','P','0', 0x02,0x00,0x00,0x00 }; if (!std::equal(prefix, prefix + sizeof(prefix), buffer.begin())) throw std::invalid_argument("not a type2 message, invalid prefix"); } uint32_t pal::type2_message::ssp_flags() const { return pal::read_uint32_from_little_endian(&buffer_[20]); } uint64_t pal::type2_message::challenge() const { return pal::read_uint64_from_little_endian(&buffer_[24]); } std::vector<uint8_t> pal::type2_message::as_bytes() const { return (buffer_); }
  • 118. ... page 2 of 2 pal::type2_message::type2_message(const std::vector<uint8_t> & buffer) : buffer_(buffer) { const std::size_t min_type2_buffer_size = 32; if (buffer.size() < min_type2_buffer_size) throw std::invalid_argument("not a type2 message, message too short"); const uint8_t prefix[12] = { 'N','T','L','M','S','S','P','0', 0x02,0x00,0x00,0x00 }; if (!std::equal(prefix, prefix + sizeof(prefix), buffer.begin())) throw std::invalid_argument("not a type2 message, invalid prefix"); } uint32_t pal::type2_message::ssp_flags() const { const std::size_t ssp_flags_offset = 20; return pal::read_uint32_from_little_endian(&buffer_[20]); } uint64_t pal::type2_message::challenge() const { const std::size_t challenge_offset = 24; return pal::read_uint64_from_little_endian(&buffer_[24]); } std::vector<uint8_t> pal::type2_message::as_bytes() const { return (buffer_); }
  • 119. ... page 2 of 2 pal::type2_message::type2_message(const std::vector<uint8_t> & buffer) : buffer_(buffer) { const std::size_t min_type2_buffer_size = 32; if (buffer.size() < min_type2_buffer_size) throw std::invalid_argument("not a type2 message, message too short"); const uint8_t prefix[12] = { 'N','T','L','M','S','S','P','0', 0x02,0x00,0x00,0x00 }; if (!std::equal(prefix, prefix + sizeof(prefix), buffer.begin())) throw std::invalid_argument("not a type2 message, invalid prefix"); } uint32_t pal::type2_message::ssp_flags() const { const std::size_t ssp_flags_offset = 20; return pal::read_uint32_from_little_endian(&buffer_[20]); } uint64_t pal::type2_message::challenge() const { const std::size_t challenge_offset = 24; return pal::read_uint64_from_little_endian(&buffer_[24]); } std::vector<uint8_t> pal::type2_message::as_bytes() const { return (buffer_); }
  • 120. ... page 2 of 2 pal::type2_message::type2_message(const std::vector<uint8_t> & buffer) : buffer_(buffer) { const std::size_t min_type2_buffer_size = 32; if (buffer.size() < min_type2_buffer_size) throw std::invalid_argument("not a type2 message, message too short"); const uint8_t prefix[12] = { 'N','T','L','M','S','S','P','0', 0x02,0x00,0x00,0x00 }; if (!std::equal(prefix, prefix + sizeof(prefix), buffer.begin())) throw std::invalid_argument("not a type2 message, invalid prefix"); } uint32_t pal::type2_message::ssp_flags() const { const std::size_t ssp_flags_offset = 20; return pal::read_uint32_from_little_endian(&buffer_[ssp_flags_offset]); } uint64_t pal::type2_message::challenge() const { const std::size_t challenge_offset = 24; return pal::read_uint64_from_little_endian(&buffer_[24]); } std::vector<uint8_t> pal::type2_message::as_bytes() const { return (buffer_); }
  • 121. ... page 2 of 2 pal::type2_message::type2_message(const std::vector<uint8_t> & buffer) : buffer_(buffer) { const std::size_t min_type2_buffer_size = 32; if (buffer.size() < min_type2_buffer_size) throw std::invalid_argument("not a type2 message, message too short"); const uint8_t prefix[12] = { 'N','T','L','M','S','S','P','0', 0x02,0x00,0x00,0x00 }; if (!std::equal(prefix, prefix + sizeof(prefix), buffer.begin())) throw std::invalid_argument("not a type2 message, invalid prefix"); } uint32_t pal::type2_message::ssp_flags() const { const std::size_t ssp_flags_offset = 20; return pal::read_uint32_from_little_endian(&buffer_[ssp_flags_offset]); } uint64_t pal::type2_message::challenge() const { const std::size_t challenge_offset = 24; return pal::read_uint64_from_little_endian(&buffer_[challenge_offset]); } std::vector<uint8_t> pal::type2_message::as_bytes() const { return (buffer_); }
  • 122. ... page 2 of 2 pal::type2_message::type2_message(const std::vector<uint8_t> & buffer) : buffer_(buffer) { const std::size_t min_type2_buffer_size = 32; if (buffer.size() < min_type2_buffer_size) throw std::invalid_argument("not a type2 message, message too short"); const uint8_t prefix[12] = { 'N','T','L','M','S','S','P','0', 0x02,0x00,0x00,0x00 }; if (!std::equal(prefix, prefix + sizeof(prefix), buffer.begin())) throw std::invalid_argument("not a type2 message, invalid prefix"); } uint32_t pal::type2_message::ssp_flags() const { const std::size_t ssp_flags_offset = 20; return pal::read_uint32_from_little_endian(&buffer_[ssp_flags_offset]); } uint64_t pal::type2_message::challenge() const { const std::size_t challenge_offset = 24; return pal::read_uint64_from_little_endian(&buffer_[challenge_offset]); } std::vector<uint8_t> pal::type2_message::as_bytes() const { return (buffer_); }
  • 123. ... page 2 of 2 pal::type2_message::type2_message(const std::vector<uint8_t> & buffer) : buffer_(buffer) { const std::size_t min_type2_buffer_size = 32; if (buffer.size() < min_type2_buffer_size) throw std::invalid_argument("not a type2 message, message too short"); const uint8_t prefix[12] = { 'N','T','L','M','S','S','P','0', 0x02,0x00,0x00,0x00 }; if (!std::equal(prefix, prefix + sizeof prefix , buffer.begin())) throw std::invalid_argument("not a type2 message, invalid prefix"); } uint32_t pal::type2_message::ssp_flags() const { const std::size_t ssp_flags_offset = 20; return pal::read_uint32_from_little_endian(&buffer_[ssp_flags_offset]); } uint64_t pal::type2_message::challenge() const { const std::size_t challenge_offset = 24; return pal::read_uint64_from_little_endian(&buffer_[challenge_offset]); } std::vector<uint8_t> pal::type2_message::as_bytes() const { return (buffer_); }
  • 124. ... page 2 of 2 pal::type2_message::type2_message(const std::vector<uint8_t> & buffer) : buffer_(buffer) { const std::size_t min_type2_buffer_size = 32; if (buffer.size() < min_type2_buffer_size) throw std::invalid_argument("not a type2 message, message too short"); const uint8_t prefix[12] = { 'N','T','L','M','S','S','P','0', 0x02,0x00,0x00,0x00 }; if (!std::equal(prefix, prefix + sizeof prefix , buffer.begin())) throw std::invalid_argument("not a type2 message, invalid prefix"); } uint32_t pal::type2_message::ssp_flags() const { const std::size_t ssp_flags_offset = 20; return pal::read_uint32_from_little_endian(&buffer_[ssp_flags_offset]); } uint64_t pal::type2_message::challenge() const { const std::size_t challenge_offset = 24; return pal::read_uint64_from_little_endian(&buffer_[challenge_offset]); } std::vector<uint8_t> pal::type2_message::as_bytes() const { return (buffer_); }
  • 125. ... page 2 of 2 pal::type2_message::type2_message(const std::vector<uint8_t> & buffer) : buffer_(buffer) { const std::size_t min_type2_buffer_size = 32; if (buffer.size() < min_type2_buffer_size) throw std::invalid_argument("not a type2 message, message too short"); const uint8_t prefix[12] = { 'N','T','L','M','S','S','P','0', 0x02,0x00,0x00,0x00 }; if (!std::equal(prefix, prefix + sizeof prefix , buffer.begin())) throw std::invalid_argument("not a type2 message, invalid prefix"); } uint32_t pal::type2_message::ssp_flags() const { const std::size_t ssp_flags_offset = 20; return pal::read_uint32_from_little_endian(&buffer_[ssp_flags_offset]); } uint64_t pal::type2_message::challenge() const { const std::size_t challenge_offset = 24; return pal::read_uint64_from_little_endian(&buffer_[challenge_offset]); } std::vector<uint8_t> pal::type2_message::as_bytes() const { return buffer_ ; }
  • 126. ... page 2 of 2 pal::type2_message::type2_message(const std::vector<uint8_t> & buffer) : buffer_(buffer) { const std::size_t min_type2_buffer_size = 32; if (buffer.size() < min_type2_buffer_size) throw std::invalid_argument("not a type2 message, message too short"); const uint8_t prefix[12] = { 'N','T','L','M','S','S','P','0', 0x02,0x00,0x00,0x00 }; if (!std::equal(prefix, prefix + sizeof prefix, buffer.begin())) throw std::invalid_argument("not a type2 message, invalid prefix"); } uint32_t pal::type2_message::ssp_flags() const { const std::size_t ssp_flags_offset = 20; return pal::read_uint32_from_little_endian(&buffer_[ssp_flags_offset]); } uint64_t pal::type2_message::challenge() const { const std::size_t challenge_offset = 24; return pal::read_uint64_from_little_endian(&buffer_[challenge_offset]); } std::vector<uint8_t> pal::type2_message::as_bytes() const { return buffer_; }
  • 127. ... page 2 of 2 pal::type2_message::type2_message(const std::vector<uint8_t> & buffer) : buffer_(buffer) { const std::size_t min_type2_buffer_size = 32; if (buffer.size() < min_type2_buffer_size) throw std::invalid_argument("not a type2 message, message too short"); const uint8_t prefix[12] = { 'N','T','L','M','S','S','P','0', 0x02,0x00,0x00,0x00 }; if (!std::equal(prefix, prefix + sizeof prefix, buffer.begin())) throw std::invalid_argument("not a type2 message, invalid prefix"); } uint32_t pal::type2_message::ssp_flags() const { const std::size_t ssp_flags_offset = 20; return pal::read_uint32_from_little_endian(&buffer_[ssp_flags_offset]); } uint64_t pal::type2_message::challenge() const { const std::size_t challenge_offset = 24; return pal::read_uint64_from_little_endian(&buffer_[challenge_offset]); } std::vector<uint8_t> pal::type2_message::as_bytes() const { return buffer_; }
  • 129. #ifndef PAL_TYPE3_MESSAGE_HPP_INCLUDED #define PAL_TYPE3_MESSAGE_HPP_INCLUDED #include "ntlm_message.hpp" #include <string> #include <iostream> namespace pal { class type3_message : public ntlm_message { public: explicit type3_message( const std::vector<uint8_t> & lm_response, const std::vector<uint8_t> & nt_response, const std::string & user, uint32_t ssp_flags = 0x202); virtual std::vector<uint8_t> as_bytes() const; void debug_print(std::ostream & out) const; private: const std::vector<uint8_t> lm_response_; const std::vector<uint8_t> nt_response_; const std::string domain_; const std::string user_; const std::string workstation_; const std::vector<uint8_t> session_key_; const uint32_t ssp_flags_; }; } #endif
  • 130. #ifndef PAL_TYPE3_MESSAGE_HPP_INCLUDED #define PAL_TYPE3_MESSAGE_HPP_INCLUDED Find 3 issues #include "ntlm_message.hpp" #include <string> #include <iostream> namespace pal { class type3_message : public ntlm_message { public: explicit type3_message( const std::vector<uint8_t> & lm_response, const std::vector<uint8_t> & nt_response, const std::string & user, uint32_t ssp_flags = 0x202); virtual std::vector<uint8_t> as_bytes() const; void debug_print(std::ostream & out) const; private: const std::vector<uint8_t> lm_response_; const std::vector<uint8_t> nt_response_; const std::string domain_; const std::string user_; const std::string workstation_; const std::vector<uint8_t> session_key_; const uint32_t ssp_flags_; }; } #endif
  • 131. #ifndef PAL_TYPE3_MESSAGE_HPP_INCLUDED #define PAL_TYPE3_MESSAGE_HPP_INCLUDED #include "ntlm_message.hpp" #include <string> #include <iostream> namespace pal { class type3_message : public ntlm_message { public: explicit type3_message( const std::vector<uint8_t> & lm_response, const std::vector<uint8_t> & nt_response, const std::string & user, uint32_t ssp_flags = 0x202); virtual std::vector<uint8_t> as_bytes() const; void debug_print(std::ostream & out) const; private: const std::vector<uint8_t> lm_response_; const std::vector<uint8_t> nt_response_; const std::string domain_; const std::string user_; const std::string workstation_; const std::vector<uint8_t> session_key_; const uint32_t ssp_flags_; }; } #endif
  • 132. #ifndef PAL_TYPE3_MESSAGE_HPP_INCLUDED #define PAL_TYPE3_MESSAGE_HPP_INCLUDED include <iosfwd> instead #include "ntlm_message.hpp" #include <string> #include <iostream> namespace pal { class type3_message : public ntlm_message { public: explicit type3_message( const std::vector<uint8_t> & lm_response, const std::vector<uint8_t> & nt_response, const std::string & user, uint32_t ssp_flags = 0x202); virtual std::vector<uint8_t> as_bytes() const; void debug_print(std::ostream & out) const; private: const std::vector<uint8_t> lm_response_; const std::vector<uint8_t> nt_response_; const std::string domain_; const std::string user_; const std::string workstation_; const std::vector<uint8_t> session_key_; const uint32_t ssp_flags_; }; } #endif
  • 133. #ifndef PAL_TYPE3_MESSAGE_HPP_INCLUDED #define PAL_TYPE3_MESSAGE_HPP_INCLUDED #include "ntlm_message.hpp" #include <string> #include <iostream> namespace pal { class type3_message : public ntlm_message { public: explicit type3_message( const std::vector<uint8_t> & lm_response, const std::vector<uint8_t> & nt_response, const std::string & user, uint32_t ssp_flags = 0x202); virtual std::vector<uint8_t> as_bytes() const; void debug_print(std::ostream & out) const; private: const std::vector<uint8_t> lm_response_; const std::vector<uint8_t> nt_response_; const std::string domain_; const std::string user_; const std::string workstation_; const std::vector<uint8_t> session_key_; const uint32_t ssp_flags_; }; } #endif
  • 134. #ifndef PAL_TYPE3_MESSAGE_HPP_INCLUDED this default argument is #define PAL_TYPE3_MESSAGE_HPP_INCLUDED #include probably not needed "ntlm_message.hpp" #include <string> #include <iostream> namespace pal { class type3_message : public ntlm_message { public: explicit type3_message( const std::vector<uint8_t> & lm_response, const std::vector<uint8_t> & nt_response, const std::string & user, uint32_t ssp_flags = 0x202); virtual std::vector<uint8_t> as_bytes() const; void debug_print(std::ostream & out) const; private: const std::vector<uint8_t> lm_response_; const std::vector<uint8_t> nt_response_; const std::string domain_; const std::string user_; const std::string workstation_; const std::vector<uint8_t> session_key_; const uint32_t ssp_flags_; }; } #endif
  • 135. #ifndef PAL_TYPE3_MESSAGE_HPP_INCLUDED #define PAL_TYPE3_MESSAGE_HPP_INCLUDED #include "ntlm_message.hpp" #include <string> #include <iostream> namespace pal { class type3_message : public ntlm_message { public: explicit type3_message( const std::vector<uint8_t> & lm_response, const std::vector<uint8_t> & nt_response, const std::string & user, uint32_t ssp_flags = 0x202); virtual std::vector<uint8_t> as_bytes() const; void debug_print(std::ostream & out) const; private: const std::vector<uint8_t> lm_response_; const std::vector<uint8_t> nt_response_; const std::string domain_; const std::string user_; const std::string workstation_; const std::vector<uint8_t> session_key_; const uint32_t ssp_flags_; }; } #endif
  • 136. #ifndef PAL_TYPE3_MESSAGE_HPP_INCLUDED #define PAL_TYPE3_MESSAGE_HPP_INCLUDED useless explicit specifier #include "ntlm_message.hpp" #include <string> #include <iostream> namespace pal { class type3_message : public ntlm_message { public: explicit type3_message( const std::vector<uint8_t> & lm_response, const std::vector<uint8_t> & nt_response, const std::string & user, uint32_t ssp_flags = 0x202); virtual std::vector<uint8_t> as_bytes() const; void debug_print(std::ostream & out) const; private: const std::vector<uint8_t> lm_response_; const std::vector<uint8_t> nt_response_; const std::string domain_; const std::string user_; const std::string workstation_; const std::vector<uint8_t> session_key_; const uint32_t ssp_flags_; }; } #endif
  • 137. #ifndef PAL_TYPE3_MESSAGE_HPP_INCLUDED #define PAL_TYPE3_MESSAGE_HPP_INCLUDED #include "ntlm_message.hpp" #include <string> #include <iostream> namespace pal { class type3_message : public ntlm_message { public: explicit type3_message( const std::vector<uint8_t> & lm_response, const std::vector<uint8_t> & nt_response, const std::string & user, uint32_t ssp_flags = 0x202); virtual std::vector<uint8_t> as_bytes() const; void debug_print(std::ostream & out) const; private: const std::vector<uint8_t> lm_response_; const std::vector<uint8_t> nt_response_; const std::string domain_; const std::string user_; const std::string workstation_; const std::vector<uint8_t> session_key_; const uint32_t ssp_flags_; }; } #endif
  • 138. #ifndef PAL_TYPE3_MESSAGE_HPP_INCLUDED #define PAL_TYPE3_MESSAGE_HPP_INCLUDED #include "ntlm_message.hpp" #include <string> #include <iostream> namespace pal { class type3_message : public ntlm_message { public: explicit type3_message( const std::vector<uint8_t> & lm_response, const std::vector<uint8_t> & nt_response, const std::string & user, uint32_t ssp_flags = 0x202); virtual std::vector<uint8_t> as_bytes() const; void debug_print(std::ostream & out) const; private: const std::vector<uint8_t> lm_response_; const std::vector<uint8_t> nt_response_; const std::string domain_; const std::string user_; const std::string workstation_; const std::vector<uint8_t> session_key_; const uint32_t ssp_flags_; }; } #endif
  • 139. #ifndef PAL_TYPE3_MESSAGE_HPP_INCLUDED #define PAL_TYPE3_MESSAGE_HPP_INCLUDED #include "ntlm_message.hpp" #include <string> #include <iosfwd> namespace pal { class type3_message : public ntlm_message { public: explicit type3_message( const std::vector<uint8_t> & lm_response, const std::vector<uint8_t> & nt_response, const std::string & user, uint32_t ssp_flags = 0x202); virtual std::vector<uint8_t> as_bytes() const; void debug_print(std::ostream & out) const; private: const std::vector<uint8_t> lm_response_; const std::vector<uint8_t> nt_response_; const std::string domain_; const std::string user_; const std::string workstation_; const std::vector<uint8_t> session_key_; const uint32_t ssp_flags_; }; } #endif
  • 140. #ifndef PAL_TYPE3_MESSAGE_HPP_INCLUDED #define PAL_TYPE3_MESSAGE_HPP_INCLUDED #include "ntlm_message.hpp" #include <string> #include <iosfwd> namespace pal { class type3_message : public ntlm_message { public: explicit type3_message( const std::vector<uint8_t> & lm_response, const std::vector<uint8_t> & nt_response, const std::string & user, uint32_t ssp_flags = 0x202); virtual std::vector<uint8_t> as_bytes() const; void debug_print(std::ostream & out) const; private: const std::vector<uint8_t> lm_response_; const std::vector<uint8_t> nt_response_; const std::string domain_; const std::string user_; const std::string workstation_; const std::vector<uint8_t> session_key_; const uint32_t ssp_flags_; }; } #endif
  • 141. #ifndef PAL_TYPE3_MESSAGE_HPP_INCLUDED #define PAL_TYPE3_MESSAGE_HPP_INCLUDED #include "ntlm_message.hpp" #include <string> #include <iosfwd> namespace pal { class type3_message : public ntlm_message { public: explicit type3_message( const std::vector<uint8_t> & lm_response, const std::vector<uint8_t> & nt_response, const std::string & user, uint32_t ssp_flags = 0x202); virtual std::vector<uint8_t> as_bytes() const; void debug_print(std::ostream & out) const; private: const std::vector<uint8_t> lm_response_; const std::vector<uint8_t> nt_response_; const std::string domain_; const std::string user_; const std::string workstation_; const std::vector<uint8_t> session_key_; const uint32_t ssp_flags_; }; } #endif
  • 142. #ifndef PAL_TYPE3_MESSAGE_HPP_INCLUDED #define PAL_TYPE3_MESSAGE_HPP_INCLUDED #include "ntlm_message.hpp" #include <string> #include <iosfwd> namespace pal { class type3_message : public ntlm_message { public: type3_message( const std::vector<uint8_t> & lm_response, const std::vector<uint8_t> & nt_response, const std::string & user, uint32_t ssp_flags = 0x202); virtual std::vector<uint8_t> as_bytes() const; void debug_print(std::ostream & out) const; private: const std::vector<uint8_t> lm_response_; const std::vector<uint8_t> nt_response_; const std::string domain_; const std::string user_; const std::string workstation_; const std::vector<uint8_t> session_key_; const uint32_t ssp_flags_; }; } #endif
  • 143. #ifndef PAL_TYPE3_MESSAGE_HPP_INCLUDED #define PAL_TYPE3_MESSAGE_HPP_INCLUDED #include "ntlm_message.hpp" #include <string> #include <iosfwd> namespace pal { class type3_message : public ntlm_message { public: type3_message( const std::vector<uint8_t> & lm_response, const std::vector<uint8_t> & nt_response, const std::string & user, uint32_t ssp_flags = 0x202); virtual std::vector<uint8_t> as_bytes() const; void debug_print(std::ostream & out) const; private: const std::vector<uint8_t> lm_response_; const std::vector<uint8_t> nt_response_; const std::string domain_; const std::string user_; const std::string workstation_; const std::vector<uint8_t> session_key_; const uint32_t ssp_flags_; }; } #endif