Solid C++ code by example - pvv.orgoma/SolidCPP_Sept_2012.pdf · Solid C++ code by example...
Transcript of Solid C++ code by example - pvv.orgoma/SolidCPP_Sept_2012.pdf · Solid C++ code by example...
![Page 1: Solid C++ code by example - pvv.orgoma/SolidCPP_Sept_2012.pdf · Solid C++ code by example olve.maudal@cisco.com Sometimes you see code that is perfectly OK according to the definition](https://reader035.fdocuments.net/reader035/viewer/2022062603/5f07bb087e708231d41e742b/html5/thumbnails/1.jpg)
Solid C++ code by [email protected]
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 3 hour session with students at NTNUTrondheim, September 3, 2012
![Page 2: Solid C++ code by example - pvv.orgoma/SolidCPP_Sept_2012.pdf · Solid C++ code by example olve.maudal@cisco.com Sometimes you see code that is perfectly OK according to the definition](https://reader035.fdocuments.net/reader035/viewer/2022062603/5f07bb087e708231d41e742b/html5/thumbnails/2.jpg)
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
![Page 3: Solid C++ code by example - pvv.orgoma/SolidCPP_Sept_2012.pdf · Solid C++ code by example olve.maudal@cisco.com Sometimes you see code that is perfectly OK according to the definition](https://reader035.fdocuments.net/reader035/viewer/2022062603/5f07bb087e708231d41e742b/html5/thumbnails/3.jpg)
![Page 4: Solid C++ code by example - pvv.orgoma/SolidCPP_Sept_2012.pdf · Solid C++ code by example olve.maudal@cisco.com Sometimes you see code that is perfectly OK according to the definition](https://reader035.fdocuments.net/reader035/viewer/2022062603/5f07bb087e708231d41e742b/html5/thumbnails/4.jpg)
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
![Page 5: Solid C++ code by example - pvv.orgoma/SolidCPP_Sept_2012.pdf · Solid C++ code by example olve.maudal@cisco.com Sometimes you see code that is perfectly OK according to the definition](https://reader035.fdocuments.net/reader035/viewer/2022062603/5f07bb087e708231d41e742b/html5/thumbnails/5.jpg)
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
![Page 6: Solid C++ code by example - pvv.orgoma/SolidCPP_Sept_2012.pdf · Solid C++ code by example olve.maudal@cisco.com Sometimes you see code that is perfectly OK according to the definition](https://reader035.fdocuments.net/reader035/viewer/2022062603/5f07bb087e708231d41e742b/html5/thumbnails/6.jpg)
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
![Page 7: Solid C++ code by example - pvv.orgoma/SolidCPP_Sept_2012.pdf · Solid C++ code by example olve.maudal@cisco.com Sometimes you see code that is perfectly OK according to the definition](https://reader035.fdocuments.net/reader035/viewer/2022062603/5f07bb087e708231d41e742b/html5/thumbnails/7.jpg)
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:- target typically an embedded system- it should be possible and convenient to create a <100kb client using the PAL library- must use C++ (due to PHB decision)- due to compiler support, tr1 and 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
![Page 8: Solid C++ code by example - pvv.orgoma/SolidCPP_Sept_2012.pdf · Solid C++ code by example olve.maudal@cisco.com Sometimes you see code that is perfectly OK according to the definition](https://reader035.fdocuments.net/reader035/viewer/2022062603/5f07bb087e708231d41e742b/html5/thumbnails/8.jpg)
Client Server
The NTLM Protocol (simplified)
![Page 9: Solid C++ code by example - pvv.orgoma/SolidCPP_Sept_2012.pdf · Solid C++ code by example olve.maudal@cisco.com Sometimes you see code that is perfectly OK according to the definition](https://reader035.fdocuments.net/reader035/viewer/2022062603/5f07bb087e708231d41e742b/html5/thumbnails/9.jpg)
Client Serverget resource X
The NTLM Protocol (simplified)
![Page 10: Solid C++ code by example - pvv.orgoma/SolidCPP_Sept_2012.pdf · Solid C++ code by example olve.maudal@cisco.com Sometimes you see code that is perfectly OK according to the definition](https://reader035.fdocuments.net/reader035/viewer/2022062603/5f07bb087e708231d41e742b/html5/thumbnails/10.jpg)
Client Serverget resource X
can you authenticate yourself?
The NTLM Protocol (simplified)
![Page 11: Solid C++ code by example - pvv.orgoma/SolidCPP_Sept_2012.pdf · Solid C++ code by example olve.maudal@cisco.com Sometimes you see code that is perfectly OK according to the definition](https://reader035.fdocuments.net/reader035/viewer/2022062603/5f07bb087e708231d41e742b/html5/thumbnails/11.jpg)
Client Serverget resource X
can you authenticate yourself?
yes, let’s do NTLM. Here is my initial ntlm request(NTLM Type1 Message)
The NTLM Protocol (simplified)
![Page 12: Solid C++ code by example - pvv.orgoma/SolidCPP_Sept_2012.pdf · Solid C++ code by example olve.maudal@cisco.com Sometimes you see code that is perfectly OK according to the definition](https://reader035.fdocuments.net/reader035/viewer/2022062603/5f07bb087e708231d41e742b/html5/thumbnails/12.jpg)
Client Serverget resource X
can you authenticate yourself?
yes, let’s do NTLM. Here is my initial ntlm request(NTLM Type1 Message)
ok. Here is a challenge for you to solve(NTLM Type 2 Message)
The NTLM Protocol (simplified)
![Page 13: Solid C++ code by example - pvv.orgoma/SolidCPP_Sept_2012.pdf · Solid C++ code by example olve.maudal@cisco.com Sometimes you see code that is perfectly OK according to the definition](https://reader035.fdocuments.net/reader035/viewer/2022062603/5f07bb087e708231d41e742b/html5/thumbnails/13.jpg)
Client Serverget resource X
can you authenticate yourself?
yes, let’s do NTLM. Here is my initial ntlm request(NTLM Type1 Message)
ok. Here is a challenge for you to solve(NTLM Type 2 Message)
use password to “solve” the challenge
and create an lm/nt response hash
The NTLM Protocol (simplified)
![Page 14: Solid C++ code by example - pvv.orgoma/SolidCPP_Sept_2012.pdf · Solid C++ code by example olve.maudal@cisco.com Sometimes you see code that is perfectly OK according to the definition](https://reader035.fdocuments.net/reader035/viewer/2022062603/5f07bb087e708231d41e742b/html5/thumbnails/14.jpg)
Client Serverget resource X
can you authenticate yourself?
yes, let’s do NTLM. Here is my initial ntlm request(NTLM Type1 Message)
ok. Here is a challenge for you to solve(NTLM Type 2 Message)
use password to “solve” the challenge
and create an lm/nt response hash I solved the challenge, here is my response
(NTLM Type 3 Message)
The NTLM Protocol (simplified)
![Page 15: Solid C++ code by example - pvv.orgoma/SolidCPP_Sept_2012.pdf · Solid C++ code by example olve.maudal@cisco.com Sometimes you see code that is perfectly OK according to the definition](https://reader035.fdocuments.net/reader035/viewer/2022062603/5f07bb087e708231d41e742b/html5/thumbnails/15.jpg)
Client Serverget resource X
can you authenticate yourself?
yes, let’s do NTLM. Here is my initial ntlm request(NTLM Type1 Message)
ok. Here is a challenge for you to solve(NTLM Type 2 Message)
use password to “solve” the challenge
and create an lm/nt response hash I solved the challenge, here is my response
(NTLM Type 3 Message)
Authentication accepted. Here is resource X
The NTLM Protocol (simplified)
![Page 16: Solid C++ code by example - pvv.orgoma/SolidCPP_Sept_2012.pdf · Solid C++ code by example olve.maudal@cisco.com Sometimes you see code that is perfectly OK according to the definition](https://reader035.fdocuments.net/reader035/viewer/2022062603/5f07bb087e708231d41e742b/html5/thumbnails/16.jpg)
ntlm_message.hpp
type2_message.hpptype2_message.cpp
type1_message.hpptype1_message.cpp
type3_message.hpptype3_message.cpp
pal
Code under discussion
Note: the code under discussion compiles just fine and does exactly what it is supposed to do... but can you suggest improvements?
![Page 17: Solid C++ code by example - pvv.orgoma/SolidCPP_Sept_2012.pdf · Solid C++ code by example olve.maudal@cisco.com Sometimes you see code that is perfectly OK according to the definition](https://reader035.fdocuments.net/reader035/viewer/2022062603/5f07bb087e708231d41e742b/html5/thumbnails/17.jpg)
Handouts(Do not look ahead, wait for instructions)
![Page 18: Solid C++ code by example - pvv.orgoma/SolidCPP_Sept_2012.pdf · Solid C++ code by example olve.maudal@cisco.com Sometimes you see code that is perfectly OK according to the definition](https://reader035.fdocuments.net/reader035/viewer/2022062603/5f07bb087e708231d41e742b/html5/thumbnails/18.jpg)
ntlm_message.hpp
type2_message.hpptype2_message.cpp
type1_message.hpptype1_message.cpp
type3_message.hpptype3_message.cpp
pal
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:- target typically an embedded system- it should be possible and convenient to create a <100kb client using the PAL library- must use C++ (due to PHB decision)- due to compiler support tr1 and 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
For more info:PAL - a Primitive Authentication Library in C++ for educational purposeshttp://github.com/olvemaudal/pal
Code under discussion
Note: the following code compiles just fine and does exactly what it is supposed to do... can you improve it?
Client Server
get resource X
can you authenticate yourself?
yes, let’s do NTLM. Here is my initial ntlm request(NTLM Type1 Message)
ok. Here is a challenge for you to solve(NTLM Type 2 Message)use password to “solve” the challenge
and create an lm/nt response hashI solved the challenge, here is my response
(NTLM Type 3 Message)
Authentication accepted. Here is resource X
The NTLM Protocol (simplified)
![Page 19: Solid C++ code by example - pvv.orgoma/SolidCPP_Sept_2012.pdf · Solid C++ code by example olve.maudal@cisco.com Sometimes you see code that is perfectly OK according to the definition](https://reader035.fdocuments.net/reader035/viewer/2022062603/5f07bb087e708231d41e742b/html5/thumbnails/19.jpg)
#ifndef NTML#define NTML
#include <vector>
namespace pal { class ntlm_message { public: ~ntlm_message() {} virtual std::vector<uint8_t> as_bytes() const = 0; }; }
#endif // NTLM
pal/ntlm_message.hpp
page 2
![Page 20: Solid C++ code by example - pvv.orgoma/SolidCPP_Sept_2012.pdf · Solid C++ code by example olve.maudal@cisco.com Sometimes you see code that is perfectly OK according to the definition](https://reader035.fdocuments.net/reader035/viewer/2022062603/5f07bb087e708231d41e742b/html5/thumbnails/20.jpg)
#ifndef NTML#define NTML
#include <vector>
namespace pal { class ntlm_message { public: ~ntlm_message() {} virtual std::vector<uint8_t> as_bytes() const = 0; }; }
#endif // NTLM
pal/ntlm_message.hpp
page 2
![Page 21: Solid C++ code by example - pvv.orgoma/SolidCPP_Sept_2012.pdf · Solid C++ code by example olve.maudal@cisco.com Sometimes you see code that is perfectly OK according to the definition](https://reader035.fdocuments.net/reader035/viewer/2022062603/5f07bb087e708231d41e742b/html5/thumbnails/21.jpg)
#ifndef NTML#define NTML
#include <vector>
namespace pal { class ntlm_message { public: ~ntlm_message() {} virtual std::vector<uint8_t> as_bytes() const = 0; }; }
#endif // NTLM
pal/ntlm_message.hpp
page 2
![Page 22: Solid C++ code by example - pvv.orgoma/SolidCPP_Sept_2012.pdf · Solid C++ code by example olve.maudal@cisco.com Sometimes you see code that is perfectly OK according to the definition](https://reader035.fdocuments.net/reader035/viewer/2022062603/5f07bb087e708231d41e742b/html5/thumbnails/22.jpg)
#ifndef NTML#define NTML
#include <vector>
namespace pal { class ntlm_message { public: ~ntlm_message() {} virtual std::vector<uint8_t> as_bytes() const = 0; }; }
#endif // NTLM
pal/ntlm_message.hpp
page 2
![Page 23: Solid C++ code by example - pvv.orgoma/SolidCPP_Sept_2012.pdf · Solid C++ code by example olve.maudal@cisco.com Sometimes you see code that is perfectly OK according to the definition](https://reader035.fdocuments.net/reader035/viewer/2022062603/5f07bb087e708231d41e742b/html5/thumbnails/23.jpg)
#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; }; }
pal/type1_message.hpp
page 3
![Page 24: Solid C++ code by example - pvv.orgoma/SolidCPP_Sept_2012.pdf · Solid C++ code by example olve.maudal@cisco.com Sometimes you see code that is perfectly OK according to the definition](https://reader035.fdocuments.net/reader035/viewer/2022062603/5f07bb087e708231d41e742b/html5/thumbnails/24.jpg)
#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; }; }
pal/type1_message.hpp
page 3
![Page 25: Solid C++ code by example - pvv.orgoma/SolidCPP_Sept_2012.pdf · Solid C++ code by example olve.maudal@cisco.com Sometimes you see code that is perfectly OK according to the definition](https://reader035.fdocuments.net/reader035/viewer/2022062603/5f07bb087e708231d41e742b/html5/thumbnails/25.jpg)
#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; }; }
pal/type1_message.hpp
page 3
![Page 26: Solid C++ code by example - pvv.orgoma/SolidCPP_Sept_2012.pdf · Solid C++ code by example olve.maudal@cisco.com Sometimes you see code that is perfectly OK according to the definition](https://reader035.fdocuments.net/reader035/viewer/2022062603/5f07bb087e708231d41e742b/html5/thumbnails/26.jpg)
#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; }; }
pal/type1_message.hpp
page 3
![Page 27: Solid C++ code by example - pvv.orgoma/SolidCPP_Sept_2012.pdf · Solid C++ code by example olve.maudal@cisco.com Sometimes you see code that is perfectly OK according to the definition](https://reader035.fdocuments.net/reader035/viewer/2022062603/5f07bb087e708231d41e742b/html5/thumbnails/27.jpg)
#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; }; }
pal/type1_message.hpp
page 3
![Page 28: Solid C++ code by example - pvv.orgoma/SolidCPP_Sept_2012.pdf · Solid C++ code by example olve.maudal@cisco.com Sometimes you see code that is perfectly OK according to the definition](https://reader035.fdocuments.net/reader035/viewer/2022062603/5f07bb087e708231d41e742b/html5/thumbnails/28.jpg)
#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; }; }
pal/type1_message.hpp
page 3
![Page 29: Solid C++ code by example - pvv.orgoma/SolidCPP_Sept_2012.pdf · Solid C++ code by example olve.maudal@cisco.com Sometimes you see code that is perfectly OK according to the definition](https://reader035.fdocuments.net/reader035/viewer/2022062603/5f07bb087e708231d41e742b/html5/thumbnails/29.jpg)
#include "type1_message.hpp"
#include "tools.hpp"
/* * See http://davenport.sourceforge.net/ntlm.html * * Type 1 Message * * 0 NTLMSSP Signature "NTLMSSP\0" * 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;
namespace pal { type1_message::type1_message(uint32_t ssp_flags) { ssp_flags_ = ssp_flags; } vector<uint8_t> 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 }; write_little_endian_from_uint32(&message[12], ssp_flags_); return vector<uint8_t>(message, message + sizeof message); }
}
pal/type1_message.cpp
page 4
![Page 30: Solid C++ code by example - pvv.orgoma/SolidCPP_Sept_2012.pdf · Solid C++ code by example olve.maudal@cisco.com Sometimes you see code that is perfectly OK according to the definition](https://reader035.fdocuments.net/reader035/viewer/2022062603/5f07bb087e708231d41e742b/html5/thumbnails/30.jpg)
#include "type1_message.hpp"
#include "tools.hpp"
/* * See http://davenport.sourceforge.net/ntlm.html * * Type 1 Message * * 0 NTLMSSP Signature "NTLMSSP\0" * 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;
namespace pal { type1_message::type1_message(uint32_t ssp_flags) { ssp_flags_ = ssp_flags; } vector<uint8_t> 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 }; write_little_endian_from_uint32(&message[12], ssp_flags_); return vector<uint8_t>(message, message + sizeof message); }
}
pal/type1_message.cpp
page 4
![Page 31: Solid C++ code by example - pvv.orgoma/SolidCPP_Sept_2012.pdf · Solid C++ code by example olve.maudal@cisco.com Sometimes you see code that is perfectly OK according to the definition](https://reader035.fdocuments.net/reader035/viewer/2022062603/5f07bb087e708231d41e742b/html5/thumbnails/31.jpg)
#include "type1_message.hpp"
#include "tools.hpp"
/* * See http://davenport.sourceforge.net/ntlm.html * * Type 1 Message * * 0 NTLMSSP Signature "NTLMSSP\0" * 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;
namespace pal { type1_message::type1_message(uint32_t ssp_flags) { ssp_flags_ = ssp_flags; } vector<uint8_t> 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 }; write_little_endian_from_uint32(&message[12], ssp_flags_); return vector<uint8_t>(message, message + sizeof message); }
}
pal/type1_message.cpp
page 4
![Page 32: Solid C++ code by example - pvv.orgoma/SolidCPP_Sept_2012.pdf · Solid C++ code by example olve.maudal@cisco.com Sometimes you see code that is perfectly OK according to the definition](https://reader035.fdocuments.net/reader035/viewer/2022062603/5f07bb087e708231d41e742b/html5/thumbnails/32.jpg)
#include "type1_message.hpp"
#include "tools.hpp"
/* * See http://davenport.sourceforge.net/ntlm.html * * Type 1 Message * * 0 NTLMSSP Signature "NTLMSSP\0" * 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;
namespace pal { type1_message::type1_message(uint32_t ssp_flags) { ssp_flags_ = ssp_flags; } vector<uint8_t> 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 }; write_little_endian_from_uint32(&message[12], ssp_flags_); return vector<uint8_t>(message, message + sizeof message); }
}
pal/type1_message.cpp
page 4
![Page 33: Solid C++ code by example - pvv.orgoma/SolidCPP_Sept_2012.pdf · Solid C++ code by example olve.maudal@cisco.com Sometimes you see code that is perfectly OK according to the definition](https://reader035.fdocuments.net/reader035/viewer/2022062603/5f07bb087e708231d41e742b/html5/thumbnails/33.jpg)
#include "type1_message.hpp"
#include "tools.hpp"
/* * See http://davenport.sourceforge.net/ntlm.html * * Type 1 Message * * 0 NTLMSSP Signature "NTLMSSP\0" * 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;
namespace pal { type1_message::type1_message(uint32_t ssp_flags) { ssp_flags_ = ssp_flags; } vector<uint8_t> 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 }; write_little_endian_from_uint32(&message[12], ssp_flags_); return vector<uint8_t>(message, message + sizeof message); }
}
pal/type1_message.cpp
page 4
![Page 34: Solid C++ code by example - pvv.orgoma/SolidCPP_Sept_2012.pdf · Solid C++ code by example olve.maudal@cisco.com Sometimes you see code that is perfectly OK according to the definition](https://reader035.fdocuments.net/reader035/viewer/2022062603/5f07bb087e708231d41e742b/html5/thumbnails/34.jpg)
#ifndef PAL_TYPE2_MESSAGE_HPP_INCLUDED#define PAL_TYPE2_MESSAGE_HPP_INCLUDED
#include "ntlm_message.hpp"
#include <stdexcept>
using namespace std;
namespace pal {
class type2_message : public ntlm_message { public: explicit type2_message(vector<uint8_t> buffer) throw(invalid_argument); virtual vector<uint8_t> as_bytes() const; uint32_t ssp_flags(); uint64_t challenge(); private: const vector<uint8_t> buffer_; };
}
#endif
pal/type2_message.hpp
page 5
![Page 35: Solid C++ code by example - pvv.orgoma/SolidCPP_Sept_2012.pdf · Solid C++ code by example olve.maudal@cisco.com Sometimes you see code that is perfectly OK according to the definition](https://reader035.fdocuments.net/reader035/viewer/2022062603/5f07bb087e708231d41e742b/html5/thumbnails/35.jpg)
#ifndef PAL_TYPE2_MESSAGE_HPP_INCLUDED#define PAL_TYPE2_MESSAGE_HPP_INCLUDED
#include "ntlm_message.hpp"
#include <stdexcept>
using namespace std;
namespace pal {
class type2_message : public ntlm_message { public: explicit type2_message(vector<uint8_t> buffer) throw(invalid_argument); virtual vector<uint8_t> as_bytes() const; uint32_t ssp_flags(); uint64_t challenge(); private: const vector<uint8_t> buffer_; };
}
#endif
pal/type2_message.hpp
page 5
![Page 36: Solid C++ code by example - pvv.orgoma/SolidCPP_Sept_2012.pdf · Solid C++ code by example olve.maudal@cisco.com Sometimes you see code that is perfectly OK according to the definition](https://reader035.fdocuments.net/reader035/viewer/2022062603/5f07bb087e708231d41e742b/html5/thumbnails/36.jpg)
#ifndef PAL_TYPE2_MESSAGE_HPP_INCLUDED#define PAL_TYPE2_MESSAGE_HPP_INCLUDED
#include "ntlm_message.hpp"
#include <stdexcept>
using namespace std;
namespace pal {
class type2_message : public ntlm_message { public: explicit type2_message(vector<uint8_t> buffer) throw(invalid_argument); virtual vector<uint8_t> as_bytes() const; uint32_t ssp_flags(); uint64_t challenge(); private: const vector<uint8_t> buffer_; };
}
#endif
pal/type2_message.hpp
page 5
![Page 37: Solid C++ code by example - pvv.orgoma/SolidCPP_Sept_2012.pdf · Solid C++ code by example olve.maudal@cisco.com Sometimes you see code that is perfectly OK according to the definition](https://reader035.fdocuments.net/reader035/viewer/2022062603/5f07bb087e708231d41e742b/html5/thumbnails/37.jpg)
#ifndef PAL_TYPE2_MESSAGE_HPP_INCLUDED#define PAL_TYPE2_MESSAGE_HPP_INCLUDED
#include "ntlm_message.hpp"
#include <stdexcept>
using namespace std;
namespace pal {
class type2_message : public ntlm_message { public: explicit type2_message(vector<uint8_t> buffer) throw(invalid_argument); virtual vector<uint8_t> as_bytes() const; uint32_t ssp_flags(); uint64_t challenge(); private: const vector<uint8_t> buffer_; };
}
#endif
pal/type2_message.hpp
page 5
![Page 38: Solid C++ code by example - pvv.orgoma/SolidCPP_Sept_2012.pdf · Solid C++ code by example olve.maudal@cisco.com Sometimes you see code that is perfectly OK according to the definition](https://reader035.fdocuments.net/reader035/viewer/2022062603/5f07bb087e708231d41e742b/html5/thumbnails/38.jpg)
#ifndef PAL_TYPE2_MESSAGE_HPP_INCLUDED#define PAL_TYPE2_MESSAGE_HPP_INCLUDED
#include "ntlm_message.hpp"
#include <stdexcept>
using namespace std;
namespace pal {
class type2_message : public ntlm_message { public: explicit type2_message(vector<uint8_t> buffer) throw(invalid_argument); virtual vector<uint8_t> as_bytes() const; uint32_t ssp_flags(); uint64_t challenge(); private: const vector<uint8_t> buffer_; };
}
#endif
pal/type2_message.hpp
page 5
![Page 39: Solid C++ code by example - pvv.orgoma/SolidCPP_Sept_2012.pdf · Solid C++ code by example olve.maudal@cisco.com Sometimes you see code that is perfectly OK according to the definition](https://reader035.fdocuments.net/reader035/viewer/2022062603/5f07bb087e708231d41e742b/html5/thumbnails/39.jpg)
#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) */ ...
pal/type2_message.cpp (page 1 of 2)
page 6
![Page 40: Solid C++ code by example - pvv.orgoma/SolidCPP_Sept_2012.pdf · Solid C++ code by example olve.maudal@cisco.com Sometimes you see code that is perfectly OK according to the definition](https://reader035.fdocuments.net/reader035/viewer/2022062603/5f07bb087e708231d41e742b/html5/thumbnails/40.jpg)
#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) */ ...
pal/type2_message.cpp (page 1 of 2)
page 6
![Page 41: Solid C++ code by example - pvv.orgoma/SolidCPP_Sept_2012.pdf · Solid C++ code by example olve.maudal@cisco.com Sometimes you see code that is perfectly OK according to the definition](https://reader035.fdocuments.net/reader035/viewer/2022062603/5f07bb087e708231d41e742b/html5/thumbnails/41.jpg)
pal::type2_message::type2_message(const std::vector<uint8_t> & buffer) : buffer_(buffer) { enum { 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{ enum { ssp_flags_offset = 20 }; return pal::read_uint32_from_little_endian(&buffer_[ssp_flags_offset]);}
uint64_t pal::type2_message::challenge() const{ enum { 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_);}
pal/type2_message.cpp (page 2 of 2)
page 7
![Page 42: Solid C++ code by example - pvv.orgoma/SolidCPP_Sept_2012.pdf · Solid C++ code by example olve.maudal@cisco.com Sometimes you see code that is perfectly OK according to the definition](https://reader035.fdocuments.net/reader035/viewer/2022062603/5f07bb087e708231d41e742b/html5/thumbnails/42.jpg)
pal::type2_message::type2_message(const std::vector<uint8_t> & buffer) : buffer_(buffer) { enum { 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{ enum { ssp_flags_offset = 20 }; return pal::read_uint32_from_little_endian(&buffer_[ssp_flags_offset]);}
uint64_t pal::type2_message::challenge() const{ enum { 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_);}
pal/type2_message.cpp (page 2 of 2)
page 7
![Page 43: Solid C++ code by example - pvv.orgoma/SolidCPP_Sept_2012.pdf · Solid C++ code by example olve.maudal@cisco.com Sometimes you see code that is perfectly OK according to the definition](https://reader035.fdocuments.net/reader035/viewer/2022062603/5f07bb087e708231d41e742b/html5/thumbnails/43.jpg)
pal::type2_message::type2_message(const std::vector<uint8_t> & buffer) : buffer_(buffer) { enum { 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{ enum { ssp_flags_offset = 20 }; return pal::read_uint32_from_little_endian(&buffer_[ssp_flags_offset]);}
uint64_t pal::type2_message::challenge() const{ enum { 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_);}
pal/type2_message.cpp (page 2 of 2)
page 7
![Page 44: Solid C++ code by example - pvv.orgoma/SolidCPP_Sept_2012.pdf · Solid C++ code by example olve.maudal@cisco.com Sometimes you see code that is perfectly OK according to the definition](https://reader035.fdocuments.net/reader035/viewer/2022062603/5f07bb087e708231d41e742b/html5/thumbnails/44.jpg)
#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
pal/type3_message.hpp
page 8
![Page 45: Solid C++ code by example - pvv.orgoma/SolidCPP_Sept_2012.pdf · Solid C++ code by example olve.maudal@cisco.com Sometimes you see code that is perfectly OK according to the definition](https://reader035.fdocuments.net/reader035/viewer/2022062603/5f07bb087e708231d41e742b/html5/thumbnails/45.jpg)
#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
pal/type3_message.hpp
page 8
![Page 46: Solid C++ code by example - pvv.orgoma/SolidCPP_Sept_2012.pdf · Solid C++ code by example olve.maudal@cisco.com Sometimes you see code that is perfectly OK according to the definition](https://reader035.fdocuments.net/reader035/viewer/2022062603/5f07bb087e708231d41e742b/html5/thumbnails/46.jpg)
#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
pal/type3_message.hpp
page 8
![Page 47: Solid C++ code by example - pvv.orgoma/SolidCPP_Sept_2012.pdf · Solid C++ code by example olve.maudal@cisco.com Sometimes you see code that is perfectly OK according to the definition](https://reader035.fdocuments.net/reader035/viewer/2022062603/5f07bb087e708231d41e742b/html5/thumbnails/47.jpg)
#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
pal/type3_message.hpp
page 8
![Page 48: Solid C++ code by example - pvv.orgoma/SolidCPP_Sept_2012.pdf · Solid C++ code by example olve.maudal@cisco.com Sometimes you see code that is perfectly OK according to the definition](https://reader035.fdocuments.net/reader035/viewer/2022062603/5f07bb087e708231d41e742b/html5/thumbnails/48.jpg)
pal::type3_message::type3_message( const std::vector<uint8_t> & lm_response, const std::vector<uint8_t> & nt_response, const std::string & user, uint32_t ssp_flags) : lm_response_(lm_response), nt_response_(nt_response), user_(user), ssp_flags_(ssp_flags), session_key_(session_key_size){ if (lm_response_.size() != lm_response_size) throw new std::invalid_argument("invalid size of lm_response"); if (nt_response_.size() != nt_response_size) throw new std::invalid_argument("invalid size of nt_response");}
...
...
pal/type3_message.cpp (snippet 1 of 2)
page 9
![Page 49: Solid C++ code by example - pvv.orgoma/SolidCPP_Sept_2012.pdf · Solid C++ code by example olve.maudal@cisco.com Sometimes you see code that is perfectly OK according to the definition](https://reader035.fdocuments.net/reader035/viewer/2022062603/5f07bb087e708231d41e742b/html5/thumbnails/49.jpg)
pal::type3_message::type3_message( const std::vector<uint8_t> & lm_response, const std::vector<uint8_t> & nt_response, const std::string & user, uint32_t ssp_flags) : lm_response_(lm_response), nt_response_(nt_response), user_(user), ssp_flags_(ssp_flags), session_key_(session_key_size){ if (lm_response_.size() != lm_response_size) throw new std::invalid_argument("invalid size of lm_response"); if (nt_response_.size() != nt_response_size) throw new std::invalid_argument("invalid size of nt_response");}
...
...
pal/type3_message.cpp (snippet 1 of 2)
page 9
![Page 50: Solid C++ code by example - pvv.orgoma/SolidCPP_Sept_2012.pdf · Solid C++ code by example olve.maudal@cisco.com Sometimes you see code that is perfectly OK according to the definition](https://reader035.fdocuments.net/reader035/viewer/2022062603/5f07bb087e708231d41e742b/html5/thumbnails/50.jpg)
pal::type3_message::type3_message( const std::vector<uint8_t> & lm_response, const std::vector<uint8_t> & nt_response, const std::string & user, uint32_t ssp_flags) : lm_response_(lm_response), nt_response_(nt_response), user_(user), ssp_flags_(ssp_flags), session_key_(session_key_size){ if (lm_response_.size() != lm_response_size) throw new std::invalid_argument("invalid size of lm_response"); if (nt_response_.size() != nt_response_size) throw new std::invalid_argument("invalid size of nt_response");}
...
...
pal/type3_message.cpp (snippet 1 of 2)
page 9
![Page 51: Solid C++ code by example - pvv.orgoma/SolidCPP_Sept_2012.pdf · Solid C++ code by example olve.maudal@cisco.com Sometimes you see code that is perfectly OK according to the definition](https://reader035.fdocuments.net/reader035/viewer/2022062603/5f07bb087e708231d41e742b/html5/thumbnails/51.jpg)
pal::type3_message::type3_message( const std::vector<uint8_t> & lm_response, const std::vector<uint8_t> & nt_response, const std::string & user, uint32_t ssp_flags) : lm_response_(lm_response), nt_response_(nt_response), user_(user), ssp_flags_(ssp_flags), session_key_(session_key_size){ if (lm_response_.size() != lm_response_size) throw new std::invalid_argument("invalid size of lm_response"); if (nt_response_.size() != nt_response_size) throw new std::invalid_argument("invalid size of nt_response");}
...
...
pal/type3_message.cpp (snippet 1 of 2)
page 9
![Page 52: Solid C++ code by example - pvv.orgoma/SolidCPP_Sept_2012.pdf · Solid C++ code by example olve.maudal@cisco.com Sometimes you see code that is perfectly OK according to the definition](https://reader035.fdocuments.net/reader035/viewer/2022062603/5f07bb087e708231d41e742b/html5/thumbnails/52.jpg)
void pal::type3_message::debug_print(std::ostream & out) const{ out << "### type3_message:" << '\n' << pal::as_hex_dump(as_bytes()) << "lm_response = " << pal::as_hex_string(lm_response_) << "\nnt_response = " << pal::as_hex_string(nt_response_) << "\ndomain = " << domain_ << "\nuser = " << user_ << "\nworkstation = " << workstation_ << "\nsession_key = " << pal::as_hex_string(session_key_) << std::hex << std::setw(8) << std::setfill('0') << "\nssp_flags = " << ssp_flags_;}
...
...
pal/type3_message.cpp (snippet 2 of 2)
page 10
![Page 53: Solid C++ code by example - pvv.orgoma/SolidCPP_Sept_2012.pdf · Solid C++ code by example olve.maudal@cisco.com Sometimes you see code that is perfectly OK according to the definition](https://reader035.fdocuments.net/reader035/viewer/2022062603/5f07bb087e708231d41e742b/html5/thumbnails/53.jpg)
void pal::type3_message::debug_print(std::ostream & out) const{ out << "### type3_message:" << '\n' << pal::as_hex_dump(as_bytes()) << "lm_response = " << pal::as_hex_string(lm_response_) << "\nnt_response = " << pal::as_hex_string(nt_response_) << "\ndomain = " << domain_ << "\nuser = " << user_ << "\nworkstation = " << workstation_ << "\nsession_key = " << pal::as_hex_string(session_key_) << std::hex << std::setw(8) << std::setfill('0') << "\nssp_flags = " << ssp_flags_;}
...
...
pal/type3_message.cpp (snippet 2 of 2)
page 10
![Page 54: Solid C++ code by example - pvv.orgoma/SolidCPP_Sept_2012.pdf · Solid C++ code by example olve.maudal@cisco.com Sometimes you see code that is perfectly OK according to the definition](https://reader035.fdocuments.net/reader035/viewer/2022062603/5f07bb087e708231d41e742b/html5/thumbnails/54.jpg)
Recap
![Page 55: Solid C++ code by example - pvv.orgoma/SolidCPP_Sept_2012.pdf · Solid C++ code by example olve.maudal@cisco.com Sometimes you see code that is perfectly OK according to the definition](https://reader035.fdocuments.net/reader035/viewer/2022062603/5f07bb087e708231d41e742b/html5/thumbnails/55.jpg)
ntlm_message.hpp
![Page 56: Solid C++ code by example - pvv.orgoma/SolidCPP_Sept_2012.pdf · Solid C++ code by example olve.maudal@cisco.com Sometimes you see code that is perfectly OK according to the definition](https://reader035.fdocuments.net/reader035/viewer/2022062603/5f07bb087e708231d41e742b/html5/thumbnails/56.jpg)
#include <vector>
namespace pal { class ntlm_message { public: virtual std::vector<uint8_t> as_bytes() const = 0; }; }
![Page 57: Solid C++ code by example - pvv.orgoma/SolidCPP_Sept_2012.pdf · Solid C++ code by example olve.maudal@cisco.com Sometimes you see code that is perfectly OK according to the definition](https://reader035.fdocuments.net/reader035/viewer/2022062603/5f07bb087e708231d41e742b/html5/thumbnails/57.jpg)
#include <vector>
namespace pal { class ntlm_message { public: virtual std::vector<uint8_t> as_bytes() const = 0; }; }
Find 3 issues
![Page 58: Solid C++ code by example - pvv.orgoma/SolidCPP_Sept_2012.pdf · Solid C++ code by example olve.maudal@cisco.com Sometimes you see code that is perfectly OK according to the definition](https://reader035.fdocuments.net/reader035/viewer/2022062603/5f07bb087e708231d41e742b/html5/thumbnails/58.jpg)
#include <vector>
namespace pal { class ntlm_message { public: virtual std::vector<uint8_t> as_bytes() const = 0; }; }
![Page 59: Solid C++ code by example - pvv.orgoma/SolidCPP_Sept_2012.pdf · Solid C++ code by example olve.maudal@cisco.com Sometimes you see code that is perfectly OK according to the definition](https://reader035.fdocuments.net/reader035/viewer/2022062603/5f07bb087e708231d41e742b/html5/thumbnails/59.jpg)
#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!
![Page 60: Solid C++ code by example - pvv.orgoma/SolidCPP_Sept_2012.pdf · Solid C++ code by example olve.maudal@cisco.com Sometimes you see code that is perfectly OK according to the definition](https://reader035.fdocuments.net/reader035/viewer/2022062603/5f07bb087e708231d41e742b/html5/thumbnails/60.jpg)
#include <vector>
namespace pal { class ntlm_message { public: virtual std::vector<uint8_t> as_bytes() const = 0; }; }
![Page 61: Solid C++ code by example - pvv.orgoma/SolidCPP_Sept_2012.pdf · Solid C++ code by example olve.maudal@cisco.com Sometimes you see code that is perfectly OK according to the definition](https://reader035.fdocuments.net/reader035/viewer/2022062603/5f07bb087e708231d41e742b/html5/thumbnails/61.jpg)
#include <vector>
namespace pal { class ntlm_message { public: virtual std::vector<uint8_t> as_bytes() const = 0; }; }
missing header guard
![Page 62: Solid C++ code by example - pvv.orgoma/SolidCPP_Sept_2012.pdf · Solid C++ code by example olve.maudal@cisco.com Sometimes you see code that is perfectly OK according to the definition](https://reader035.fdocuments.net/reader035/viewer/2022062603/5f07bb087e708231d41e742b/html5/thumbnails/62.jpg)
#include <vector>
namespace pal { class ntlm_message { public: virtual std::vector<uint8_t> as_bytes() const = 0; }; }
![Page 63: Solid C++ code by example - pvv.orgoma/SolidCPP_Sept_2012.pdf · Solid C++ code by example olve.maudal@cisco.com Sometimes you see code that is perfectly OK according to the definition](https://reader035.fdocuments.net/reader035/viewer/2022062603/5f07bb087e708231d41e742b/html5/thumbnails/63.jpg)
#include <vector>
namespace pal { class ntlm_message { public: virtual std::vector<uint8_t> as_bytes() const = 0; }; }
should include <stdint.h>
![Page 64: Solid C++ code by example - pvv.orgoma/SolidCPP_Sept_2012.pdf · Solid C++ code by example olve.maudal@cisco.com Sometimes you see code that is perfectly OK according to the definition](https://reader035.fdocuments.net/reader035/viewer/2022062603/5f07bb087e708231d41e742b/html5/thumbnails/64.jpg)
#include <vector>
namespace pal { class ntlm_message { public: virtual std::vector<uint8_t> as_bytes() const = 0; }; }
![Page 65: Solid C++ code by example - pvv.orgoma/SolidCPP_Sept_2012.pdf · Solid C++ code by example olve.maudal@cisco.com Sometimes you see code that is perfectly OK according to the definition](https://reader035.fdocuments.net/reader035/viewer/2022062603/5f07bb087e708231d41e742b/html5/thumbnails/65.jpg)
#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
#endif
![Page 66: Solid C++ code by example - pvv.orgoma/SolidCPP_Sept_2012.pdf · Solid C++ code by example olve.maudal@cisco.com Sometimes you see code that is perfectly OK according to the definition](https://reader035.fdocuments.net/reader035/viewer/2022062603/5f07bb087e708231d41e742b/html5/thumbnails/66.jpg)
#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
![Page 67: Solid C++ code by example - pvv.orgoma/SolidCPP_Sept_2012.pdf · Solid C++ code by example olve.maudal@cisco.com Sometimes you see code that is perfectly OK according to the definition](https://reader035.fdocuments.net/reader035/viewer/2022062603/5f07bb087e708231d41e742b/html5/thumbnails/67.jpg)
virtual ~ntlm_message() {}
#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
![Page 68: Solid C++ code by example - pvv.orgoma/SolidCPP_Sept_2012.pdf · Solid C++ code by example olve.maudal@cisco.com Sometimes you see code that is perfectly OK according to the definition](https://reader035.fdocuments.net/reader035/viewer/2022062603/5f07bb087e708231d41e742b/html5/thumbnails/68.jpg)
#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
![Page 69: Solid C++ code by example - pvv.orgoma/SolidCPP_Sept_2012.pdf · Solid C++ code by example olve.maudal@cisco.com Sometimes you see code that is perfectly OK according to the definition](https://reader035.fdocuments.net/reader035/viewer/2022062603/5f07bb087e708231d41e742b/html5/thumbnails/69.jpg)
#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
#include <stdint.h>
![Page 70: Solid C++ code by example - pvv.orgoma/SolidCPP_Sept_2012.pdf · Solid C++ code by example olve.maudal@cisco.com Sometimes you see code that is perfectly OK according to the definition](https://reader035.fdocuments.net/reader035/viewer/2022062603/5f07bb087e708231d41e742b/html5/thumbnails/70.jpg)
#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
#include <stdint.h>
![Page 71: Solid C++ code by example - pvv.orgoma/SolidCPP_Sept_2012.pdf · Solid C++ code by example olve.maudal@cisco.com Sometimes you see code that is perfectly OK according to the definition](https://reader035.fdocuments.net/reader035/viewer/2022062603/5f07bb087e708231d41e742b/html5/thumbnails/71.jpg)
#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
#include <stdint.h>
This is Solid C++!
![Page 72: Solid C++ code by example - pvv.orgoma/SolidCPP_Sept_2012.pdf · Solid C++ code by example olve.maudal@cisco.com Sometimes you see code that is perfectly OK according to the definition](https://reader035.fdocuments.net/reader035/viewer/2022062603/5f07bb087e708231d41e742b/html5/thumbnails/72.jpg)
type1_message.hpp
![Page 73: Solid C++ code by example - pvv.orgoma/SolidCPP_Sept_2012.pdf · Solid C++ code by example olve.maudal@cisco.com Sometimes you see code that is perfectly OK according to the definition](https://reader035.fdocuments.net/reader035/viewer/2022062603/5f07bb087e708231d41e742b/html5/thumbnails/73.jpg)
#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
#include <vector>
![Page 74: Solid C++ code by example - pvv.orgoma/SolidCPP_Sept_2012.pdf · Solid C++ code by example olve.maudal@cisco.com Sometimes you see code that is perfectly OK according to the definition](https://reader035.fdocuments.net/reader035/viewer/2022062603/5f07bb087e708231d41e742b/html5/thumbnails/74.jpg)
#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
#include <vector>
Find 3 issues
![Page 75: Solid C++ code by example - pvv.orgoma/SolidCPP_Sept_2012.pdf · Solid C++ code by example olve.maudal@cisco.com Sometimes you see code that is perfectly OK according to the definition](https://reader035.fdocuments.net/reader035/viewer/2022062603/5f07bb087e708231d41e742b/html5/thumbnails/75.jpg)
#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
#include <vector>
![Page 76: Solid C++ code by example - pvv.orgoma/SolidCPP_Sept_2012.pdf · Solid C++ code by example olve.maudal@cisco.com Sometimes you see code that is perfectly OK according to the definition](https://reader035.fdocuments.net/reader035/viewer/2022062603/5f07bb087e708231d41e742b/html5/thumbnails/76.jpg)
#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
#include <vector>
no need to include <vector> again
![Page 77: Solid C++ code by example - pvv.orgoma/SolidCPP_Sept_2012.pdf · Solid C++ code by example olve.maudal@cisco.com Sometimes you see code that is perfectly OK according to the definition](https://reader035.fdocuments.net/reader035/viewer/2022062603/5f07bb087e708231d41e742b/html5/thumbnails/77.jpg)
#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
#include <vector>
![Page 78: Solid C++ code by example - pvv.orgoma/SolidCPP_Sept_2012.pdf · Solid C++ code by example olve.maudal@cisco.com Sometimes you see code that is perfectly OK according to the definition](https://reader035.fdocuments.net/reader035/viewer/2022062603/5f07bb087e708231d41e742b/html5/thumbnails/78.jpg)
#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
#include <vector>
focus on usage; public stuff first, then
private stuff
![Page 79: Solid C++ code by example - pvv.orgoma/SolidCPP_Sept_2012.pdf · Solid C++ code by example olve.maudal@cisco.com Sometimes you see code that is perfectly OK according to the definition](https://reader035.fdocuments.net/reader035/viewer/2022062603/5f07bb087e708231d41e742b/html5/thumbnails/79.jpg)
#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
#include <vector>
![Page 80: Solid C++ code by example - pvv.orgoma/SolidCPP_Sept_2012.pdf · Solid C++ code by example olve.maudal@cisco.com Sometimes you see code that is perfectly OK according to the definition](https://reader035.fdocuments.net/reader035/viewer/2022062603/5f07bb087e708231d41e742b/html5/thumbnails/80.jpg)
#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
#include <vector>
single argument constructors should
nearly always have the explicit specifier
![Page 81: Solid C++ code by example - pvv.orgoma/SolidCPP_Sept_2012.pdf · Solid C++ code by example olve.maudal@cisco.com Sometimes you see code that is perfectly OK according to the definition](https://reader035.fdocuments.net/reader035/viewer/2022062603/5f07bb087e708231d41e742b/html5/thumbnails/81.jpg)
#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
![Page 82: Solid C++ code by example - pvv.orgoma/SolidCPP_Sept_2012.pdf · Solid C++ code by example olve.maudal@cisco.com Sometimes you see code that is perfectly OK according to the definition](https://reader035.fdocuments.net/reader035/viewer/2022062603/5f07bb087e708231d41e742b/html5/thumbnails/82.jpg)
#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
![Page 83: Solid C++ code by example - pvv.orgoma/SolidCPP_Sept_2012.pdf · Solid C++ code by example olve.maudal@cisco.com Sometimes you see code that is perfectly OK according to the definition](https://reader035.fdocuments.net/reader035/viewer/2022062603/5f07bb087e708231d41e742b/html5/thumbnails/83.jpg)
#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
![Page 84: Solid C++ code by example - pvv.orgoma/SolidCPP_Sept_2012.pdf · Solid C++ code by example olve.maudal@cisco.com Sometimes you see code that is perfectly OK according to the definition](https://reader035.fdocuments.net/reader035/viewer/2022062603/5f07bb087e708231d41e742b/html5/thumbnails/84.jpg)
#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
private:
![Page 85: Solid C++ code by example - pvv.orgoma/SolidCPP_Sept_2012.pdf · Solid C++ code by example olve.maudal@cisco.com Sometimes you see code that is perfectly OK according to the definition](https://reader035.fdocuments.net/reader035/viewer/2022062603/5f07bb087e708231d41e742b/html5/thumbnails/85.jpg)
public: type1_message(uint32_t ssp_flags); virtual std::vector<uint8_t> as_bytes() const;
#ifndef PAL_TYPE1_MESSAGE_HPP_INCLUDED#define PAL_TYPE1_MESSAGE_HPP_INCLUDED
#include "ntlm_message.hpp"
namespace pal { class type1_message : public ntlm_message {
}; }
#endif
private: uint32_t ssp_flags_;
![Page 86: Solid C++ code by example - pvv.orgoma/SolidCPP_Sept_2012.pdf · Solid C++ code by example olve.maudal@cisco.com Sometimes you see code that is perfectly OK according to the definition](https://reader035.fdocuments.net/reader035/viewer/2022062603/5f07bb087e708231d41e742b/html5/thumbnails/86.jpg)
public: type1_message(uint32_t ssp_flags); virtual std::vector<uint8_t> as_bytes() const;
#ifndef PAL_TYPE1_MESSAGE_HPP_INCLUDED#define PAL_TYPE1_MESSAGE_HPP_INCLUDED
#include "ntlm_message.hpp"
namespace pal { class type1_message : public ntlm_message {
}; }
#endif
private: uint32_t ssp_flags_;
![Page 87: Solid C++ code by example - pvv.orgoma/SolidCPP_Sept_2012.pdf · Solid C++ code by example olve.maudal@cisco.com Sometimes you see code that is perfectly OK according to the definition](https://reader035.fdocuments.net/reader035/viewer/2022062603/5f07bb087e708231d41e742b/html5/thumbnails/87.jpg)
#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:
virtual std::vector<uint8_t> as_bytes() const; private: uint32_t ssp_flags_; }; }
#endif
type1_message(uint32_t ssp_flags);
![Page 88: Solid C++ code by example - pvv.orgoma/SolidCPP_Sept_2012.pdf · Solid C++ code by example olve.maudal@cisco.com Sometimes you see code that is perfectly OK according to the definition](https://reader035.fdocuments.net/reader035/viewer/2022062603/5f07bb087e708231d41e742b/html5/thumbnails/88.jpg)
#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:
virtual std::vector<uint8_t> as_bytes() const; private: uint32_t ssp_flags_; }; }
#endif
type1_message(uint32_t ssp_flags); explicit
![Page 89: Solid C++ code by example - pvv.orgoma/SolidCPP_Sept_2012.pdf · Solid C++ code by example olve.maudal@cisco.com Sometimes you see code that is perfectly OK according to the definition](https://reader035.fdocuments.net/reader035/viewer/2022062603/5f07bb087e708231d41e742b/html5/thumbnails/89.jpg)
#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
![Page 90: Solid C++ code by example - pvv.orgoma/SolidCPP_Sept_2012.pdf · Solid C++ code by example olve.maudal@cisco.com Sometimes you see code that is perfectly OK according to the definition](https://reader035.fdocuments.net/reader035/viewer/2022062603/5f07bb087e708231d41e742b/html5/thumbnails/90.jpg)
#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!
![Page 91: Solid C++ code by example - pvv.orgoma/SolidCPP_Sept_2012.pdf · Solid C++ code by example olve.maudal@cisco.com Sometimes you see code that is perfectly OK according to the definition](https://reader035.fdocuments.net/reader035/viewer/2022062603/5f07bb087e708231d41e742b/html5/thumbnails/91.jpg)
type1_message.cpp
![Page 92: Solid C++ code by example - pvv.orgoma/SolidCPP_Sept_2012.pdf · Solid C++ code by example olve.maudal@cisco.com Sometimes you see code that is perfectly OK according to the definition](https://reader035.fdocuments.net/reader035/viewer/2022062603/5f07bb087e708231d41e742b/html5/thumbnails/92.jpg)
#include "type1_message.hpp"
#include "tools.hpp"
/* * See http://davenport.sourceforge.net/ntlm.html * * Type 1 Message * * 0 NTLMSSP Signature "NTLMSSP\0" * 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);}
![Page 93: Solid C++ code by example - pvv.orgoma/SolidCPP_Sept_2012.pdf · Solid C++ code by example olve.maudal@cisco.com Sometimes you see code that is perfectly OK according to the definition](https://reader035.fdocuments.net/reader035/viewer/2022062603/5f07bb087e708231d41e742b/html5/thumbnails/93.jpg)
#include "type1_message.hpp"
#include "tools.hpp"
/* * See http://davenport.sourceforge.net/ntlm.html * * Type 1 Message * * 0 NTLMSSP Signature "NTLMSSP\0" * 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);}
Find at least 3 issues here
![Page 94: Solid C++ code by example - pvv.orgoma/SolidCPP_Sept_2012.pdf · Solid C++ code by example olve.maudal@cisco.com Sometimes you see code that is perfectly OK according to the definition](https://reader035.fdocuments.net/reader035/viewer/2022062603/5f07bb087e708231d41e742b/html5/thumbnails/94.jpg)
#include "type1_message.hpp"
#include "tools.hpp"
/* * See http://davenport.sourceforge.net/ntlm.html * * Type 1 Message * * 0 NTLMSSP Signature "NTLMSSP\0" * 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);}
![Page 95: Solid C++ code by example - pvv.orgoma/SolidCPP_Sept_2012.pdf · Solid C++ code by example olve.maudal@cisco.com Sometimes you see code that is perfectly OK according to the definition](https://reader035.fdocuments.net/reader035/viewer/2022062603/5f07bb087e708231d41e742b/html5/thumbnails/95.jpg)
#include "type1_message.hpp"
#include "tools.hpp"
/* * See http://davenport.sourceforge.net/ntlm.html * * Type 1 Message * * 0 NTLMSSP Signature "NTLMSSP\0" * 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);}
focus on readability; importing a namespace might save some keystrokes, but often it does not increase readability
![Page 96: Solid C++ code by example - pvv.orgoma/SolidCPP_Sept_2012.pdf · Solid C++ code by example olve.maudal@cisco.com Sometimes you see code that is perfectly OK according to the definition](https://reader035.fdocuments.net/reader035/viewer/2022062603/5f07bb087e708231d41e742b/html5/thumbnails/96.jpg)
#include "type1_message.hpp"
#include "tools.hpp"
/* * See http://davenport.sourceforge.net/ntlm.html * * Type 1 Message * * 0 NTLMSSP Signature "NTLMSSP\0" * 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);}
![Page 97: Solid C++ code by example - pvv.orgoma/SolidCPP_Sept_2012.pdf · Solid C++ code by example olve.maudal@cisco.com Sometimes you see code that is perfectly OK according to the definition](https://reader035.fdocuments.net/reader035/viewer/2022062603/5f07bb087e708231d41e742b/html5/thumbnails/97.jpg)
#include "type1_message.hpp"
#include "tools.hpp"
/* * See http://davenport.sourceforge.net/ntlm.html * * Type 1 Message * * 0 NTLMSSP Signature "NTLMSSP\0" * 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);}
use the initializer list
![Page 98: Solid C++ code by example - pvv.orgoma/SolidCPP_Sept_2012.pdf · Solid C++ code by example olve.maudal@cisco.com Sometimes you see code that is perfectly OK according to the definition](https://reader035.fdocuments.net/reader035/viewer/2022062603/5f07bb087e708231d41e742b/html5/thumbnails/98.jpg)
#include "type1_message.hpp"
#include "tools.hpp"
/* * See http://davenport.sourceforge.net/ntlm.html * * Type 1 Message * * 0 NTLMSSP Signature "NTLMSSP\0" * 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);}
![Page 99: Solid C++ code by example - pvv.orgoma/SolidCPP_Sept_2012.pdf · Solid C++ code by example olve.maudal@cisco.com Sometimes you see code that is perfectly OK according to the definition](https://reader035.fdocuments.net/reader035/viewer/2022062603/5f07bb087e708231d41e742b/html5/thumbnails/99.jpg)
#include "type1_message.hpp"
#include "tools.hpp"
/* * See http://davenport.sourceforge.net/ntlm.html * * Type 1 Message * * 0 NTLMSSP Signature "NTLMSSP\0" * 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);}
use std::size_t when appropriate
![Page 100: Solid C++ code by example - pvv.orgoma/SolidCPP_Sept_2012.pdf · Solid C++ code by example olve.maudal@cisco.com Sometimes you see code that is perfectly OK according to the definition](https://reader035.fdocuments.net/reader035/viewer/2022062603/5f07bb087e708231d41e742b/html5/thumbnails/100.jpg)
#include "type1_message.hpp"
#include "tools.hpp"
/* * See http://davenport.sourceforge.net/ntlm.html * * Type 1 Message * * 0 NTLMSSP Signature "NTLMSSP\0" * 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);}
![Page 101: Solid C++ code by example - pvv.orgoma/SolidCPP_Sept_2012.pdf · Solid C++ code by example olve.maudal@cisco.com Sometimes you see code that is perfectly OK according to the definition](https://reader035.fdocuments.net/reader035/viewer/2022062603/5f07bb087e708231d41e742b/html5/thumbnails/101.jpg)
#include "type1_message.hpp"
#include "tools.hpp"
/* * See http://davenport.sourceforge.net/ntlm.html * * Type 1 Message * * 0 NTLMSSP Signature "NTLMSSP\0" * 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);}
![Page 102: Solid C++ code by example - pvv.orgoma/SolidCPP_Sept_2012.pdf · Solid C++ code by example olve.maudal@cisco.com Sometimes you see code that is perfectly OK according to the definition](https://reader035.fdocuments.net/reader035/viewer/2022062603/5f07bb087e708231d41e742b/html5/thumbnails/102.jpg)
#include "type1_message.hpp"
#include "tools.hpp"
/* * See http://davenport.sourceforge.net/ntlm.html * * Type 1 Message * * 0 NTLMSSP Signature "NTLMSSP\0" * 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);}
![Page 103: Solid C++ code by example - pvv.orgoma/SolidCPP_Sept_2012.pdf · Solid C++ code by example olve.maudal@cisco.com Sometimes you see code that is perfectly OK according to the definition](https://reader035.fdocuments.net/reader035/viewer/2022062603/5f07bb087e708231d41e742b/html5/thumbnails/103.jpg)
#include "type1_message.hpp"
#include "tools.hpp"
/* * See http://davenport.sourceforge.net/ntlm.html * * Type 1 Message * * 0 NTLMSSP Signature "NTLMSSP\0" * 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);}
![Page 104: Solid C++ code by example - pvv.orgoma/SolidCPP_Sept_2012.pdf · Solid C++ code by example olve.maudal@cisco.com Sometimes you see code that is perfectly OK according to the definition](https://reader035.fdocuments.net/reader035/viewer/2022062603/5f07bb087e708231d41e742b/html5/thumbnails/104.jpg)
#include "type1_message.hpp"
#include "tools.hpp"
/* * See http://davenport.sourceforge.net/ntlm.html * * Type 1 Message * * 0 NTLMSSP Signature "NTLMSSP\0" * 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);}
![Page 105: Solid C++ code by example - pvv.orgoma/SolidCPP_Sept_2012.pdf · Solid C++ code by example olve.maudal@cisco.com Sometimes you see code that is perfectly OK according to the definition](https://reader035.fdocuments.net/reader035/viewer/2022062603/5f07bb087e708231d41e742b/html5/thumbnails/105.jpg)
#include "type1_message.hpp"
#include "tools.hpp"
/* * See http://davenport.sourceforge.net/ntlm.html * * Type 1 Message * * 0 NTLMSSP Signature "NTLMSSP\0" * 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);}
![Page 106: Solid C++ code by example - pvv.orgoma/SolidCPP_Sept_2012.pdf · Solid C++ code by example olve.maudal@cisco.com Sometimes you see code that is perfectly OK according to the definition](https://reader035.fdocuments.net/reader035/viewer/2022062603/5f07bb087e708231d41e742b/html5/thumbnails/106.jpg)
#include "type1_message.hpp"
#include "tools.hpp"
/* * See http://davenport.sourceforge.net/ntlm.html * * Type 1 Message * * 0 NTLMSSP Signature "NTLMSSP\0" * 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);}
![Page 107: Solid C++ code by example - pvv.orgoma/SolidCPP_Sept_2012.pdf · Solid C++ code by example olve.maudal@cisco.com Sometimes you see code that is perfectly OK according to the definition](https://reader035.fdocuments.net/reader035/viewer/2022062603/5f07bb087e708231d41e742b/html5/thumbnails/107.jpg)
#include "type1_message.hpp"
#include "tools.hpp"
/* * See http://davenport.sourceforge.net/ntlm.html * * Type 1 Message * * 0 NTLMSSP Signature "NTLMSSP\0" * 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);}
![Page 108: Solid C++ code by example - pvv.orgoma/SolidCPP_Sept_2012.pdf · Solid C++ code by example olve.maudal@cisco.com Sometimes you see code that is perfectly OK according to the definition](https://reader035.fdocuments.net/reader035/viewer/2022062603/5f07bb087e708231d41e742b/html5/thumbnails/108.jpg)
#include "type1_message.hpp"
#include "tools.hpp"
/* * See http://davenport.sourceforge.net/ntlm.html * * Type 1 Message * * 0 NTLMSSP Signature "NTLMSSP\0" * 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);}
![Page 109: Solid C++ code by example - pvv.orgoma/SolidCPP_Sept_2012.pdf · Solid C++ code by example olve.maudal@cisco.com Sometimes you see code that is perfectly OK according to the definition](https://reader035.fdocuments.net/reader035/viewer/2022062603/5f07bb087e708231d41e742b/html5/thumbnails/109.jpg)
#include "type1_message.hpp"
#include "tools.hpp"
/* * See http://davenport.sourceforge.net/ntlm.html * * Type 1 Message * * 0 NTLMSSP Signature "NTLMSSP\0" * 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);}
![Page 110: Solid C++ code by example - pvv.orgoma/SolidCPP_Sept_2012.pdf · Solid C++ code by example olve.maudal@cisco.com Sometimes you see code that is perfectly OK according to the definition](https://reader035.fdocuments.net/reader035/viewer/2022062603/5f07bb087e708231d41e742b/html5/thumbnails/110.jpg)
#include "type1_message.hpp"
#include "tools.hpp"
/* * See http://davenport.sourceforge.net/ntlm.html * * Type 1 Message * * 0 NTLMSSP Signature "NTLMSSP\0" * 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);}
![Page 111: Solid C++ code by example - pvv.orgoma/SolidCPP_Sept_2012.pdf · Solid C++ code by example olve.maudal@cisco.com Sometimes you see code that is perfectly OK according to the definition](https://reader035.fdocuments.net/reader035/viewer/2022062603/5f07bb087e708231d41e742b/html5/thumbnails/111.jpg)
#include "type1_message.hpp"
#include "tools.hpp"
/* * See http://davenport.sourceforge.net/ntlm.html * * Type 1 Message * * 0 NTLMSSP Signature "NTLMSSP\0" * 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);}
![Page 112: Solid C++ code by example - pvv.orgoma/SolidCPP_Sept_2012.pdf · Solid C++ code by example olve.maudal@cisco.com Sometimes you see code that is perfectly OK according to the definition](https://reader035.fdocuments.net/reader035/viewer/2022062603/5f07bb087e708231d41e742b/html5/thumbnails/112.jpg)
#include "type1_message.hpp"
#include "tools.hpp"
/* * See http://davenport.sourceforge.net/ntlm.html * * Type 1 Message * * 0 NTLMSSP Signature "NTLMSSP\0" * 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);}
![Page 113: Solid C++ code by example - pvv.orgoma/SolidCPP_Sept_2012.pdf · Solid C++ code by example olve.maudal@cisco.com Sometimes you see code that is perfectly OK according to the definition](https://reader035.fdocuments.net/reader035/viewer/2022062603/5f07bb087e708231d41e742b/html5/thumbnails/113.jpg)
#include "type1_message.hpp"
#include "tools.hpp"
/* * See http://davenport.sourceforge.net/ntlm.html * * Type 1 Message * * 0 NTLMSSP Signature "NTLMSSP\0" * 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);}
![Page 114: Solid C++ code by example - pvv.orgoma/SolidCPP_Sept_2012.pdf · Solid C++ code by example olve.maudal@cisco.com Sometimes you see code that is perfectly OK according to the definition](https://reader035.fdocuments.net/reader035/viewer/2022062603/5f07bb087e708231d41e742b/html5/thumbnails/114.jpg)
#include "type1_message.hpp"
#include "tools.hpp"
/* * See http://davenport.sourceforge.net/ntlm.html * * Type 1 Message * * 0 NTLMSSP Signature "NTLMSSP\0" * 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);}
![Page 115: Solid C++ code by example - pvv.orgoma/SolidCPP_Sept_2012.pdf · Solid C++ code by example olve.maudal@cisco.com Sometimes you see code that is perfectly OK according to the definition](https://reader035.fdocuments.net/reader035/viewer/2022062603/5f07bb087e708231d41e742b/html5/thumbnails/115.jpg)
#include "type1_message.hpp"
#include "tools.hpp"
/* * See http://davenport.sourceforge.net/ntlm.html * * Type 1 Message * * 0 NTLMSSP Signature "NTLMSSP\0" * 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);}
![Page 116: Solid C++ code by example - pvv.orgoma/SolidCPP_Sept_2012.pdf · Solid C++ code by example olve.maudal@cisco.com Sometimes you see code that is perfectly OK according to the definition](https://reader035.fdocuments.net/reader035/viewer/2022062603/5f07bb087e708231d41e742b/html5/thumbnails/116.jpg)
#include "type1_message.hpp"
#include "tools.hpp"
/* * See http://davenport.sourceforge.net/ntlm.html * * Type 1 Message * * 0 NTLMSSP Signature "NTLMSSP\0" * 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);}
This is better
![Page 117: Solid C++ code by example - pvv.orgoma/SolidCPP_Sept_2012.pdf · Solid C++ code by example olve.maudal@cisco.com Sometimes you see code that is perfectly OK according to the definition](https://reader035.fdocuments.net/reader035/viewer/2022062603/5f07bb087e708231d41e742b/html5/thumbnails/117.jpg)
type2_message.hpp
![Page 118: Solid C++ code by example - pvv.orgoma/SolidCPP_Sept_2012.pdf · Solid C++ code by example olve.maudal@cisco.com Sometimes you see code that is perfectly OK according to the definition](https://reader035.fdocuments.net/reader035/viewer/2022062603/5f07bb087e708231d41e742b/html5/thumbnails/118.jpg)
#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
![Page 119: Solid C++ code by example - pvv.orgoma/SolidCPP_Sept_2012.pdf · Solid C++ code by example olve.maudal@cisco.com Sometimes you see code that is perfectly OK according to the definition](https://reader035.fdocuments.net/reader035/viewer/2022062603/5f07bb087e708231d41e742b/html5/thumbnails/119.jpg)
#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
![Page 120: Solid C++ code by example - pvv.orgoma/SolidCPP_Sept_2012.pdf · Solid C++ code by example olve.maudal@cisco.com Sometimes you see code that is perfectly OK according to the definition](https://reader035.fdocuments.net/reader035/viewer/2022062603/5f07bb087e708231d41e742b/html5/thumbnails/120.jpg)
#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
![Page 121: Solid C++ code by example - pvv.orgoma/SolidCPP_Sept_2012.pdf · Solid C++ code by example olve.maudal@cisco.com Sometimes you see code that is perfectly OK according to the definition](https://reader035.fdocuments.net/reader035/viewer/2022062603/5f07bb087e708231d41e742b/html5/thumbnails/121.jpg)
#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!
![Page 122: Solid C++ code by example - pvv.orgoma/SolidCPP_Sept_2012.pdf · Solid C++ code by example olve.maudal@cisco.com Sometimes you see code that is perfectly OK according to the definition](https://reader035.fdocuments.net/reader035/viewer/2022062603/5f07bb087e708231d41e742b/html5/thumbnails/122.jpg)
#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
![Page 123: Solid C++ code by example - pvv.orgoma/SolidCPP_Sept_2012.pdf · Solid C++ code by example olve.maudal@cisco.com Sometimes you see code that is perfectly OK according to the definition](https://reader035.fdocuments.net/reader035/viewer/2022062603/5f07bb087e708231d41e742b/html5/thumbnails/123.jpg)
#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 &
![Page 124: Solid C++ code by example - pvv.orgoma/SolidCPP_Sept_2012.pdf · Solid C++ code by example olve.maudal@cisco.com Sometimes you see code that is perfectly OK according to the definition](https://reader035.fdocuments.net/reader035/viewer/2022062603/5f07bb087e708231d41e742b/html5/thumbnails/124.jpg)
#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
![Page 125: Solid C++ code by example - pvv.orgoma/SolidCPP_Sept_2012.pdf · Solid C++ code by example olve.maudal@cisco.com Sometimes you see code that is perfectly OK according to the definition](https://reader035.fdocuments.net/reader035/viewer/2022062603/5f07bb087e708231d41e742b/html5/thumbnails/125.jpg)
#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
![Page 126: Solid C++ code by example - pvv.orgoma/SolidCPP_Sept_2012.pdf · Solid C++ code by example olve.maudal@cisco.com Sometimes you see code that is perfectly OK according to the definition](https://reader035.fdocuments.net/reader035/viewer/2022062603/5f07bb087e708231d41e742b/html5/thumbnails/126.jpg)
#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
using namespace std;
![Page 127: Solid C++ code by example - pvv.orgoma/SolidCPP_Sept_2012.pdf · Solid C++ code by example olve.maudal@cisco.com Sometimes you see code that is perfectly OK according to the definition](https://reader035.fdocuments.net/reader035/viewer/2022062603/5f07bb087e708231d41e742b/html5/thumbnails/127.jpg)
#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
![Page 128: Solid C++ code by example - pvv.orgoma/SolidCPP_Sept_2012.pdf · Solid C++ code by example olve.maudal@cisco.com Sometimes you see code that is perfectly OK according to the definition](https://reader035.fdocuments.net/reader035/viewer/2022062603/5f07bb087e708231d41e742b/html5/thumbnails/128.jpg)
#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
![Page 129: Solid C++ code by example - pvv.orgoma/SolidCPP_Sept_2012.pdf · Solid C++ code by example olve.maudal@cisco.com Sometimes you see code that is perfectly OK according to the definition](https://reader035.fdocuments.net/reader035/viewer/2022062603/5f07bb087e708231d41e742b/html5/thumbnails/129.jpg)
#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
![Page 130: Solid C++ code by example - pvv.orgoma/SolidCPP_Sept_2012.pdf · Solid C++ code by example olve.maudal@cisco.com Sometimes you see code that is perfectly OK according to the definition](https://reader035.fdocuments.net/reader035/viewer/2022062603/5f07bb087e708231d41e742b/html5/thumbnails/130.jpg)
#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
![Page 131: Solid C++ code by example - pvv.orgoma/SolidCPP_Sept_2012.pdf · Solid C++ code by example olve.maudal@cisco.com Sometimes you see code that is perfectly OK according to the definition](https://reader035.fdocuments.net/reader035/viewer/2022062603/5f07bb087e708231d41e742b/html5/thumbnails/131.jpg)
#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
![Page 132: Solid C++ code by example - pvv.orgoma/SolidCPP_Sept_2012.pdf · Solid C++ code by example olve.maudal@cisco.com Sometimes you see code that is perfectly OK according to the definition](https://reader035.fdocuments.net/reader035/viewer/2022062603/5f07bb087e708231d41e742b/html5/thumbnails/132.jpg)
#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
![Page 133: Solid C++ code by example - pvv.orgoma/SolidCPP_Sept_2012.pdf · Solid C++ code by example olve.maudal@cisco.com Sometimes you see code that is perfectly OK according to the definition](https://reader035.fdocuments.net/reader035/viewer/2022062603/5f07bb087e708231d41e742b/html5/thumbnails/133.jpg)
#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
![Page 134: Solid C++ code by example - pvv.orgoma/SolidCPP_Sept_2012.pdf · Solid C++ code by example olve.maudal@cisco.com Sometimes you see code that is perfectly OK according to the definition](https://reader035.fdocuments.net/reader035/viewer/2022062603/5f07bb087e708231d41e742b/html5/thumbnails/134.jpg)
#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
![Page 135: Solid C++ code by example - pvv.orgoma/SolidCPP_Sept_2012.pdf · Solid C++ code by example olve.maudal@cisco.com Sometimes you see code that is perfectly OK according to the definition](https://reader035.fdocuments.net/reader035/viewer/2022062603/5f07bb087e708231d41e742b/html5/thumbnails/135.jpg)
#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
![Page 136: Solid C++ code by example - pvv.orgoma/SolidCPP_Sept_2012.pdf · Solid C++ code by example olve.maudal@cisco.com Sometimes you see code that is perfectly OK according to the definition](https://reader035.fdocuments.net/reader035/viewer/2022062603/5f07bb087e708231d41e742b/html5/thumbnails/136.jpg)
#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
![Page 137: Solid C++ code by example - pvv.orgoma/SolidCPP_Sept_2012.pdf · Solid C++ code by example olve.maudal@cisco.com Sometimes you see code that is perfectly OK according to the definition](https://reader035.fdocuments.net/reader035/viewer/2022062603/5f07bb087e708231d41e742b/html5/thumbnails/137.jpg)
#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
![Page 138: Solid C++ code by example - pvv.orgoma/SolidCPP_Sept_2012.pdf · Solid C++ code by example olve.maudal@cisco.com Sometimes you see code that is perfectly OK according to the definition](https://reader035.fdocuments.net/reader035/viewer/2022062603/5f07bb087e708231d41e742b/html5/thumbnails/138.jpg)
#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
![Page 139: Solid C++ code by example - pvv.orgoma/SolidCPP_Sept_2012.pdf · Solid C++ code by example olve.maudal@cisco.com Sometimes you see code that is perfectly OK according to the definition](https://reader035.fdocuments.net/reader035/viewer/2022062603/5f07bb087e708231d41e742b/html5/thumbnails/139.jpg)
#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++
![Page 140: Solid C++ code by example - pvv.orgoma/SolidCPP_Sept_2012.pdf · Solid C++ code by example olve.maudal@cisco.com Sometimes you see code that is perfectly OK according to the definition](https://reader035.fdocuments.net/reader035/viewer/2022062603/5f07bb087e708231d41e742b/html5/thumbnails/140.jpg)
type2_message.cpp
![Page 141: Solid C++ code by example - pvv.orgoma/SolidCPP_Sept_2012.pdf · Solid C++ code by example olve.maudal@cisco.com Sometimes you see code that is perfectly OK according to the definition](https://reader035.fdocuments.net/reader035/viewer/2022062603/5f07bb087e708231d41e742b/html5/thumbnails/141.jpg)
#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
...
![Page 142: Solid C++ code by example - pvv.orgoma/SolidCPP_Sept_2012.pdf · Solid C++ code by example olve.maudal@cisco.com Sometimes you see code that is perfectly OK according to the definition](https://reader035.fdocuments.net/reader035/viewer/2022062603/5f07bb087e708231d41e742b/html5/thumbnails/142.jpg)
#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
...
Find one issue
![Page 143: Solid C++ code by example - pvv.orgoma/SolidCPP_Sept_2012.pdf · Solid C++ code by example olve.maudal@cisco.com Sometimes you see code that is perfectly OK according to the definition](https://reader035.fdocuments.net/reader035/viewer/2022062603/5f07bb087e708231d41e742b/html5/thumbnails/143.jpg)
#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
...
![Page 144: Solid C++ code by example - pvv.orgoma/SolidCPP_Sept_2012.pdf · Solid C++ code by example olve.maudal@cisco.com Sometimes you see code that is perfectly OK according to the definition](https://reader035.fdocuments.net/reader035/viewer/2022062603/5f07bb087e708231d41e742b/html5/thumbnails/144.jpg)
#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 to order the include files
![Page 145: Solid C++ code by example - pvv.orgoma/SolidCPP_Sept_2012.pdf · Solid C++ code by example olve.maudal@cisco.com Sometimes you see code that is perfectly OK according to the definition](https://reader035.fdocuments.net/reader035/viewer/2022062603/5f07bb087e708231d41e742b/html5/thumbnails/145.jpg)
#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
...
![Page 146: Solid C++ code by example - pvv.orgoma/SolidCPP_Sept_2012.pdf · Solid C++ code by example olve.maudal@cisco.com Sometimes you see code that is perfectly OK according to the definition](https://reader035.fdocuments.net/reader035/viewer/2022062603/5f07bb087e708231d41e742b/html5/thumbnails/146.jpg)
/* * 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>
![Page 147: Solid C++ code by example - pvv.orgoma/SolidCPP_Sept_2012.pdf · Solid C++ code by example olve.maudal@cisco.com Sometimes you see code that is perfectly OK according to the definition](https://reader035.fdocuments.net/reader035/viewer/2022062603/5f07bb087e708231d41e742b/html5/thumbnails/147.jpg)
/* * 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>
![Page 148: Solid C++ code by example - pvv.orgoma/SolidCPP_Sept_2012.pdf · Solid C++ code by example olve.maudal@cisco.com Sometimes you see code that is perfectly OK according to the definition](https://reader035.fdocuments.net/reader035/viewer/2022062603/5f07bb087e708231d41e742b/html5/thumbnails/148.jpg)
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
![Page 149: Solid C++ code by example - pvv.orgoma/SolidCPP_Sept_2012.pdf · Solid C++ code by example olve.maudal@cisco.com Sometimes you see code that is perfectly OK according to the definition](https://reader035.fdocuments.net/reader035/viewer/2022062603/5f07bb087e708231d41e742b/html5/thumbnails/149.jpg)
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
Any issues here?
![Page 150: Solid C++ code by example - pvv.orgoma/SolidCPP_Sept_2012.pdf · Solid C++ code by example olve.maudal@cisco.com Sometimes you see code that is perfectly OK according to the definition](https://reader035.fdocuments.net/reader035/viewer/2022062603/5f07bb087e708231d41e742b/html5/thumbnails/150.jpg)
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
![Page 151: Solid C++ code by example - pvv.orgoma/SolidCPP_Sept_2012.pdf · Solid C++ code by example olve.maudal@cisco.com Sometimes you see code that is perfectly OK according to the definition](https://reader035.fdocuments.net/reader035/viewer/2022062603/5f07bb087e708231d41e742b/html5/thumbnails/151.jpg)
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
![Page 152: Solid C++ code by example - pvv.orgoma/SolidCPP_Sept_2012.pdf · Solid C++ code by example olve.maudal@cisco.com Sometimes you see code that is perfectly OK according to the definition](https://reader035.fdocuments.net/reader035/viewer/2022062603/5f07bb087e708231d41e742b/html5/thumbnails/152.jpg)
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
![Page 153: Solid C++ code by example - pvv.orgoma/SolidCPP_Sept_2012.pdf · Solid C++ code by example olve.maudal@cisco.com Sometimes you see code that is perfectly OK according to the definition](https://reader035.fdocuments.net/reader035/viewer/2022062603/5f07bb087e708231d41e742b/html5/thumbnails/153.jpg)
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
superfluous use of ()
![Page 154: Solid C++ code by example - pvv.orgoma/SolidCPP_Sept_2012.pdf · Solid C++ code by example olve.maudal@cisco.com Sometimes you see code that is perfectly OK according to the definition](https://reader035.fdocuments.net/reader035/viewer/2022062603/5f07bb087e708231d41e742b/html5/thumbnails/154.jpg)
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
superfluous use of ()
![Page 155: Solid C++ code by example - pvv.orgoma/SolidCPP_Sept_2012.pdf · Solid C++ code by example olve.maudal@cisco.com Sometimes you see code that is perfectly OK according to the definition](https://reader035.fdocuments.net/reader035/viewer/2022062603/5f07bb087e708231d41e742b/html5/thumbnails/155.jpg)
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
so you really like () do you? Why not add a few more?
![Page 156: Solid C++ code by example - pvv.orgoma/SolidCPP_Sept_2012.pdf · Solid C++ code by example olve.maudal@cisco.com Sometimes you see code that is perfectly OK according to the definition](https://reader035.fdocuments.net/reader035/viewer/2022062603/5f07bb087e708231d41e742b/html5/thumbnails/156.jpg)
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
so you really like () do you? Why not add a few more?
![Page 157: Solid C++ code by example - pvv.orgoma/SolidCPP_Sept_2012.pdf · Solid C++ code by example olve.maudal@cisco.com Sometimes you see code that is perfectly OK according to the definition](https://reader035.fdocuments.net/reader035/viewer/2022062603/5f07bb087e708231d41e742b/html5/thumbnails/157.jpg)
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
![Page 158: Solid C++ code by example - pvv.orgoma/SolidCPP_Sept_2012.pdf · Solid C++ code by example olve.maudal@cisco.com Sometimes you see code that is perfectly OK according to the definition](https://reader035.fdocuments.net/reader035/viewer/2022062603/5f07bb087e708231d41e742b/html5/thumbnails/158.jpg)
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
![Page 159: Solid C++ code by example - pvv.orgoma/SolidCPP_Sept_2012.pdf · Solid C++ code by example olve.maudal@cisco.com Sometimes you see code that is perfectly OK according to the definition](https://reader035.fdocuments.net/reader035/viewer/2022062603/5f07bb087e708231d41e742b/html5/thumbnails/159.jpg)
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
![Page 160: Solid C++ code by example - pvv.orgoma/SolidCPP_Sept_2012.pdf · Solid C++ code by example olve.maudal@cisco.com Sometimes you see code that is perfectly OK according to the definition](https://reader035.fdocuments.net/reader035/viewer/2022062603/5f07bb087e708231d41e742b/html5/thumbnails/160.jpg)
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
![Page 161: Solid C++ code by example - pvv.orgoma/SolidCPP_Sept_2012.pdf · Solid C++ code by example olve.maudal@cisco.com Sometimes you see code that is perfectly OK according to the definition](https://reader035.fdocuments.net/reader035/viewer/2022062603/5f07bb087e708231d41e742b/html5/thumbnails/161.jpg)
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
![Page 162: Solid C++ code by example - pvv.orgoma/SolidCPP_Sept_2012.pdf · Solid C++ code by example olve.maudal@cisco.com Sometimes you see code that is perfectly OK according to the definition](https://reader035.fdocuments.net/reader035/viewer/2022062603/5f07bb087e708231d41e742b/html5/thumbnails/162.jpg)
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
![Page 163: Solid C++ code by example - pvv.orgoma/SolidCPP_Sept_2012.pdf · Solid C++ code by example olve.maudal@cisco.com Sometimes you see code that is perfectly OK according to the definition](https://reader035.fdocuments.net/reader035/viewer/2022062603/5f07bb087e708231d41e742b/html5/thumbnails/163.jpg)
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
![Page 164: Solid C++ code by example - pvv.orgoma/SolidCPP_Sept_2012.pdf · Solid C++ code by example olve.maudal@cisco.com Sometimes you see code that is perfectly OK according to the definition](https://reader035.fdocuments.net/reader035/viewer/2022062603/5f07bb087e708231d41e742b/html5/thumbnails/164.jpg)
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
![Page 165: Solid C++ code by example - pvv.orgoma/SolidCPP_Sept_2012.pdf · Solid C++ code by example olve.maudal@cisco.com Sometimes you see code that is perfectly OK according to the definition](https://reader035.fdocuments.net/reader035/viewer/2022062603/5f07bb087e708231d41e742b/html5/thumbnails/165.jpg)
( )
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
( )
![Page 166: Solid C++ code by example - pvv.orgoma/SolidCPP_Sept_2012.pdf · Solid C++ code by example olve.maudal@cisco.com Sometimes you see code that is perfectly OK according to the definition](https://reader035.fdocuments.net/reader035/viewer/2022062603/5f07bb087e708231d41e742b/html5/thumbnails/166.jpg)
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
( )
![Page 167: Solid C++ code by example - pvv.orgoma/SolidCPP_Sept_2012.pdf · Solid C++ code by example olve.maudal@cisco.com Sometimes you see code that is perfectly OK according to the definition](https://reader035.fdocuments.net/reader035/viewer/2022062603/5f07bb087e708231d41e742b/html5/thumbnails/167.jpg)
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
( )
![Page 168: Solid C++ code by example - pvv.orgoma/SolidCPP_Sept_2012.pdf · Solid C++ code by example olve.maudal@cisco.com Sometimes you see code that is perfectly OK according to the definition](https://reader035.fdocuments.net/reader035/viewer/2022062603/5f07bb087e708231d41e742b/html5/thumbnails/168.jpg)
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
![Page 169: Solid C++ code by example - pvv.orgoma/SolidCPP_Sept_2012.pdf · Solid C++ code by example olve.maudal@cisco.com Sometimes you see code that is perfectly OK according to the definition](https://reader035.fdocuments.net/reader035/viewer/2022062603/5f07bb087e708231d41e742b/html5/thumbnails/169.jpg)
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
![Page 170: Solid C++ code by example - pvv.orgoma/SolidCPP_Sept_2012.pdf · Solid C++ code by example olve.maudal@cisco.com Sometimes you see code that is perfectly OK according to the definition](https://reader035.fdocuments.net/reader035/viewer/2022062603/5f07bb087e708231d41e742b/html5/thumbnails/170.jpg)
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
![Page 171: Solid C++ code by example - pvv.orgoma/SolidCPP_Sept_2012.pdf · Solid C++ code by example olve.maudal@cisco.com Sometimes you see code that is perfectly OK according to the definition](https://reader035.fdocuments.net/reader035/viewer/2022062603/5f07bb087e708231d41e742b/html5/thumbnails/171.jpg)
type3_message.hpp
![Page 172: Solid C++ code by example - pvv.orgoma/SolidCPP_Sept_2012.pdf · Solid C++ code by example olve.maudal@cisco.com Sometimes you see code that is perfectly OK according to the definition](https://reader035.fdocuments.net/reader035/viewer/2022062603/5f07bb087e708231d41e742b/html5/thumbnails/172.jpg)
#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
![Page 173: Solid C++ code by example - pvv.orgoma/SolidCPP_Sept_2012.pdf · Solid C++ code by example olve.maudal@cisco.com Sometimes you see code that is perfectly OK according to the definition](https://reader035.fdocuments.net/reader035/viewer/2022062603/5f07bb087e708231d41e742b/html5/thumbnails/173.jpg)
#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
Find 3 issues
![Page 174: Solid C++ code by example - pvv.orgoma/SolidCPP_Sept_2012.pdf · Solid C++ code by example olve.maudal@cisco.com Sometimes you see code that is perfectly OK according to the definition](https://reader035.fdocuments.net/reader035/viewer/2022062603/5f07bb087e708231d41e742b/html5/thumbnails/174.jpg)
#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
![Page 175: Solid C++ code by example - pvv.orgoma/SolidCPP_Sept_2012.pdf · Solid C++ code by example olve.maudal@cisco.com Sometimes you see code that is perfectly OK according to the definition](https://reader035.fdocuments.net/reader035/viewer/2022062603/5f07bb087e708231d41e742b/html5/thumbnails/175.jpg)
#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
include <iosfwd> instead
![Page 176: Solid C++ code by example - pvv.orgoma/SolidCPP_Sept_2012.pdf · Solid C++ code by example olve.maudal@cisco.com Sometimes you see code that is perfectly OK according to the definition](https://reader035.fdocuments.net/reader035/viewer/2022062603/5f07bb087e708231d41e742b/html5/thumbnails/176.jpg)
#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
![Page 177: Solid C++ code by example - pvv.orgoma/SolidCPP_Sept_2012.pdf · Solid C++ code by example olve.maudal@cisco.com Sometimes you see code that is perfectly OK according to the definition](https://reader035.fdocuments.net/reader035/viewer/2022062603/5f07bb087e708231d41e742b/html5/thumbnails/177.jpg)
#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
this default argument is probably not needed
![Page 178: Solid C++ code by example - pvv.orgoma/SolidCPP_Sept_2012.pdf · Solid C++ code by example olve.maudal@cisco.com Sometimes you see code that is perfectly OK according to the definition](https://reader035.fdocuments.net/reader035/viewer/2022062603/5f07bb087e708231d41e742b/html5/thumbnails/178.jpg)
#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
![Page 179: Solid C++ code by example - pvv.orgoma/SolidCPP_Sept_2012.pdf · Solid C++ code by example olve.maudal@cisco.com Sometimes you see code that is perfectly OK according to the definition](https://reader035.fdocuments.net/reader035/viewer/2022062603/5f07bb087e708231d41e742b/html5/thumbnails/179.jpg)
#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
useless explicit specifier
![Page 180: Solid C++ code by example - pvv.orgoma/SolidCPP_Sept_2012.pdf · Solid C++ code by example olve.maudal@cisco.com Sometimes you see code that is perfectly OK according to the definition](https://reader035.fdocuments.net/reader035/viewer/2022062603/5f07bb087e708231d41e742b/html5/thumbnails/180.jpg)
#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
![Page 181: Solid C++ code by example - pvv.orgoma/SolidCPP_Sept_2012.pdf · Solid C++ code by example olve.maudal@cisco.com Sometimes you see code that is perfectly OK according to the definition](https://reader035.fdocuments.net/reader035/viewer/2022062603/5f07bb087e708231d41e742b/html5/thumbnails/181.jpg)
#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
![Page 182: Solid C++ code by example - pvv.orgoma/SolidCPP_Sept_2012.pdf · Solid C++ code by example olve.maudal@cisco.com Sometimes you see code that is perfectly OK according to the definition](https://reader035.fdocuments.net/reader035/viewer/2022062603/5f07bb087e708231d41e742b/html5/thumbnails/182.jpg)
#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
![Page 183: Solid C++ code by example - pvv.orgoma/SolidCPP_Sept_2012.pdf · Solid C++ code by example olve.maudal@cisco.com Sometimes you see code that is perfectly OK according to the definition](https://reader035.fdocuments.net/reader035/viewer/2022062603/5f07bb087e708231d41e742b/html5/thumbnails/183.jpg)
#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
![Page 184: Solid C++ code by example - pvv.orgoma/SolidCPP_Sept_2012.pdf · Solid C++ code by example olve.maudal@cisco.com Sometimes you see code that is perfectly OK according to the definition](https://reader035.fdocuments.net/reader035/viewer/2022062603/5f07bb087e708231d41e742b/html5/thumbnails/184.jpg)
#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 ); 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
= 0x202
explicit
![Page 185: Solid C++ code by example - pvv.orgoma/SolidCPP_Sept_2012.pdf · Solid C++ code by example olve.maudal@cisco.com Sometimes you see code that is perfectly OK according to the definition](https://reader035.fdocuments.net/reader035/viewer/2022062603/5f07bb087e708231d41e742b/html5/thumbnails/185.jpg)
#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 ); 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
= 0x202
![Page 186: Solid C++ code by example - pvv.orgoma/SolidCPP_Sept_2012.pdf · Solid C++ code by example olve.maudal@cisco.com Sometimes you see code that is perfectly OK according to the definition](https://reader035.fdocuments.net/reader035/viewer/2022062603/5f07bb087e708231d41e742b/html5/thumbnails/186.jpg)
#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 ); 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
= 0x202
![Page 187: Solid C++ code by example - pvv.orgoma/SolidCPP_Sept_2012.pdf · Solid C++ code by example olve.maudal@cisco.com Sometimes you see code that is perfectly OK according to the definition](https://reader035.fdocuments.net/reader035/viewer/2022062603/5f07bb087e708231d41e742b/html5/thumbnails/187.jpg)
#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 ); 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
![Page 188: Solid C++ code by example - pvv.orgoma/SolidCPP_Sept_2012.pdf · Solid C++ code by example olve.maudal@cisco.com Sometimes you see code that is perfectly OK according to the definition](https://reader035.fdocuments.net/reader035/viewer/2022062603/5f07bb087e708231d41e742b/html5/thumbnails/188.jpg)
#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); 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
![Page 189: Solid C++ code by example - pvv.orgoma/SolidCPP_Sept_2012.pdf · Solid C++ code by example olve.maudal@cisco.com Sometimes you see code that is perfectly OK according to the definition](https://reader035.fdocuments.net/reader035/viewer/2022062603/5f07bb087e708231d41e742b/html5/thumbnails/189.jpg)
#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); 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
![Page 190: Solid C++ code by example - pvv.orgoma/SolidCPP_Sept_2012.pdf · Solid C++ code by example olve.maudal@cisco.com Sometimes you see code that is perfectly OK according to the definition](https://reader035.fdocuments.net/reader035/viewer/2022062603/5f07bb087e708231d41e742b/html5/thumbnails/190.jpg)
#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); 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
Not too bad!
![Page 191: Solid C++ code by example - pvv.orgoma/SolidCPP_Sept_2012.pdf · Solid C++ code by example olve.maudal@cisco.com Sometimes you see code that is perfectly OK according to the definition](https://reader035.fdocuments.net/reader035/viewer/2022062603/5f07bb087e708231d41e742b/html5/thumbnails/191.jpg)
type3_message.cpp
![Page 192: Solid C++ code by example - pvv.orgoma/SolidCPP_Sept_2012.pdf · Solid C++ code by example olve.maudal@cisco.com Sometimes you see code that is perfectly OK according to the definition](https://reader035.fdocuments.net/reader035/viewer/2022062603/5f07bb087e708231d41e742b/html5/thumbnails/192.jpg)
pal::type3_message::type3_message( const std::vector<uint8_t> & lm_response, const std::vector<uint8_t> & nt_response, const std::string & user, uint32_t ssp_flags) : lm_response_(lm_response), nt_response_(nt_response), user_(user), ssp_flags_(ssp_flags), session_key_(session_key_size){ if (lm_response_.size() != lm_response_size) throw new std::invalid_argument("invalid size of lm_response"); if (nt_response_.size() != nt_response_size) throw new std::invalid_argument("invalid size of nt_response");}
...
...
![Page 193: Solid C++ code by example - pvv.orgoma/SolidCPP_Sept_2012.pdf · Solid C++ code by example olve.maudal@cisco.com Sometimes you see code that is perfectly OK according to the definition](https://reader035.fdocuments.net/reader035/viewer/2022062603/5f07bb087e708231d41e742b/html5/thumbnails/193.jpg)
pal::type3_message::type3_message( const std::vector<uint8_t> & lm_response, const std::vector<uint8_t> & nt_response, const std::string & user, uint32_t ssp_flags) : lm_response_(lm_response), nt_response_(nt_response), user_(user), ssp_flags_(ssp_flags), session_key_(session_key_size){ if (lm_response_.size() != lm_response_size) throw new std::invalid_argument("invalid size of lm_response"); if (nt_response_.size() != nt_response_size) throw new std::invalid_argument("invalid size of nt_response");}
...
...
Find 3 issues
![Page 194: Solid C++ code by example - pvv.orgoma/SolidCPP_Sept_2012.pdf · Solid C++ code by example olve.maudal@cisco.com Sometimes you see code that is perfectly OK according to the definition](https://reader035.fdocuments.net/reader035/viewer/2022062603/5f07bb087e708231d41e742b/html5/thumbnails/194.jpg)
pal::type3_message::type3_message( const std::vector<uint8_t> & lm_response, const std::vector<uint8_t> & nt_response, const std::string & user, uint32_t ssp_flags) : lm_response_(lm_response), nt_response_(nt_response), user_(user), ssp_flags_(ssp_flags), session_key_(session_key_size){ if (lm_response_.size() != lm_response_size) throw new std::invalid_argument("invalid size of lm_response"); if (nt_response_.size() != nt_response_size) throw new std::invalid_argument("invalid size of nt_response");}
...
...
![Page 195: Solid C++ code by example - pvv.orgoma/SolidCPP_Sept_2012.pdf · Solid C++ code by example olve.maudal@cisco.com Sometimes you see code that is perfectly OK according to the definition](https://reader035.fdocuments.net/reader035/viewer/2022062603/5f07bb087e708231d41e742b/html5/thumbnails/195.jpg)
pal::type3_message::type3_message( const std::vector<uint8_t> & lm_response, const std::vector<uint8_t> & nt_response, const std::string & user, uint32_t ssp_flags) : lm_response_(lm_response), nt_response_(nt_response), user_(user), ssp_flags_(ssp_flags), session_key_(session_key_size){ if (lm_response_.size() != lm_response_size) throw new std::invalid_argument("invalid size of lm_response"); if (nt_response_.size() != nt_response_size) throw new std::invalid_argument("invalid size of nt_response");}
...
...
WTF?
![Page 196: Solid C++ code by example - pvv.orgoma/SolidCPP_Sept_2012.pdf · Solid C++ code by example olve.maudal@cisco.com Sometimes you see code that is perfectly OK according to the definition](https://reader035.fdocuments.net/reader035/viewer/2022062603/5f07bb087e708231d41e742b/html5/thumbnails/196.jpg)
pal::type3_message::type3_message( const std::vector<uint8_t> & lm_response, const std::vector<uint8_t> & nt_response, const std::string & user, uint32_t ssp_flags) : lm_response_(lm_response), nt_response_(nt_response), user_(user), ssp_flags_(ssp_flags), session_key_(session_key_size){ if (lm_response_.size() != lm_response_size) throw new std::invalid_argument("invalid size of lm_response"); if (nt_response_.size() != nt_response_size) throw new std::invalid_argument("invalid size of nt_response");}
...
...
![Page 197: Solid C++ code by example - pvv.orgoma/SolidCPP_Sept_2012.pdf · Solid C++ code by example olve.maudal@cisco.com Sometimes you see code that is perfectly OK according to the definition](https://reader035.fdocuments.net/reader035/viewer/2022062603/5f07bb087e708231d41e742b/html5/thumbnails/197.jpg)
pal::type3_message::type3_message( const std::vector<uint8_t> & lm_response, const std::vector<uint8_t> & nt_response, const std::string & user, uint32_t ssp_flags) : lm_response_(lm_response), nt_response_(nt_response), user_(user), ssp_flags_(ssp_flags), session_key_(session_key_size){ if (lm_response_.size() != lm_response_size) throw new std::invalid_argument("invalid size of lm_response"); if (nt_response_.size() != nt_response_size) throw new std::invalid_argument("invalid size of nt_response");}
...
...
Does not match initialization order...
![Page 198: Solid C++ code by example - pvv.orgoma/SolidCPP_Sept_2012.pdf · Solid C++ code by example olve.maudal@cisco.com Sometimes you see code that is perfectly OK according to the definition](https://reader035.fdocuments.net/reader035/viewer/2022062603/5f07bb087e708231d41e742b/html5/thumbnails/198.jpg)
pal::type3_message::type3_message( const std::vector<uint8_t> & lm_response, const std::vector<uint8_t> & nt_response, const std::string & user, uint32_t ssp_flags) : lm_response_(lm_response), nt_response_(nt_response), user_(user), ssp_flags_(ssp_flags), session_key_(session_key_size){ if (lm_response_.size() != lm_response_size) throw new std::invalid_argument("invalid size of lm_response"); if (nt_response_.size() != nt_response_size) throw new std::invalid_argument("invalid size of nt_response");}
...
...
![Page 199: Solid C++ code by example - pvv.orgoma/SolidCPP_Sept_2012.pdf · Solid C++ code by example olve.maudal@cisco.com Sometimes you see code that is perfectly OK according to the definition](https://reader035.fdocuments.net/reader035/viewer/2022062603/5f07bb087e708231d41e742b/html5/thumbnails/199.jpg)
pal::type3_message::type3_message( const std::vector<uint8_t> & lm_response, const std::vector<uint8_t> & nt_response, const std::string & user, uint32_t ssp_flags) : lm_response_(lm_response), nt_response_(nt_response), user_(user), ssp_flags_(ssp_flags), session_key_(session_key_size){ if (lm_response_.size() != lm_response_size) throw new std::invalid_argument("invalid size of lm_response"); if (nt_response_.size() != nt_response_size) throw new std::invalid_argument("invalid size of nt_response");}
...
...
... but this indicates a deeper problem, the user is not compiling with -Wall and -Wextra, or even worse... they
do not care about warnings!
![Page 200: Solid C++ code by example - pvv.orgoma/SolidCPP_Sept_2012.pdf · Solid C++ code by example olve.maudal@cisco.com Sometimes you see code that is perfectly OK according to the definition](https://reader035.fdocuments.net/reader035/viewer/2022062603/5f07bb087e708231d41e742b/html5/thumbnails/200.jpg)
pal::type3_message::type3_message( const std::vector<uint8_t> & lm_response, const std::vector<uint8_t> & nt_response, const std::string & user, uint32_t ssp_flags) : lm_response_(lm_response), nt_response_(nt_response), user_(user), ssp_flags_(ssp_flags), session_key_(session_key_size){ if (lm_response_.size() != lm_response_size) throw new std::invalid_argument("invalid size of lm_response"); if (nt_response_.size() != nt_response_size) throw new std::invalid_argument("invalid size of nt_response");}
...
...
![Page 201: Solid C++ code by example - pvv.orgoma/SolidCPP_Sept_2012.pdf · Solid C++ code by example olve.maudal@cisco.com Sometimes you see code that is perfectly OK according to the definition](https://reader035.fdocuments.net/reader035/viewer/2022062603/5f07bb087e708231d41e742b/html5/thumbnails/201.jpg)
pal::type3_message::type3_message( const std::vector<uint8_t> & lm_response, const std::vector<uint8_t> & nt_response, const std::string & user, uint32_t ssp_flags) : lm_response_(lm_response), nt_response_(nt_response), user_(user), ssp_flags_(ssp_flags), session_key_(session_key_size){ if (lm_response_.size() != lm_response_size) throw new std::invalid_argument("invalid size of lm_response"); if (nt_response_.size() != nt_response_size) throw new std::invalid_argument("invalid size of nt_response");}
...
...
It's often a good idea to explicitly initialize all object members. Consider the -Weffc++ flag
![Page 202: Solid C++ code by example - pvv.orgoma/SolidCPP_Sept_2012.pdf · Solid C++ code by example olve.maudal@cisco.com Sometimes you see code that is perfectly OK according to the definition](https://reader035.fdocuments.net/reader035/viewer/2022062603/5f07bb087e708231d41e742b/html5/thumbnails/202.jpg)
pal::type3_message::type3_message( const std::vector<uint8_t> & lm_response, const std::vector<uint8_t> & nt_response, const std::string & user, uint32_t ssp_flags) : lm_response_(lm_response), nt_response_(nt_response), user_(user), ssp_flags_(ssp_flags), session_key_(session_key_size){ if (lm_response_.size() != lm_response_size) throw new std::invalid_argument("invalid size of lm_response"); if (nt_response_.size() != nt_response_size) throw new std::invalid_argument("invalid size of nt_response");}
...
...
![Page 203: Solid C++ code by example - pvv.orgoma/SolidCPP_Sept_2012.pdf · Solid C++ code by example olve.maudal@cisco.com Sometimes you see code that is perfectly OK according to the definition](https://reader035.fdocuments.net/reader035/viewer/2022062603/5f07bb087e708231d41e742b/html5/thumbnails/203.jpg)
pal::type3_message::type3_message( const std::vector<uint8_t> & lm_response, const std::vector<uint8_t> & nt_response, const std::string & user, uint32_t ssp_flags) : lm_response_(lm_response), nt_response_(nt_response), user_(user), ssp_flags_(ssp_flags), session_key_(session_key_size){ if (lm_response_.size() != lm_response_size) throw new std::invalid_argument("invalid size of lm_response"); if (nt_response_.size() != nt_response_size) throw new std::invalid_argument("invalid size of nt_response");}
...
...
![Page 204: Solid C++ code by example - pvv.orgoma/SolidCPP_Sept_2012.pdf · Solid C++ code by example olve.maudal@cisco.com Sometimes you see code that is perfectly OK according to the definition](https://reader035.fdocuments.net/reader035/viewer/2022062603/5f07bb087e708231d41e742b/html5/thumbnails/204.jpg)
pal::type3_message::type3_message( const std::vector<uint8_t> & lm_response, const std::vector<uint8_t> & nt_response, const std::string & user, uint32_t ssp_flags) : lm_response_(lm_response), nt_response_(nt_response), user_(user), ssp_flags_(ssp_flags), session_key_(session_key_size){ if (lm_response_.size() != lm_response_size) throw std::invalid_argument("invalid size of lm_response"); if (nt_response_.size() != nt_response_size) throw std::invalid_argument("invalid size of nt_response");}
...
...
![Page 205: Solid C++ code by example - pvv.orgoma/SolidCPP_Sept_2012.pdf · Solid C++ code by example olve.maudal@cisco.com Sometimes you see code that is perfectly OK according to the definition](https://reader035.fdocuments.net/reader035/viewer/2022062603/5f07bb087e708231d41e742b/html5/thumbnails/205.jpg)
pal::type3_message::type3_message( const std::vector<uint8_t> & lm_response, const std::vector<uint8_t> & nt_response, const std::string & user, uint32_t ssp_flags) : lm_response_(lm_response), nt_response_(nt_response), user_(user), ssp_flags_(ssp_flags), session_key_(session_key_size){ if (lm_response_.size() != lm_response_size) throw std::invalid_argument("invalid size of lm_response"); if (nt_response_.size() != nt_response_size) throw std::invalid_argument("invalid size of nt_response");}
...
...
![Page 206: Solid C++ code by example - pvv.orgoma/SolidCPP_Sept_2012.pdf · Solid C++ code by example olve.maudal@cisco.com Sometimes you see code that is perfectly OK according to the definition](https://reader035.fdocuments.net/reader035/viewer/2022062603/5f07bb087e708231d41e742b/html5/thumbnails/206.jpg)
pal::type3_message::type3_message( const std::vector<uint8_t> & lm_response, const std::vector<uint8_t> & nt_response, const std::string & user, uint32_t ssp_flags) : lm_response_(lm_response), nt_response_(nt_response), user_(user), session_key_(session_key_size), ssp_flags_(ssp_flags){ if (lm_response_.size() != lm_response_size) throw std::invalid_argument("invalid size of lm_response"); if (nt_response_.size() != nt_response_size) throw std::invalid_argument("invalid size of nt_response");}
...
...
![Page 207: Solid C++ code by example - pvv.orgoma/SolidCPP_Sept_2012.pdf · Solid C++ code by example olve.maudal@cisco.com Sometimes you see code that is perfectly OK according to the definition](https://reader035.fdocuments.net/reader035/viewer/2022062603/5f07bb087e708231d41e742b/html5/thumbnails/207.jpg)
pal::type3_message::type3_message( const std::vector<uint8_t> & lm_response, const std::vector<uint8_t> & nt_response, const std::string & user, uint32_t ssp_flags) : lm_response_(lm_response), nt_response_(nt_response),
user_(user),
session_key_(session_key_size), ssp_flags_(ssp_flags){ if (lm_response_.size() != lm_response_size) throw std::invalid_argument("invalid size of lm_response"); if (nt_response_.size() != nt_response_size) throw std::invalid_argument("invalid size of nt_response");}
...
...
![Page 208: Solid C++ code by example - pvv.orgoma/SolidCPP_Sept_2012.pdf · Solid C++ code by example olve.maudal@cisco.com Sometimes you see code that is perfectly OK according to the definition](https://reader035.fdocuments.net/reader035/viewer/2022062603/5f07bb087e708231d41e742b/html5/thumbnails/208.jpg)
pal::type3_message::type3_message( const std::vector<uint8_t> & lm_response, const std::vector<uint8_t> & nt_response, const std::string & user, uint32_t ssp_flags) : lm_response_(lm_response), nt_response_(nt_response), domain_(), user_(user), workstation_(), session_key_(session_key_size), ssp_flags_(ssp_flags){ if (lm_response_.size() != lm_response_size) throw std::invalid_argument("invalid size of lm_response"); if (nt_response_.size() != nt_response_size) throw std::invalid_argument("invalid size of nt_response");}
...
...
![Page 209: Solid C++ code by example - pvv.orgoma/SolidCPP_Sept_2012.pdf · Solid C++ code by example olve.maudal@cisco.com Sometimes you see code that is perfectly OK according to the definition](https://reader035.fdocuments.net/reader035/viewer/2022062603/5f07bb087e708231d41e742b/html5/thumbnails/209.jpg)
pal::type3_message::type3_message( const std::vector<uint8_t> & lm_response, const std::vector<uint8_t> & nt_response, const std::string & user, uint32_t ssp_flags) : lm_response_(lm_response), nt_response_(nt_response), domain_(), user_(user), workstation_(), session_key_(session_key_size), ssp_flags_(ssp_flags){ if (lm_response_.size() != lm_response_size) throw std::invalid_argument("invalid size of lm_response"); if (nt_response_.size() != nt_response_size) throw std::invalid_argument("invalid size of nt_response");}
...
...
![Page 210: Solid C++ code by example - pvv.orgoma/SolidCPP_Sept_2012.pdf · Solid C++ code by example olve.maudal@cisco.com Sometimes you see code that is perfectly OK according to the definition](https://reader035.fdocuments.net/reader035/viewer/2022062603/5f07bb087e708231d41e742b/html5/thumbnails/210.jpg)
pal::type3_message::type3_message( const std::vector<uint8_t> & lm_response, const std::vector<uint8_t> & nt_response, const std::string & user, uint32_t ssp_flags) : lm_response_(lm_response), nt_response_(nt_response), domain_(), user_(user), workstation_(), session_key_(session_key_size), ssp_flags_(ssp_flags){ if (lm_response_.size() != lm_response_size) throw std::invalid_argument("invalid size of lm_response"); if (nt_response_.size() != nt_response_size) throw std::invalid_argument("invalid size of nt_response");}
...
...
Much better!
![Page 211: Solid C++ code by example - pvv.orgoma/SolidCPP_Sept_2012.pdf · Solid C++ code by example olve.maudal@cisco.com Sometimes you see code that is perfectly OK according to the definition](https://reader035.fdocuments.net/reader035/viewer/2022062603/5f07bb087e708231d41e742b/html5/thumbnails/211.jpg)
void pal::type3_message::debug_print(std::ostream & out) const{ out << "### type3_message:" << '\n' << pal::as_hex_dump(as_bytes()) << "lm_response = " << pal::as_hex_string(lm_response_) << "\nnt_response = " << pal::as_hex_string(nt_response_) << "\ndomain = " << domain_ << "\nuser = " << user_ << "\nworkstation = " << workstation_ << "\nsession_key = " << pal::as_hex_string(session_key_) << std::hex << std::setw(8) << std::setfill('0') << "\nssp_flags = " << ssp_flags_;}
...
...
![Page 212: Solid C++ code by example - pvv.orgoma/SolidCPP_Sept_2012.pdf · Solid C++ code by example olve.maudal@cisco.com Sometimes you see code that is perfectly OK according to the definition](https://reader035.fdocuments.net/reader035/viewer/2022062603/5f07bb087e708231d41e742b/html5/thumbnails/212.jpg)
void pal::type3_message::debug_print(std::ostream & out) const{ out << "### type3_message:" << '\n' << pal::as_hex_dump(as_bytes()) << "lm_response = " << pal::as_hex_string(lm_response_) << "\nnt_response = " << pal::as_hex_string(nt_response_) << "\ndomain = " << domain_ << "\nuser = " << user_ << "\nworkstation = " << workstation_ << "\nsession_key = " << pal::as_hex_string(session_key_) << std::hex << std::setw(8) << std::setfill('0') << "\nssp_flags = " << ssp_flags_;}
...
...
Any issues here?
![Page 213: Solid C++ code by example - pvv.orgoma/SolidCPP_Sept_2012.pdf · Solid C++ code by example olve.maudal@cisco.com Sometimes you see code that is perfectly OK according to the definition](https://reader035.fdocuments.net/reader035/viewer/2022062603/5f07bb087e708231d41e742b/html5/thumbnails/213.jpg)
void pal::type3_message::debug_print(std::ostream & out) const{ out << "### type3_message:" << '\n' << pal::as_hex_dump(as_bytes()) << "lm_response = " << pal::as_hex_string(lm_response_) << "\nnt_response = " << pal::as_hex_string(nt_response_) << "\ndomain = " << domain_ << "\nuser = " << user_ << "\nworkstation = " << workstation_ << "\nsession_key = " << pal::as_hex_string(session_key_) << std::hex << std::setw(8) << std::setfill('0') << "\nssp_flags = " << ssp_flags_;}
...
...
![Page 214: Solid C++ code by example - pvv.orgoma/SolidCPP_Sept_2012.pdf · Solid C++ code by example olve.maudal@cisco.com Sometimes you see code that is perfectly OK according to the definition](https://reader035.fdocuments.net/reader035/viewer/2022062603/5f07bb087e708231d41e742b/html5/thumbnails/214.jpg)
void pal::type3_message::debug_print(std::ostream & out) const{ out << "### type3_message:" << '\n' << pal::as_hex_dump(as_bytes()) << "lm_response = " << pal::as_hex_string(lm_response_) << "\nnt_response = " << pal::as_hex_string(nt_response_) << "\ndomain = " << domain_ << "\nuser = " << user_ << "\nworkstation = " << workstation_ << "\nsession_key = " << pal::as_hex_string(session_key_) << std::hex << std::setw(8) << std::setfill('0') << "\nssp_flags = " << ssp_flags_;}
...
...
DO NOT MESS WITH BORROWED THINGS!
![Page 215: Solid C++ code by example - pvv.orgoma/SolidCPP_Sept_2012.pdf · Solid C++ code by example olve.maudal@cisco.com Sometimes you see code that is perfectly OK according to the definition](https://reader035.fdocuments.net/reader035/viewer/2022062603/5f07bb087e708231d41e742b/html5/thumbnails/215.jpg)
void pal::type3_message::debug_print(std::ostream & out) const{ out << "### type3_message:" << '\n' << pal::as_hex_dump(as_bytes()) << "lm_response = " << pal::as_hex_string(lm_response_) << "\nnt_response = " << pal::as_hex_string(nt_response_) << "\ndomain = " << domain_ << "\nuser = " << user_ << "\nworkstation = " << workstation_ << "\nsession_key = " << pal::as_hex_string(session_key_) << std::hex << std::setw(8) << std::setfill('0') << "\nssp_flags = " << ssp_flags_;}
...
...
![Page 216: Solid C++ code by example - pvv.orgoma/SolidCPP_Sept_2012.pdf · Solid C++ code by example olve.maudal@cisco.com Sometimes you see code that is perfectly OK according to the definition](https://reader035.fdocuments.net/reader035/viewer/2022062603/5f07bb087e708231d41e742b/html5/thumbnails/216.jpg)
void pal::type3_message::debug_print(std::ostream & out) const{ out << "### type3_message:" << '\n' << pal::as_hex_dump(as_bytes()) << "lm_response = " << pal::as_hex_string(lm_response_) << "\nnt_response = " << pal::as_hex_string(nt_response_) << "\ndomain = " << domain_ << "\nuser = " << user_ << "\nworkstation = " << workstation_ << "\nsession_key = " << pal::as_hex_string(session_key_) << std::hex << std::setw(8) << std::setfill('0') << "\nssp_flags = " << ssp_flags_;}
...
...
No easy way to fix this! Probably better to build into a local stringstream and return it.
![Page 217: Solid C++ code by example - pvv.orgoma/SolidCPP_Sept_2012.pdf · Solid C++ code by example olve.maudal@cisco.com Sometimes you see code that is perfectly OK according to the definition](https://reader035.fdocuments.net/reader035/viewer/2022062603/5f07bb087e708231d41e742b/html5/thumbnails/217.jpg)
void pal::type3_message::debug_print(std::ostream & out) const{ out << "### type3_message:" << '\n' << pal::as_hex_dump(as_bytes()) << "lm_response = " << pal::as_hex_string(lm_response_) << "\nnt_response = " << pal::as_hex_string(nt_response_) << "\ndomain = " << domain_ << "\nuser = " << user_ << "\nworkstation = " << workstation_ << "\nsession_key = " << pal::as_hex_string(session_key_) << std::hex << std::setw(8) << std::setfill('0') << "\nssp_flags = " << ssp_flags_;}
...
...
![Page 218: Solid C++ code by example - pvv.orgoma/SolidCPP_Sept_2012.pdf · Solid C++ code by example olve.maudal@cisco.com Sometimes you see code that is perfectly OK according to the definition](https://reader035.fdocuments.net/reader035/viewer/2022062603/5f07bb087e708231d41e742b/html5/thumbnails/218.jpg)
std::string pal::type3_message::debug_print() const{ std::ostringstream buf; buf << "### type3_message:" << '\n' << pal::as_hex_dump(as_bytes()) << "lm_response = " << pal::as_hex_string(lm_response_) << "\nnt_response = " << pal::as_hex_string(nt_response_) << "\ndomain = " << domain_ << "\nuser = " << user_ << "\nworkstation = " << workstation_ << "\nsession_key = " << pal::as_hex_string(session_key_) << std::hex << std::setw(8) << std::setfill('0') << "\nssp_flags = " << ssp_flags_; return buf.str();}
...
...
![Page 219: Solid C++ code by example - pvv.orgoma/SolidCPP_Sept_2012.pdf · Solid C++ code by example olve.maudal@cisco.com Sometimes you see code that is perfectly OK according to the definition](https://reader035.fdocuments.net/reader035/viewer/2022062603/5f07bb087e708231d41e742b/html5/thumbnails/219.jpg)
std::string pal::type3_message::debug_print() const{ std::ostringstream buf; buf << "### type3_message:" << '\n' << pal::as_hex_dump(as_bytes()) << "lm_response = " << pal::as_hex_string(lm_response_) << "\nnt_response = " << pal::as_hex_string(nt_response_) << "\ndomain = " << domain_ << "\nuser = " << user_ << "\nworkstation = " << workstation_ << "\nsession_key = " << pal::as_hex_string(session_key_) << std::hex << std::setw(8) << std::setfill('0') << "\nssp_flags = " << ssp_flags_; return buf.str();}
...
...
![Page 220: Solid C++ code by example - pvv.orgoma/SolidCPP_Sept_2012.pdf · Solid C++ code by example olve.maudal@cisco.com Sometimes you see code that is perfectly OK according to the definition](https://reader035.fdocuments.net/reader035/viewer/2022062603/5f07bb087e708231d41e742b/html5/thumbnails/220.jpg)
std::string pal::type3_message::debug_print() const{ std::ostringstream buf; buf << "### type3_message:" << '\n' << pal::as_hex_dump(as_bytes()) << "lm_response = " << pal::as_hex_string(lm_response_) << "\nnt_response = " << pal::as_hex_string(nt_response_) << "\ndomain = " << domain_ << "\nuser = " << user_ << "\nworkstation = " << workstation_ << "\nsession_key = " << pal::as_hex_string(session_key_) << std::hex << std::setw(8) << std::setfill('0') << "\nssp_flags = " << ssp_flags_; return buf.str();}
...
...
Big improvement!
![Page 221: Solid C++ code by example - pvv.orgoma/SolidCPP_Sept_2012.pdf · Solid C++ code by example olve.maudal@cisco.com Sometimes you see code that is perfectly OK according to the definition](https://reader035.fdocuments.net/reader035/viewer/2022062603/5f07bb087e708231d41e742b/html5/thumbnails/221.jpg)
Issues discussed here
![Page 222: Solid C++ code by example - pvv.orgoma/SolidCPP_Sept_2012.pdf · Solid C++ code by example olve.maudal@cisco.com Sometimes you see code that is perfectly OK according to the definition](https://reader035.fdocuments.net/reader035/viewer/2022062603/5f07bb087e708231d41e742b/html5/thumbnails/222.jpg)
1. base classes should have virtual destructors
Issues discussed here
![Page 223: Solid C++ code by example - pvv.orgoma/SolidCPP_Sept_2012.pdf · Solid C++ code by example olve.maudal@cisco.com Sometimes you see code that is perfectly OK according to the definition](https://reader035.fdocuments.net/reader035/viewer/2022062603/5f07bb087e708231d41e742b/html5/thumbnails/223.jpg)
1. base classes should have virtual destructors2. header files should have header guards
Issues discussed here
![Page 224: Solid C++ code by example - pvv.orgoma/SolidCPP_Sept_2012.pdf · Solid C++ code by example olve.maudal@cisco.com Sometimes you see code that is perfectly OK according to the definition](https://reader035.fdocuments.net/reader035/viewer/2022062603/5f07bb087e708231d41e742b/html5/thumbnails/224.jpg)
1. base classes should have virtual destructors2. header files should have header guards3. make sure you include the proper header files, especially in header files
Issues discussed here
![Page 225: Solid C++ code by example - pvv.orgoma/SolidCPP_Sept_2012.pdf · Solid C++ code by example olve.maudal@cisco.com Sometimes you see code that is perfectly OK according to the definition](https://reader035.fdocuments.net/reader035/viewer/2022062603/5f07bb087e708231d41e742b/html5/thumbnails/225.jpg)
1. base classes should have virtual destructors2. header files should have header guards3. make sure you include the proper header files, especially in header files4. no need to include files included by the base class declaration
Issues discussed here
![Page 226: Solid C++ code by example - pvv.orgoma/SolidCPP_Sept_2012.pdf · Solid C++ code by example olve.maudal@cisco.com Sometimes you see code that is perfectly OK according to the definition](https://reader035.fdocuments.net/reader035/viewer/2022062603/5f07bb087e708231d41e742b/html5/thumbnails/226.jpg)
1. base classes should have virtual destructors2. header files should have header guards3. make sure you include the proper header files, especially in header files4. no need to include files included by the base class declaration5. single argument constructors should be specified as explicit
Issues discussed here
![Page 227: Solid C++ code by example - pvv.orgoma/SolidCPP_Sept_2012.pdf · Solid C++ code by example olve.maudal@cisco.com Sometimes you see code that is perfectly OK according to the definition](https://reader035.fdocuments.net/reader035/viewer/2022062603/5f07bb087e708231d41e742b/html5/thumbnails/227.jpg)
1. base classes should have virtual destructors2. header files should have header guards3. make sure you include the proper header files, especially in header files4. no need to include files included by the base class declaration5. single argument constructors should be specified as explicit6. focus on usage of class; public stuff first, then private stuff
Issues discussed here
![Page 228: Solid C++ code by example - pvv.orgoma/SolidCPP_Sept_2012.pdf · Solid C++ code by example olve.maudal@cisco.com Sometimes you see code that is perfectly OK according to the definition](https://reader035.fdocuments.net/reader035/viewer/2022062603/5f07bb087e708231d41e742b/html5/thumbnails/228.jpg)
1. base classes should have virtual destructors2. header files should have header guards3. make sure you include the proper header files, especially in header files4. no need to include files included by the base class declaration5. single argument constructors should be specified as explicit6. focus on usage of class; public stuff first, then private stuff7. always focus on readability, you spend more time reading code than writing it
Issues discussed here
![Page 229: Solid C++ code by example - pvv.orgoma/SolidCPP_Sept_2012.pdf · Solid C++ code by example olve.maudal@cisco.com Sometimes you see code that is perfectly OK according to the definition](https://reader035.fdocuments.net/reader035/viewer/2022062603/5f07bb087e708231d41e742b/html5/thumbnails/229.jpg)
1. base classes should have virtual destructors2. header files should have header guards3. make sure you include the proper header files, especially in header files4. no need to include files included by the base class declaration5. single argument constructors should be specified as explicit6. focus on usage of class; public stuff first, then private stuff7. always focus on readability, you spend more time reading code than writing it8. importing a namespace in implementation files is usually not a good idea
Issues discussed here
![Page 230: Solid C++ code by example - pvv.orgoma/SolidCPP_Sept_2012.pdf · Solid C++ code by example olve.maudal@cisco.com Sometimes you see code that is perfectly OK according to the definition](https://reader035.fdocuments.net/reader035/viewer/2022062603/5f07bb087e708231d41e742b/html5/thumbnails/230.jpg)
1. base classes should have virtual destructors2. header files should have header guards3. make sure you include the proper header files, especially in header files4. no need to include files included by the base class declaration5. single argument constructors should be specified as explicit6. focus on usage of class; public stuff first, then private stuff7. always focus on readability, you spend more time reading code than writing it8. importing a namespace in implementation files is usually not a good idea9. "never" import a namespace in a header file
Issues discussed here
![Page 231: Solid C++ code by example - pvv.orgoma/SolidCPP_Sept_2012.pdf · Solid C++ code by example olve.maudal@cisco.com Sometimes you see code that is perfectly OK according to the definition](https://reader035.fdocuments.net/reader035/viewer/2022062603/5f07bb087e708231d41e742b/html5/thumbnails/231.jpg)
1. base classes should have virtual destructors2. header files should have header guards3. make sure you include the proper header files, especially in header files4. no need to include files included by the base class declaration5. single argument constructors should be specified as explicit6. focus on usage of class; public stuff first, then private stuff7. always focus on readability, you spend more time reading code than writing it8. importing a namespace in implementation files is usually not a good idea9. "never" import a namespace in a header file10. initialize objects properly, use the initialization list
Issues discussed here
![Page 232: Solid C++ code by example - pvv.orgoma/SolidCPP_Sept_2012.pdf · Solid C++ code by example olve.maudal@cisco.com Sometimes you see code that is perfectly OK according to the definition](https://reader035.fdocuments.net/reader035/viewer/2022062603/5f07bb087e708231d41e742b/html5/thumbnails/232.jpg)
1. base classes should have virtual destructors2. header files should have header guards3. make sure you include the proper header files, especially in header files4. no need to include files included by the base class declaration5. single argument constructors should be specified as explicit6. focus on usage of class; public stuff first, then private stuff7. always focus on readability, you spend more time reading code than writing it8. importing a namespace in implementation files is usually not a good idea9. "never" import a namespace in a header file10. initialize objects properly, use the initialization list11. prefer std::size_t when working with memory indexing and offsets
Issues discussed here
![Page 233: Solid C++ code by example - pvv.orgoma/SolidCPP_Sept_2012.pdf · Solid C++ code by example olve.maudal@cisco.com Sometimes you see code that is perfectly OK according to the definition](https://reader035.fdocuments.net/reader035/viewer/2022062603/5f07bb087e708231d41e742b/html5/thumbnails/233.jpg)
1. base classes should have virtual destructors2. header files should have header guards3. make sure you include the proper header files, especially in header files4. no need to include files included by the base class declaration5. single argument constructors should be specified as explicit6. focus on usage of class; public stuff first, then private stuff7. always focus on readability, you spend more time reading code than writing it8. importing a namespace in implementation files is usually not a good idea9. "never" import a namespace in a header file10. initialize objects properly, use the initialization list11. prefer std::size_t when working with memory indexing and offsets12. for non-trivial objects, prefer pass by const over pass by copy
Issues discussed here
![Page 234: Solid C++ code by example - pvv.orgoma/SolidCPP_Sept_2012.pdf · Solid C++ code by example olve.maudal@cisco.com Sometimes you see code that is perfectly OK according to the definition](https://reader035.fdocuments.net/reader035/viewer/2022062603/5f07bb087e708231d41e742b/html5/thumbnails/234.jpg)
1. base classes should have virtual destructors2. header files should have header guards3. make sure you include the proper header files, especially in header files4. no need to include files included by the base class declaration5. single argument constructors should be specified as explicit6. focus on usage of class; public stuff first, then private stuff7. always focus on readability, you spend more time reading code than writing it8. importing a namespace in implementation files is usually not a good idea9. "never" import a namespace in a header file10. initialize objects properly, use the initialization list11. prefer std::size_t when working with memory indexing and offsets12. for non-trivial objects, prefer pass by const over pass by copy13. query methods should be specified as const
Issues discussed here
![Page 235: Solid C++ code by example - pvv.orgoma/SolidCPP_Sept_2012.pdf · Solid C++ code by example olve.maudal@cisco.com Sometimes you see code that is perfectly OK according to the definition](https://reader035.fdocuments.net/reader035/viewer/2022062603/5f07bb087e708231d41e742b/html5/thumbnails/235.jpg)
1. base classes should have virtual destructors2. header files should have header guards3. make sure you include the proper header files, especially in header files4. no need to include files included by the base class declaration5. single argument constructors should be specified as explicit6. focus on usage of class; public stuff first, then private stuff7. always focus on readability, you spend more time reading code than writing it8. importing a namespace in implementation files is usually not a good idea9. "never" import a namespace in a header file10. initialize objects properly, use the initialization list11. prefer std::size_t when working with memory indexing and offsets12. for non-trivial objects, prefer pass by const over pass by copy13. query methods should be specified as const14. order the include files like this; own, project/platform, standard
Issues discussed here
![Page 236: Solid C++ code by example - pvv.orgoma/SolidCPP_Sept_2012.pdf · Solid C++ code by example olve.maudal@cisco.com Sometimes you see code that is perfectly OK according to the definition](https://reader035.fdocuments.net/reader035/viewer/2022062603/5f07bb087e708231d41e742b/html5/thumbnails/236.jpg)
1. base classes should have virtual destructors2. header files should have header guards3. make sure you include the proper header files, especially in header files4. no need to include files included by the base class declaration5. single argument constructors should be specified as explicit6. focus on usage of class; public stuff first, then private stuff7. always focus on readability, you spend more time reading code than writing it8. importing a namespace in implementation files is usually not a good idea9. "never" import a namespace in a header file10. initialize objects properly, use the initialization list11. prefer std::size_t when working with memory indexing and offsets12. for non-trivial objects, prefer pass by const over pass by copy13. query methods should be specified as const14. order the include files like this; own, project/platform, standard15. avoid magic numbers, use explaination variables
Issues discussed here
![Page 237: Solid C++ code by example - pvv.orgoma/SolidCPP_Sept_2012.pdf · Solid C++ code by example olve.maudal@cisco.com Sometimes you see code that is perfectly OK according to the definition](https://reader035.fdocuments.net/reader035/viewer/2022062603/5f07bb087e708231d41e742b/html5/thumbnails/237.jpg)
1. base classes should have virtual destructors2. header files should have header guards3. make sure you include the proper header files, especially in header files4. no need to include files included by the base class declaration5. single argument constructors should be specified as explicit6. focus on usage of class; public stuff first, then private stuff7. always focus on readability, you spend more time reading code than writing it8. importing a namespace in implementation files is usually not a good idea9. "never" import a namespace in a header file10. initialize objects properly, use the initialization list11. prefer std::size_t when working with memory indexing and offsets12. for non-trivial objects, prefer pass by const over pass by copy13. query methods should be specified as const14. order the include files like this; own, project/platform, standard15. avoid magic numbers, use explaination variables16. avoid superfluous use of ()
Issues discussed here
![Page 238: Solid C++ code by example - pvv.orgoma/SolidCPP_Sept_2012.pdf · Solid C++ code by example olve.maudal@cisco.com Sometimes you see code that is perfectly OK according to the definition](https://reader035.fdocuments.net/reader035/viewer/2022062603/5f07bb087e708231d41e742b/html5/thumbnails/238.jpg)
1. base classes should have virtual destructors2. header files should have header guards3. make sure you include the proper header files, especially in header files4. no need to include files included by the base class declaration5. single argument constructors should be specified as explicit6. focus on usage of class; public stuff first, then private stuff7. always focus on readability, you spend more time reading code than writing it8. importing a namespace in implementation files is usually not a good idea9. "never" import a namespace in a header file10. initialize objects properly, use the initialization list11. prefer std::size_t when working with memory indexing and offsets12. for non-trivial objects, prefer pass by const over pass by copy13. query methods should be specified as const14. order the include files like this; own, project/platform, standard15. avoid magic numbers, use explaination variables16. avoid superfluous use of ()17. prefer forward declarations when you can
Issues discussed here
![Page 239: Solid C++ code by example - pvv.orgoma/SolidCPP_Sept_2012.pdf · Solid C++ code by example olve.maudal@cisco.com Sometimes you see code that is perfectly OK according to the definition](https://reader035.fdocuments.net/reader035/viewer/2022062603/5f07bb087e708231d41e742b/html5/thumbnails/239.jpg)
1. base classes should have virtual destructors2. header files should have header guards3. make sure you include the proper header files, especially in header files4. no need to include files included by the base class declaration5. single argument constructors should be specified as explicit6. focus on usage of class; public stuff first, then private stuff7. always focus on readability, you spend more time reading code than writing it8. importing a namespace in implementation files is usually not a good idea9. "never" import a namespace in a header file10. initialize objects properly, use the initialization list11. prefer std::size_t when working with memory indexing and offsets12. for non-trivial objects, prefer pass by const over pass by copy13. query methods should be specified as const14. order the include files like this; own, project/platform, standard15. avoid magic numbers, use explaination variables16. avoid superfluous use of ()17. prefer forward declarations when you can18. do not use explicit on multi argument constructors
Issues discussed here
![Page 240: Solid C++ code by example - pvv.orgoma/SolidCPP_Sept_2012.pdf · Solid C++ code by example olve.maudal@cisco.com Sometimes you see code that is perfectly OK according to the definition](https://reader035.fdocuments.net/reader035/viewer/2022062603/5f07bb087e708231d41e742b/html5/thumbnails/240.jpg)
1. base classes should have virtual destructors2. header files should have header guards3. make sure you include the proper header files, especially in header files4. no need to include files included by the base class declaration5. single argument constructors should be specified as explicit6. focus on usage of class; public stuff first, then private stuff7. always focus on readability, you spend more time reading code than writing it8. importing a namespace in implementation files is usually not a good idea9. "never" import a namespace in a header file10. initialize objects properly, use the initialization list11. prefer std::size_t when working with memory indexing and offsets12. for non-trivial objects, prefer pass by const over pass by copy13. query methods should be specified as const14. order the include files like this; own, project/platform, standard15. avoid magic numbers, use explaination variables16. avoid superfluous use of ()17. prefer forward declarations when you can18. do not use explicit on multi argument constructors19. consider explainability, don't do things that needs elaborate explainations
Issues discussed here
![Page 241: Solid C++ code by example - pvv.orgoma/SolidCPP_Sept_2012.pdf · Solid C++ code by example olve.maudal@cisco.com Sometimes you see code that is perfectly OK according to the definition](https://reader035.fdocuments.net/reader035/viewer/2022062603/5f07bb087e708231d41e742b/html5/thumbnails/241.jpg)
1. base classes should have virtual destructors2. header files should have header guards3. make sure you include the proper header files, especially in header files4. no need to include files included by the base class declaration5. single argument constructors should be specified as explicit6. focus on usage of class; public stuff first, then private stuff7. always focus on readability, you spend more time reading code than writing it8. importing a namespace in implementation files is usually not a good idea9. "never" import a namespace in a header file10. initialize objects properly, use the initialization list11. prefer std::size_t when working with memory indexing and offsets12. for non-trivial objects, prefer pass by const over pass by copy13. query methods should be specified as const14. order the include files like this; own, project/platform, standard15. avoid magic numbers, use explaination variables16. avoid superfluous use of ()17. prefer forward declarations when you can18. do not use explicit on multi argument constructors19. consider explainability, don't do things that needs elaborate explainations20. avoid default arguments (they are often not used anyway)
Issues discussed here
![Page 242: Solid C++ code by example - pvv.orgoma/SolidCPP_Sept_2012.pdf · Solid C++ code by example olve.maudal@cisco.com Sometimes you see code that is perfectly OK according to the definition](https://reader035.fdocuments.net/reader035/viewer/2022062603/5f07bb087e708231d41e742b/html5/thumbnails/242.jpg)
1. base classes should have virtual destructors2. header files should have header guards3. make sure you include the proper header files, especially in header files4. no need to include files included by the base class declaration5. single argument constructors should be specified as explicit6. focus on usage of class; public stuff first, then private stuff7. always focus on readability, you spend more time reading code than writing it8. importing a namespace in implementation files is usually not a good idea9. "never" import a namespace in a header file10. initialize objects properly, use the initialization list11. prefer std::size_t when working with memory indexing and offsets12. for non-trivial objects, prefer pass by const over pass by copy13. query methods should be specified as const14. order the include files like this; own, project/platform, standard15. avoid magic numbers, use explaination variables16. avoid superfluous use of ()17. prefer forward declarations when you can18. do not use explicit on multi argument constructors19. consider explainability, don't do things that needs elaborate explainations20. avoid default arguments (they are often not used anyway)21. do not throw pointers to exceptions (eg, not "throw new ...")
Issues discussed here
![Page 243: Solid C++ code by example - pvv.orgoma/SolidCPP_Sept_2012.pdf · Solid C++ code by example olve.maudal@cisco.com Sometimes you see code that is perfectly OK according to the definition](https://reader035.fdocuments.net/reader035/viewer/2022062603/5f07bb087e708231d41e742b/html5/thumbnails/243.jpg)
1. base classes should have virtual destructors2. header files should have header guards3. make sure you include the proper header files, especially in header files4. no need to include files included by the base class declaration5. single argument constructors should be specified as explicit6. focus on usage of class; public stuff first, then private stuff7. always focus on readability, you spend more time reading code than writing it8. importing a namespace in implementation files is usually not a good idea9. "never" import a namespace in a header file10. initialize objects properly, use the initialization list11. prefer std::size_t when working with memory indexing and offsets12. for non-trivial objects, prefer pass by const over pass by copy13. query methods should be specified as const14. order the include files like this; own, project/platform, standard15. avoid magic numbers, use explaination variables16. avoid superfluous use of ()17. prefer forward declarations when you can18. do not use explicit on multi argument constructors19. consider explainability, don't do things that needs elaborate explainations20. 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)
Issues discussed here
![Page 244: Solid C++ code by example - pvv.orgoma/SolidCPP_Sept_2012.pdf · Solid C++ code by example olve.maudal@cisco.com Sometimes you see code that is perfectly OK according to the definition](https://reader035.fdocuments.net/reader035/viewer/2022062603/5f07bb087e708231d41e742b/html5/thumbnails/244.jpg)
1. base classes should have virtual destructors2. header files should have header guards3. make sure you include the proper header files, especially in header files4. no need to include files included by the base class declaration5. single argument constructors should be specified as explicit6. focus on usage of class; public stuff first, then private stuff7. always focus on readability, you spend more time reading code than writing it8. importing a namespace in implementation files is usually not a good idea9. "never" import a namespace in a header file10. initialize objects properly, use the initialization list11. prefer std::size_t when working with memory indexing and offsets12. for non-trivial objects, prefer pass by const over pass by copy13. query methods should be specified as const14. order the include files like this; own, project/platform, standard15. avoid magic numbers, use explaination variables16. avoid superfluous use of ()17. prefer forward declarations when you can18. do not use explicit on multi argument constructors19. consider explainability, don't do things that needs elaborate explainations20. 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
Issues discussed here
![Page 245: Solid C++ code by example - pvv.orgoma/SolidCPP_Sept_2012.pdf · Solid C++ code by example olve.maudal@cisco.com Sometimes you see code that is perfectly OK according to the definition](https://reader035.fdocuments.net/reader035/viewer/2022062603/5f07bb087e708231d41e742b/html5/thumbnails/245.jpg)
1. base classes should have virtual destructors2. header files should have header guards3. make sure you include the proper header files, especially in header files4. no need to include files included by the base class declaration5. single argument constructors should be specified as explicit6. focus on usage of class; public stuff first, then private stuff7. always focus on readability, you spend more time reading code than writing it8. importing a namespace in implementation files is usually not a good idea9. "never" import a namespace in a header file10. initialize objects properly, use the initialization list11. prefer std::size_t when working with memory indexing and offsets12. for non-trivial objects, prefer pass by const over pass by copy13. query methods should be specified as const14. order the include files like this; own, project/platform, standard15. avoid magic numbers, use explaination variables16. avoid superfluous use of ()17. prefer forward declarations when you can18. do not use explicit on multi argument constructors19. consider explainability, don't do things that needs elaborate explainations20. 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 well24. do not mess with borrowed things
Issues discussed here
![Page 246: Solid C++ code by example - pvv.orgoma/SolidCPP_Sept_2012.pdf · Solid C++ code by example olve.maudal@cisco.com Sometimes you see code that is perfectly OK according to the definition](https://reader035.fdocuments.net/reader035/viewer/2022062603/5f07bb087e708231d41e742b/html5/thumbnails/246.jpg)
1. base classes should have virtual destructors2. header files should have header guards3. make sure you include the proper header files, especially in header files4. no need to include files included by the base class declaration5. single argument constructors should be specified as explicit6. focus on usage of class; public stuff first, then private stuff7. always focus on readability, you spend more time reading code than writing it8. importing a namespace in implementation files is usually not a good idea9. "never" import a namespace in a header file10. initialize objects properly, use the initialization list11. prefer std::size_t when working with memory indexing and offsets12. for non-trivial objects, prefer pass by const over pass by copy13. query methods should be specified as const14. order the include files like this; own, project/platform, standard15. avoid magic numbers, use explaination variables16. avoid superfluous use of ()17. prefer forward declarations when you can18. do not use explicit on multi argument constructors19. consider explainability, don't do things that needs elaborate explainations20. 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 well24. do not mess with borrowed things25. always consider the sideeffects of what you do
Issues discussed here
![Page 247: Solid C++ code by example - pvv.orgoma/SolidCPP_Sept_2012.pdf · Solid C++ code by example olve.maudal@cisco.com Sometimes you see code that is perfectly OK according to the definition](https://reader035.fdocuments.net/reader035/viewer/2022062603/5f07bb087e708231d41e742b/html5/thumbnails/247.jpg)
are you now able to spot the “broken” C++?
![Page 248: Solid C++ code by example - pvv.orgoma/SolidCPP_Sept_2012.pdf · Solid C++ code by example olve.maudal@cisco.com Sometimes you see code that is perfectly OK according to the definition](https://reader035.fdocuments.net/reader035/viewer/2022062603/5f07bb087e708231d41e742b/html5/thumbnails/248.jpg)
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
![Page 249: Solid C++ code by example - pvv.orgoma/SolidCPP_Sept_2012.pdf · Solid C++ code by example olve.maudal@cisco.com Sometimes you see code that is perfectly OK according to the definition](https://reader035.fdocuments.net/reader035/viewer/2022062603/5f07bb087e708231d41e742b/html5/thumbnails/249.jpg)
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
![Page 250: Solid C++ code by example - pvv.orgoma/SolidCPP_Sept_2012.pdf · Solid C++ code by example olve.maudal@cisco.com Sometimes you see code that is perfectly OK according to the definition](https://reader035.fdocuments.net/reader035/viewer/2022062603/5f07bb087e708231d41e742b/html5/thumbnails/250.jpg)
![Page 251: Solid C++ code by example - pvv.orgoma/SolidCPP_Sept_2012.pdf · Solid C++ code by example olve.maudal@cisco.com Sometimes you see code that is perfectly OK according to the definition](https://reader035.fdocuments.net/reader035/viewer/2022062603/5f07bb087e708231d41e742b/html5/thumbnails/251.jpg)
!