SlideShare a Scribd company logo
1 of 204
Download to read offline
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

What's hot (20)

Top C Language Interview Questions and Answer
Top C Language Interview Questions and AnswerTop C Language Interview Questions and Answer
Top C Language Interview Questions and Answer
 
C vs c++
C vs c++C vs c++
C vs c++
 
C++11
C++11C++11
C++11
 
Smart Pointers in C++
Smart Pointers in C++Smart Pointers in C++
Smart Pointers in C++
 
C++ 11 Features
C++ 11 FeaturesC++ 11 Features
C++ 11 Features
 
C++ presentation
C++ presentationC++ presentation
C++ presentation
 
Chapter 5 Balagurusamy Programming ANSI in c
Chapter 5 Balagurusamy Programming ANSI  in cChapter 5 Balagurusamy Programming ANSI  in c
Chapter 5 Balagurusamy Programming ANSI in c
 
OOP Core Concept
OOP Core ConceptOOP Core Concept
OOP Core Concept
 
Introduction Of C++
Introduction Of C++Introduction Of C++
Introduction Of C++
 
Intro to c++
Intro to c++Intro to c++
Intro to c++
 
OOP in C++
OOP in C++OOP in C++
OOP in C++
 
C function
C functionC function
C function
 
C++ Inheritance
C++ InheritanceC++ Inheritance
C++ Inheritance
 
Introduction to c++ ppt
Introduction to c++ pptIntroduction to c++ ppt
Introduction to c++ ppt
 
Virtual function in C++ Pure Virtual Function
Virtual function in C++ Pure Virtual Function Virtual function in C++ Pure Virtual Function
Virtual function in C++ Pure Virtual Function
 
C++
C++C++
C++
 
Deep drive into rust programming language
Deep drive into rust programming languageDeep drive into rust programming language
Deep drive into rust programming language
 
Operator overloading
Operator overloadingOperator overloading
Operator overloading
 
Object Oriented Programming using C++(UNIT 1)
Object Oriented Programming using C++(UNIT 1)Object Oriented Programming using C++(UNIT 1)
Object Oriented Programming using C++(UNIT 1)
 
LET US C (5th EDITION) CHAPTER 2 ANSWERS
LET US C (5th EDITION) CHAPTER 2 ANSWERSLET US C (5th EDITION) CHAPTER 2 ANSWERS
LET US C (5th EDITION) CHAPTER 2 ANSWERS
 

Similar to Solid C++ by Example

00 C hello world.pptx
00 C hello world.pptx00 C hello world.pptx
00 C hello world.pptxCarla227537
 
CPP Programming Homework Help
CPP Programming Homework HelpCPP Programming Homework Help
CPP Programming Homework HelpC++ Homework Help
 
Cpp17 and Beyond
Cpp17 and BeyondCpp17 and Beyond
Cpp17 and BeyondComicSansMS
 
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 15184
88 c programs 1518488 c programs 15184
88 c programs 15184Sumit 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 IntegrationGlobalLogic Ukraine
 
C++aptitude questions and answers
C++aptitude questions and answersC++aptitude questions and answers
C++aptitude questions and answerssheibansari
 
Hooking signals and dumping the callstack
Hooking signals and dumping the callstackHooking signals and dumping the callstack
Hooking signals and dumping the callstackThierry Gayet
 

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 15184
88 c programs 1518488 c programs 15184
88 c programs 15184
 
88 c-programs
88 c-programs88 c-programs
88 c-programs
 
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

Time Series Foundation Models - current state and future directions
Time Series Foundation Models - current state and future directionsTime Series Foundation Models - current state and future directions
Time Series Foundation Models - current state and future directionsNathaniel Shimoni
 
Gen AI in Business - Global Trends Report 2024.pdf
Gen AI in Business - Global Trends Report 2024.pdfGen AI in Business - Global Trends Report 2024.pdf
Gen AI in Business - Global Trends Report 2024.pdfAddepto
 
What is Artificial Intelligence?????????
What is Artificial Intelligence?????????What is Artificial Intelligence?????????
What is Artificial Intelligence?????????blackmambaettijean
 
Visualising and forecasting stocks using Dash
Visualising and forecasting stocks using DashVisualising and forecasting stocks using Dash
Visualising and forecasting stocks using Dashnarutouzumaki53779
 
Rise of the Machines: Known As Drones...
Rise of the Machines: Known As Drones...Rise of the Machines: Known As Drones...
Rise of the Machines: Known As Drones...Rick Flair
 
DevoxxFR 2024 Reproducible Builds with Apache Maven
DevoxxFR 2024 Reproducible Builds with Apache MavenDevoxxFR 2024 Reproducible Builds with Apache Maven
DevoxxFR 2024 Reproducible Builds with Apache MavenHervé Boutemy
 
SALESFORCE EDUCATION CLOUD | FEXLE SERVICES
SALESFORCE EDUCATION CLOUD | FEXLE SERVICESSALESFORCE EDUCATION CLOUD | FEXLE SERVICES
SALESFORCE EDUCATION CLOUD | FEXLE SERVICESmohitsingh558521
 
A Deep Dive on Passkeys: FIDO Paris Seminar.pptx
A Deep Dive on Passkeys: FIDO Paris Seminar.pptxA Deep Dive on Passkeys: FIDO Paris Seminar.pptx
A Deep Dive on Passkeys: FIDO Paris Seminar.pptxLoriGlavin3
 
Digital Identity is Under Attack: FIDO Paris Seminar.pptx
Digital Identity is Under Attack: FIDO Paris Seminar.pptxDigital Identity is Under Attack: FIDO Paris Seminar.pptx
Digital Identity is Under Attack: FIDO Paris Seminar.pptxLoriGlavin3
 
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptx
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptxPasskey Providers and Enabling Portability: FIDO Paris Seminar.pptx
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptxLoriGlavin3
 
unit 4 immunoblotting technique complete.pptx
unit 4 immunoblotting technique complete.pptxunit 4 immunoblotting technique complete.pptx
unit 4 immunoblotting technique complete.pptxBkGupta21
 
Unraveling Multimodality with Large Language Models.pdf
Unraveling Multimodality with Large Language Models.pdfUnraveling Multimodality with Large Language Models.pdf
Unraveling Multimodality with Large Language Models.pdfAlex Barbosa Coqueiro
 
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek SchlawackFwdays
 
Developer Data Modeling Mistakes: From Postgres to NoSQL
Developer Data Modeling Mistakes: From Postgres to NoSQLDeveloper Data Modeling Mistakes: From Postgres to NoSQL
Developer Data Modeling Mistakes: From Postgres to NoSQLScyllaDB
 
Sample pptx for embedding into website for demo
Sample pptx for embedding into website for demoSample pptx for embedding into website for demo
Sample pptx for embedding into website for demoHarshalMandlekar2
 
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)Mark Simos
 
SIP trunking in Janus @ Kamailio World 2024
SIP trunking in Janus @ Kamailio World 2024SIP trunking in Janus @ Kamailio World 2024
SIP trunking in Janus @ Kamailio World 2024Lorenzo Miniero
 
How to write a Business Continuity Plan
How to write a Business Continuity PlanHow to write a Business Continuity Plan
How to write a Business Continuity PlanDatabarracks
 
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024BookNet Canada
 
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptx
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptxThe Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptx
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptxLoriGlavin3
 

Recently uploaded (20)

Time Series Foundation Models - current state and future directions
Time Series Foundation Models - current state and future directionsTime Series Foundation Models - current state and future directions
Time Series Foundation Models - current state and future directions
 
Gen AI in Business - Global Trends Report 2024.pdf
Gen AI in Business - Global Trends Report 2024.pdfGen AI in Business - Global Trends Report 2024.pdf
Gen AI in Business - Global Trends Report 2024.pdf
 
What is Artificial Intelligence?????????
What is Artificial Intelligence?????????What is Artificial Intelligence?????????
What is Artificial Intelligence?????????
 
Visualising and forecasting stocks using Dash
Visualising and forecasting stocks using DashVisualising and forecasting stocks using Dash
Visualising and forecasting stocks using Dash
 
Rise of the Machines: Known As Drones...
Rise of the Machines: Known As Drones...Rise of the Machines: Known As Drones...
Rise of the Machines: Known As Drones...
 
DevoxxFR 2024 Reproducible Builds with Apache Maven
DevoxxFR 2024 Reproducible Builds with Apache MavenDevoxxFR 2024 Reproducible Builds with Apache Maven
DevoxxFR 2024 Reproducible Builds with Apache Maven
 
SALESFORCE EDUCATION CLOUD | FEXLE SERVICES
SALESFORCE EDUCATION CLOUD | FEXLE SERVICESSALESFORCE EDUCATION CLOUD | FEXLE SERVICES
SALESFORCE EDUCATION CLOUD | FEXLE SERVICES
 
A Deep Dive on Passkeys: FIDO Paris Seminar.pptx
A Deep Dive on Passkeys: FIDO Paris Seminar.pptxA Deep Dive on Passkeys: FIDO Paris Seminar.pptx
A Deep Dive on Passkeys: FIDO Paris Seminar.pptx
 
Digital Identity is Under Attack: FIDO Paris Seminar.pptx
Digital Identity is Under Attack: FIDO Paris Seminar.pptxDigital Identity is Under Attack: FIDO Paris Seminar.pptx
Digital Identity is Under Attack: FIDO Paris Seminar.pptx
 
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptx
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptxPasskey Providers and Enabling Portability: FIDO Paris Seminar.pptx
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptx
 
unit 4 immunoblotting technique complete.pptx
unit 4 immunoblotting technique complete.pptxunit 4 immunoblotting technique complete.pptx
unit 4 immunoblotting technique complete.pptx
 
Unraveling Multimodality with Large Language Models.pdf
Unraveling Multimodality with Large Language Models.pdfUnraveling Multimodality with Large Language Models.pdf
Unraveling Multimodality with Large Language Models.pdf
 
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
 
Developer Data Modeling Mistakes: From Postgres to NoSQL
Developer Data Modeling Mistakes: From Postgres to NoSQLDeveloper Data Modeling Mistakes: From Postgres to NoSQL
Developer Data Modeling Mistakes: From Postgres to NoSQL
 
Sample pptx for embedding into website for demo
Sample pptx for embedding into website for demoSample pptx for embedding into website for demo
Sample pptx for embedding into website for demo
 
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
 
SIP trunking in Janus @ Kamailio World 2024
SIP trunking in Janus @ Kamailio World 2024SIP trunking in Janus @ Kamailio World 2024
SIP trunking in Janus @ Kamailio World 2024
 
How to write a Business Continuity Plan
How to write a Business Continuity PlanHow to write a Business Continuity Plan
How to write a Business Continuity Plan
 
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
 
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptx
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptxThe Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptx
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptx
 

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