diff options
-rw-r--r-- | cmd-option-letters | 2 | ||||
-rw-r--r-- | etc/anytun/client1/config | 2 | ||||
-rw-r--r-- | etc/anytun/client2/config | 2 | ||||
-rw-r--r-- | etc/anytun/client3/config | 2 | ||||
-rw-r--r-- | etc/anytun/p2p-a/config | 2 | ||||
-rw-r--r-- | etc/anytun/p2p-b/config | 2 | ||||
-rw-r--r-- | etc/anytun/server/conf.d/client1 | 2 | ||||
-rw-r--r-- | etc/anytun/server/conf.d/client2 | 2 | ||||
-rw-r--r-- | etc/anytun/server/conf.d/client3 | 2 | ||||
-rw-r--r-- | src/anytun-config.cpp | 23 | ||||
-rw-r--r-- | src/anytun.cpp | 3 | ||||
-rw-r--r-- | src/authAlgo.cpp | 4 | ||||
-rw-r--r-- | src/cipher.cpp | 4 | ||||
-rw-r--r-- | src/connectionList.cpp | 2 | ||||
-rw-r--r-- | src/datatypes.h | 1 | ||||
-rw-r--r-- | src/endian.h | 3 | ||||
-rw-r--r-- | src/keyDerivation.cpp | 91 | ||||
-rw-r--r-- | src/keyDerivation.h | 55 | ||||
-rw-r--r-- | src/man/anytun-config.8.txt | 16 | ||||
-rw-r--r-- | src/man/anytun.8.txt | 38 | ||||
-rw-r--r-- | src/options.cpp | 32 | ||||
-rw-r--r-- | src/options.h | 8 |
22 files changed, 173 insertions, 125 deletions
diff --git a/cmd-option-letters b/cmd-option-letters index b9c8eae..5533d21 100644 --- a/cmd-option-letters +++ b/cmd-option-letters @@ -5,7 +5,7 @@ a: auth algo b: auth tag length (not yet) c: cipher d: device name -e: +e: role f: input file g: unix group h: print help text diff --git a/etc/anytun/client1/config b/etc/anytun/client1/config index 8e7970a..3f19a85 100644 --- a/etc/anytun/client1/config +++ b/etc/anytun/client1/config @@ -2,6 +2,8 @@ ## Main options # ############################# +role client + ## Client ID ## (has to be unique for each client) mux 1 diff --git a/etc/anytun/client2/config b/etc/anytun/client2/config index a33419e..ff6b809 100644 --- a/etc/anytun/client2/config +++ b/etc/anytun/client2/config @@ -2,6 +2,8 @@ ## Main options # ############################# +role client + ## Client ID ## (has to be unique for each client) mux 2 diff --git a/etc/anytun/client3/config b/etc/anytun/client3/config index 5799470..670ae85 100644 --- a/etc/anytun/client3/config +++ b/etc/anytun/client3/config @@ -2,6 +2,8 @@ ## Main options # ############################# +role client + ## Client ID ## (has to be unique for each client) mux 3 diff --git a/etc/anytun/p2p-a/config b/etc/anytun/p2p-a/config index 1fa5763..59c35e6 100644 --- a/etc/anytun/p2p-a/config +++ b/etc/anytun/p2p-a/config @@ -2,6 +2,8 @@ ## Main options # ############################# +role alice + ## device type tun = ip/ipv6, tap = ethernet type tun diff --git a/etc/anytun/p2p-b/config b/etc/anytun/p2p-b/config index 340545a..3a92711 100644 --- a/etc/anytun/p2p-b/config +++ b/etc/anytun/p2p-b/config @@ -2,6 +2,8 @@ ## Main options # ############################# +role bob + ## device type tun = ip/ipv6, tap = ethernet type tun diff --git a/etc/anytun/server/conf.d/client1 b/etc/anytun/server/conf.d/client1 index fd56071..5099cef 100644 --- a/etc/anytun/server/conf.d/client1 +++ b/etc/anytun/server/conf.d/client1 @@ -2,6 +2,8 @@ ## main options # ############################# +role server + ## Client ID ## (has to be unique for each client) mux 1 diff --git a/etc/anytun/server/conf.d/client2 b/etc/anytun/server/conf.d/client2 index 59d2e21..e0b05d2 100644 --- a/etc/anytun/server/conf.d/client2 +++ b/etc/anytun/server/conf.d/client2 @@ -2,6 +2,8 @@ ## main options # ############################# +role server + ## Client ID ## (has to be unique for each client) mux 2 diff --git a/etc/anytun/server/conf.d/client3 b/etc/anytun/server/conf.d/client3 index a3a4fa0..8f22de0 100644 --- a/etc/anytun/server/conf.d/client3 +++ b/etc/anytun/server/conf.d/client3 @@ -2,6 +2,8 @@ ## main options # ############################# +role server + ## Client ID ## (has to be unique for each client) mux 3 diff --git a/src/anytun-config.cpp b/src/anytun-config.cpp index cafb753..466c36f 100644 --- a/src/anytun-config.cpp +++ b/src/anytun-config.cpp @@ -53,15 +53,16 @@ void createConnection(const PacketSourceEndpoint & remote_end, ConnectionList & { SeqWindow * seq = new SeqWindow(seqSize); seq_nr_t seq_nr_ = 0; - KeyDerivation * kd = KeyDerivationFactory::create( gOpt.getKdPrf() , gOpt.getAnytun02Compat() ); - kd->init( gOpt.getKey(), gOpt.getSalt() ); + KeyDerivation * kd = KeyDerivationFactory::create(gOpt.getKdPrf(), gOpt.getAnytun02Compat()); + kd->init(gOpt.getKey(), gOpt.getSalt(), gOpt.getPassphrase()); + kd->setRole(gOpt.getRole()); cLog.msg(Log::PRIO_NOTICE) << "added connection remote host " << remote_end; - ConnectionParam connparam ( (*kd), (*seq), seq_nr_, remote_end ); - cl.addConnection( connparam, mux ); + ConnectionParam connparam ((*kd), (*seq), seq_nr_, remote_end); + cl.addConnection(connparam, mux); std::ostringstream sout; - boost::archive::text_oarchive oa( sout ); - const SyncCommand scom( cl, mux ); + boost::archive::text_oarchive oa(sout); + const SyncCommand scom(cl, mux); oa << scom; std::cout << std::setw(5) << std::setfill('0') << sout.str().size()<< ' ' << sout.str() << std::endl; @@ -70,14 +71,14 @@ void createConnection(const PacketSourceEndpoint & remote_end, ConnectionList & NetworkList::const_iterator rit; for(rit = routes.begin(); rit != routes.end(); ++rit) { - NetworkAddress addr( rit->net_addr.c_str() ); - NetworkPrefix prefix( addr, rit->prefix_length ); + NetworkAddress addr(rit->net_addr.c_str()); + NetworkPrefix prefix(addr, rit->prefix_length); - gRoutingTable.addRoute( prefix, mux ); + gRoutingTable.addRoute(prefix, mux); std::ostringstream sout2; - boost::archive::text_oarchive oa2( sout2 ); - const SyncCommand scom2( prefix ); + boost::archive::text_oarchive oa2(sout2); + const SyncCommand scom2(prefix); oa2 << scom2; std::cout << std::setw(5) << std::setfill('0') << sout2.str().size()<< ' ' << sout2.str() << std::endl; diff --git a/src/anytun.cpp b/src/anytun.cpp index ef46a5e..c19ceb5 100644 --- a/src/anytun.cpp +++ b/src/anytun.cpp @@ -86,7 +86,7 @@ void createConnection(const PacketSourceEndpoint & remote_end, window_size_t seq seq_nr_t seq_nr_=0; KeyDerivation * kd = KeyDerivationFactory::create(gOpt.getKdPrf(), gOpt.getAnytun02Compat()); kd->init(gOpt.getKey(), gOpt.getSalt(), gOpt.getPassphrase()); - kd->setLogKDRate(gOpt.getLdKdr()); + kd->setRole(gOpt.getRole()); cLog.msg(Log::PRIO_NOTICE) << "added connection remote host " << remote_end; ConnectionParam connparam ((*kd), (*seq), seq_nr_, remote_end); @@ -419,7 +419,6 @@ int main(int argc, char* argv[]) cLog.msg(Log::PRIO_NOTICE) << "anytun started..."; gOpt.parse_post(); // print warnings - // daemonizing has to done before any thread gets started #ifndef NO_DAEMON #ifndef NO_PRIVDROP diff --git a/src/authAlgo.cpp b/src/authAlgo.cpp index 3f63c86..49974ee 100644 --- a/src/authAlgo.cpp +++ b/src/authAlgo.cpp @@ -86,7 +86,7 @@ void Sha1AuthAlgo::generate(KeyDerivation& kd, EncryptedPacket& packet) if(!packet.getAuthTagLength()) return; - kd.generate(dir_, LABEL_SATP_MSG_AUTH, packet.getSeqNr(), key_); + kd.generate(dir_, LABEL_AUTH, packet.getSeqNr(), key_); #ifndef USE_SSL_CRYPTO gcry_error_t err = gcry_md_setkey(handle_, key_.getBuf(), key_.getLength()); if(err) { @@ -126,7 +126,7 @@ bool Sha1AuthAlgo::checkTag(KeyDerivation& kd, EncryptedPacket& packet) if(!packet.getAuthTagLength()) return true; - kd.generate(dir_, LABEL_SATP_MSG_AUTH, packet.getSeqNr(), key_); + kd.generate(dir_, LABEL_AUTH, packet.getSeqNr(), key_); #ifndef USE_SSL_CRYPTO gcry_error_t err = gcry_md_setkey(handle_, key_.getBuf(), key_.getLength()); if(err) { diff --git a/src/cipher.cpp b/src/cipher.cpp index 3524052..15c9af2 100644 --- a/src/cipher.cpp +++ b/src/cipher.cpp @@ -140,7 +140,7 @@ u_int32_t AesIcmCipher::decipher(KeyDerivation& kd, u_int8_t* in, u_int32_t ilen void AesIcmCipher::calcCtr(KeyDerivation& kd, seq_nr_t seq_nr, sender_id_t sender_id, mux_t mux) { - kd.generate(dir_, LABEL_SATP_SALT, seq_nr, salt_); + kd.generate(dir_, LABEL_SALT, seq_nr, salt_); if(anytun02_compat_) { @@ -164,7 +164,7 @@ void AesIcmCipher::calc(KeyDerivation& kd, u_int8_t* in, u_int32_t ilen, u_int8_ return; #endif - kd.generate(dir_, LABEL_SATP_ENCRYPTION, seq_nr, key_); + kd.generate(dir_, LABEL_ENC, seq_nr, key_); #ifdef USE_SSL_CRYPTO int ret = AES_set_encrypt_key(key_.getBuf(), key_.getLength()*8, &aes_key_); if(ret) { diff --git a/src/connectionList.cpp b/src/connectionList.cpp index dd3fa6c..b21102a 100644 --- a/src/connectionList.cpp +++ b/src/connectionList.cpp @@ -130,7 +130,7 @@ ConnectionParam & ConnectionList::getOrNewConnectionUnlocked(u_int16_t mux) seq_nr_t seq_nr_=0; KeyDerivation * kd = KeyDerivationFactory::create(gOpt.getKdPrf(), gOpt.getAnytun02Compat()); kd->init(Buffer(key, sizeof(key)), Buffer(salt, sizeof(salt))); - ConnectionParam conn ( (*kd), (*seq), seq_nr_, PacketSourceEndpoint()); + ConnectionParam conn ((*kd), (*seq), seq_nr_, PacketSourceEndpoint()); connections_.insert(ConnectionMap::value_type(mux, conn)); it = connections_.find(mux); return it->second; diff --git a/src/datatypes.h b/src/datatypes.h index 23bdde6..141aae3 100644 --- a/src/datatypes.h +++ b/src/datatypes.h @@ -51,6 +51,7 @@ typedef u_int32_t seq_nr_t; typedef u_int16_t sender_id_t; typedef u_int16_t payload_type_t; typedef u_int16_t mux_t; +typedef u_int32_t satp_prf_label_t; typedef enum { ANY, IPV4_ONLY, IPV6_ONLY } ResolvAddrType; diff --git a/src/endian.h b/src/endian.h index b4cc995..9d96126 100644 --- a/src/endian.h +++ b/src/endian.h @@ -50,6 +50,9 @@ #define MUX_T_NTOH(a) ntohs(a) #define MUX_T_HTON(a) htons(a) +#define SATP_PRF_LABEL_T_NTOH(a) ntohl(a) +#define SATP_PRF_LABEL_T_HTON(a) htonl(a) + //#define AUTH_TAG_T_NTOH(a) ntohl(a) //#define AUTH_TAG_T_HTON(a) htonl(a) diff --git a/src/keyDerivation.cpp b/src/keyDerivation.cpp index 75c49ae..2e9dd94 100644 --- a/src/keyDerivation.cpp +++ b/src/keyDerivation.cpp @@ -50,12 +50,10 @@ #endif #endif -void KeyDerivation::setLogKDRate(const int8_t log_rate) +void KeyDerivation::setRole(const role_t role) { WritersLock lock(mutex_); - ld_kdr_ = log_rate; - if(ld_kdr_ > (int8_t)(sizeof(seq_nr_t) * 8)) - ld_kdr_ = sizeof(seq_nr_t) * 8; + role_ = role; } #ifndef NO_CRYPT @@ -120,6 +118,47 @@ void KeyDerivation::calcMasterSalt(std::string passphrase, u_int16_t length) #endif #endif +satp_prf_label_t KeyDerivation::convertLabel(kd_dir_t dir, satp_prf_label_t label) +{ + switch(label) { + case LABEL_ENC: { + if(dir == KD_OUTBOUND) { + if(role_ == ROLE_LEFT) return LABEL_LEFT_ENC; + if(role_ == ROLE_RIGHT) return LABEL_RIGHT_ENC; + } + else { + if(role_ == ROLE_LEFT) return LABEL_RIGHT_ENC; + if(role_ == ROLE_RIGHT) return LABEL_LEFT_ENC; + } + break; + } + case LABEL_SALT: { + if(dir == KD_OUTBOUND) { + if(role_ == ROLE_LEFT) return LABEL_LEFT_SALT; + if(role_ == ROLE_RIGHT) return LABEL_RIGHT_SALT; + } + else { + if(role_ == ROLE_LEFT) return LABEL_RIGHT_SALT; + if(role_ == ROLE_RIGHT) return LABEL_LEFT_SALT; + } + break; + } + case LABEL_AUTH: { + if(dir == KD_OUTBOUND) { + if(role_ == ROLE_LEFT) return LABEL_LEFT_AUTH; + if(role_ == ROLE_RIGHT) return LABEL_RIGHT_AUTH; + } + else { + if(role_ == ROLE_LEFT) return LABEL_RIGHT_AUTH; + if(role_ == ROLE_RIGHT) return LABEL_LEFT_AUTH; + } + break; + } + } + + return label; +} + //****** NullKeyDerivation ****** bool NullKeyDerivation::generate(kd_dir_t dir, satp_prf_label_t label, seq_nr_t seq_nr, Buffer& key) @@ -176,7 +215,7 @@ AesIcmKeyDerivation::~AesIcmKeyDerivation() void AesIcmKeyDerivation::init(Buffer key, Buffer salt, std::string passphrase) { WritersLock lock(mutex_); - + is_initialized_ = false; #ifndef NO_PASSPHRASE if(passphrase != "" && !key.getLength()) @@ -257,17 +296,8 @@ std::string AesIcmKeyDerivation::printType() return sstr.str(); } -bool AesIcmKeyDerivation::calcCtr(kd_dir_t dir, seq_nr_t* r, satp_prf_label_t label, seq_nr_t seq_nr) +bool AesIcmKeyDerivation::calcCtr(kd_dir_t dir, satp_prf_label_t label, seq_nr_t seq_nr) { - *r = 0; - if(ld_kdr_ >= 0) - *r = seq_nr >> ld_kdr_; - - if(key_store_[dir][label].key_.getLength() && key_store_[dir][label].r_ == *r) { - if(!(*r) || (seq_nr % (*r))) - return false; - } - if(master_salt_.getLength() != SALT_LENGTH) { cLog.msg(Log::PRIO_ERROR) << "KeyDerivation::calcCtr: salt lengths don't match"; return false; @@ -276,11 +306,11 @@ bool AesIcmKeyDerivation::calcCtr(kd_dir_t dir, seq_nr_t* r, satp_prf_label_t la ctr_[dir].salt_.zero_ = 0; if(anytun02_compat_) { ctr_[dir].params_compat_.label_ ^= label; - ctr_[dir].params_compat_.r_ ^= SEQ_NR_T_HTON(*r); + ctr_[dir].params_compat_.seq_ ^= SEQ_NR_T_HTON(seq_nr); } else { - ctr_[dir].params_.label_ ^= label; - ctr_[dir].params_.r_ ^= SEQ_NR_T_HTON(*r); + ctr_[dir].params_.label_ ^= SATP_PRF_LABEL_T_HTON(convertLabel(dir, label)); + ctr_[dir].params_.seq_ ^= SEQ_NR_T_HTON(seq_nr); } return true; @@ -293,20 +323,10 @@ bool AesIcmKeyDerivation::generate(kd_dir_t dir, satp_prf_label_t label, seq_nr_ if(!is_initialized_) return false; - seq_nr_t r; - calcCtr(dir, &r, label, seq_nr); - bool result = calcCtr(dir, &r, label, seq_nr); - if(!result) { - u_int32_t len = key.getLength(); - if(len > key_store_[dir][label].key_.getLength()) { - cLog.msg(Log::PRIO_WARNING) << "KeyDerivation::generate: stored (old) key for label " << label << " is too short, filling with zeros"; - std::memset(key.getBuf(), 0, len); - len = key_store_[dir][label].key_.getLength(); - } - std::memcpy(key.getBuf(), key_store_[dir][label].key_.getBuf(), len); + if(!calcCtr(dir, label, seq_nr)) { return false; } - + #ifndef USE_SSL_CRYPTO gcry_error_t err = gcry_cipher_reset(handle_[dir]); if(err) { @@ -324,7 +344,6 @@ bool AesIcmKeyDerivation::generate(kd_dir_t dir, satp_prf_label_t label, seq_nr_ if(err) { cLog.msg(Log::PRIO_ERROR) << "KeyDerivation::generate: Failed to generate cipher bitstream: " << AnytunGpgError(err); } - return true; #else if(CTR_LENGTH != AES_BLOCK_SIZE) { cLog.msg(Log::PRIO_ERROR) << "AesIcmCipher: Failed to set cipher CTR: size don't fits"; @@ -336,16 +355,6 @@ bool AesIcmKeyDerivation::generate(kd_dir_t dir, satp_prf_label_t label, seq_nr_ AES_ctr128_encrypt(key.getBuf(), key.getBuf(), key.getLength(), &aes_key_[dir], ctr_[dir].buf_, ecount_buf_[dir], &num); #endif - if(!ld_kdr_) - return true; - - if(key_store_[dir][label].key_.getLength() < key.getLength()) { - key_store_[dir][label].key_.setLength(key.getLength()); - } - - std::memcpy(key_store_[dir][label].key_.getBuf(), key.getBuf(), key.getLength()); - key_store_[dir][label].r_ = r; - return true; } #endif diff --git a/src/keyDerivation.h b/src/keyDerivation.h index 8318609..748a9a9 100644 --- a/src/keyDerivation.h +++ b/src/keyDerivation.h @@ -36,6 +36,7 @@ #include "buffer.h" #include "threadUtils.hpp" #include "syncBuffer.h" +#include "options.h" #ifndef NO_CRYPT #ifndef USE_SSL_CRYPTO @@ -47,39 +48,37 @@ #include <boost/archive/text_oarchive.hpp> #include <boost/archive/text_iarchive.hpp> -#define KD_LABEL_COUNT 3 -typedef enum { - LABEL_SATP_ENCRYPTION = 0x00, - LABEL_SATP_MSG_AUTH = 0x01, - LABEL_SATP_SALT = 0x02, -} satp_prf_label_t; +#define LABEL_ENC 0 +#define LABEL_AUTH 1 +#define LABEL_SALT 2 -typedef enum { - KD_INBOUND = 0, - KD_OUTBOUND = 1 -} kd_dir_t; +#define LABEL_LEFT_ENC 0xDEADBEEF +#define LABEL_RIGHT_ENC 0xDEAE0010 +#define LABEL_LEFT_SALT 0xDF10416F +#define LABEL_RIGHT_SALT 0xDF13FF90 +#define LABEL_LEFT_AUTH 0xE0000683 +#define LABEL_RIGHT_AUTH 0xE001B97C -typedef struct { - Buffer key_; - seq_nr_t r_; -} key_store_t; +typedef enum { KD_INBOUND, KD_OUTBOUND } kd_dir_t; class KeyDerivation { public: - KeyDerivation() : is_initialized_(false), ld_kdr_(0), anytun02_compat_(false), key_length_(0), master_salt_(0), master_key_(0) {}; - KeyDerivation(bool a) : is_initialized_(false), ld_kdr_(0), anytun02_compat_(a), key_length_(0), master_salt_(0), master_key_(0) {}; - KeyDerivation(u_int16_t key_length) : is_initialized_(false), ld_kdr_(0), anytun02_compat_(false), key_length_(key_length), master_salt_(0), master_key_(0) {}; - KeyDerivation(bool a, u_int16_t key_length) : is_initialized_(false), ld_kdr_(0), anytun02_compat_(a), key_length_(key_length), master_salt_(0), master_key_(0) {}; + KeyDerivation() : is_initialized_(false), role_(ROLE_LEFT), anytun02_compat_(false), key_length_(0), master_salt_(0), master_key_(0) {}; + KeyDerivation(bool a) : is_initialized_(false), role_(ROLE_LEFT), anytun02_compat_(a), key_length_(0), master_salt_(0), master_key_(0) {}; + KeyDerivation(u_int16_t key_length) : is_initialized_(false), role_(ROLE_LEFT), anytun02_compat_(false), key_length_(key_length), master_salt_(0), master_key_(0) {}; + KeyDerivation(bool a, u_int16_t key_length) : is_initialized_(false), role_(ROLE_LEFT), anytun02_compat_(a), key_length_(key_length), master_salt_(0), master_key_(0) {}; virtual ~KeyDerivation() {}; - void setLogKDRate(const int8_t ld_rate); + void setRole(const role_t role); virtual void init(Buffer key, Buffer salt, std::string passphrase = "") = 0; virtual bool generate(kd_dir_t dir, satp_prf_label_t label, seq_nr_t seq_nr, Buffer& key) = 0; virtual std::string printType() { return "GenericKeyDerivation"; }; + satp_prf_label_t convertLabel(kd_dir_t dir, satp_prf_label_t label); + protected: virtual void updateMasterKey() = 0; @@ -94,7 +93,7 @@ protected: void serialize(Archive & ar, const unsigned int version) { WritersLock lock(mutex_); - ar & ld_kdr_; + ar & role_; ar & key_length_; ar & master_salt_; ar & master_key_; @@ -102,7 +101,7 @@ protected: } bool is_initialized_; - int8_t ld_kdr_; // ld(key_derivation_rate) + role_t role_; bool anytun02_compat_; u_int16_t key_length_; SyncBuffer master_salt_; @@ -166,7 +165,7 @@ public: private: void updateMasterKey(); - bool calcCtr(kd_dir_t dir, seq_nr_t* r, satp_prf_label_t label, seq_nr_t seq_nr); + bool calcCtr(kd_dir_t dir, satp_prf_label_t label, seq_nr_t seq_nr); friend class boost::serialization::access; template<class Archive> @@ -182,8 +181,6 @@ private: u_int8_t ecount_buf_[2][AES_BLOCK_SIZE]; #endif - key_store_t key_store_[2][KD_LABEL_COUNT]; - #ifdef _MSC_VER #pragma pack(push, 1) #endif @@ -194,16 +191,16 @@ private: u_int16_t zero_; } salt_; struct ATTR_PACKED { - u_int8_t fill_[SALT_LENGTH - sizeof(u_int8_t) - sizeof(seq_nr_t)]; - u_int8_t label_; - seq_nr_t r_; + u_int8_t fill_[SALT_LENGTH - sizeof(satp_prf_label_t) - sizeof(seq_nr_t)]; + satp_prf_label_t label_; + seq_nr_t seq_; u_int16_t zero_; } params_; struct ATTR_PACKED { u_int8_t fill_[SALT_LENGTH - sizeof(u_int8_t) - 2*sizeof(u_int8_t) - sizeof(seq_nr_t)]; u_int8_t label_; - u_int8_t r_fill_[2]; - seq_nr_t r_; + u_int8_t seq_fill_[2]; + seq_nr_t seq_; u_int16_t zero_; } params_compat_; } ctr_[2]; diff --git a/src/man/anytun-config.8.txt b/src/man/anytun-config.8.txt index 5c0c7a1..8eb2839 100644 --- a/src/man/anytun-config.8.txt +++ b/src/man/anytun-config.8.txt @@ -19,7 +19,7 @@ SYNOPSIS [ *-m|--mux* <mux-id> ] [ *-w|--window-size* <window size> ] [ *-k|--kd-prf* <kd-prf type> ] -[ *-O|--anytun02-compat* ] +[ *-e|--role <role>* ] [ *-E|--passphrase* <pass phrase> ] [ *-K|--key* <master key> ] [ *-A|--salt* <master salt> ] @@ -128,11 +128,15 @@ Possible values: * *aes-ctr-192* - AES in counter mode with 192 Bits * *aes-ctr-256* - AES in counter mode with 256 Bits --O|--anytun02-compat -~~~~~~~~~~~~~~~~~~~~ +-e|--role <role> +~~~~~~~~~~~~~~~~ -Enable compatibility mode with version of anytun 0.2.x and prior. -This is for backwards compaitbility to old internet draft of satp. +SATP uses different session keys for inbound and outbound traffic. The +role parameter is used to determine which keys to use for outbound or +inbound packets. On both sides of a vpn connection different roles have +to be used. Possible values are *left* and *right*. You may also use +*alice* or *server* as a replacement for *left* and *bob* or *client* as +a replacement for *right*. By default *left* is used. -E|--passphrase <pass phrase> ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -169,7 +173,7 @@ Add a client with Connection ID (Mux) 12 and add 2 Routes to this client ------------------------------------------------------------------------------------------------ # anytun-config -w 0 -m 12 -K 0123456789ABCDEFFEDCBA9876543210 -A 0123456789ABCDDCBA9876543210 \ - -R 192.0.2.0/24 -R 192.168.1.1/32 >> routingtable + -R 192.0.2.0/24 -R 192.168.1.1/32 -e server >> routingtable ------------------------------------------------------------------------------------------------ BUGS diff --git a/src/man/anytun.8.txt b/src/man/anytun.8.txt index e393b70..05a650c 100644 --- a/src/man/anytun.8.txt +++ b/src/man/anytun.8.txt @@ -35,7 +35,7 @@ SYNOPSIS [ *-s|--sender-id* <sender id> ] [ *-w|--window-size* <window size> ] [ *-k|--kd-prf* <kd-prf type> ] -[ *-O|--anytun02-compat* ] +[ *-e|--role <role>* ] [ *-E|--passphrase* <pass phrase> ] [ *-K|--key* <master key> ] [ *-A|--salt* <master salt> ] @@ -298,11 +298,15 @@ Possible values: * *aes-ctr-192* - AES in counter mode with 192 Bits * *aes-ctr-256* - AES in counter mode with 256 Bits --O|--anytun02-compat -~~~~~~~~~~~~~~~~~~~~ +-e|--role <role> +~~~~~~~~~~~~~~~~ -Enable compatibility mode with version of anytun 0.2.x and prior. -This is for backwards compaitbility to old internet draft of satp. +SATP uses different session keys for inbound and outbound traffic. The +role parameter is used to determine which keys to use for outbound or +inbound packets. On both sides of a vpn connection different roles have +to be used. Possible values are *left* and *right*. You may also use +*alice* or *server* as a replacement for *left* and *bob* or *client* as +a replacement for *right*. By default *left* is used. -E|--passphrase <pass phrase> ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -372,12 +376,12 @@ Host A: ^^^^^^^ anytun -r hostb.example.com -t tun -n 192.168.123.1/30 -c aes-ctr-256 -k aes-ctr-256 \ - -E have_a_very_safe_and_productive_day + -E have_a_very_safe_and_productive_day -e left Host B: ^^^^^^^ anytun -r hosta.example.com -t tun -n 192.168.123.2/30 -c aes-ctr-256 -k aes-ctr-256 \ - -E have_a_very_safe_and_productive_day + -E have_a_very_safe_and_productive_day -e right One unicast and one anycast tunnel endpoint: @@ -386,31 +390,31 @@ One unicast and one anycast tunnel endpoint: Unicast tunnel endpoint: ^^^^^^^^^^^^^^^^^^^^^^^^ -anytun -r anycast.anytun.org -d anytun0 -t tun -n 192.0.2.2/30 -a null -c null -w 0 +anytun -r anycast.anytun.org -d anytun0 -t tun -n 192.0.2.2/30 -a null -c null -w 0 -e client Anycast tunnel endpoints: ^^^^^^^^^^^^^^^^^^^^^^^^^ On the host with unicast hostname unicast1.anycast.anytun.org and anycast hostname anycast.anytun.org: ---------------------------------------------------------------------------------------- -# anytun -i anycast.anytun.org -d anytun0 -t tun -n 192.0.2.1/30 -a null -c null -w 0 \ +------------------------------------------------------------------------------------------------- +# anytun -i anycast.anytun.org -d anytun0 -t tun -n 192.0.2.1/30 -a null -c null -w 0 -e server \ -S 2342 -M unicast2.anycast.anytun.org:2342,unicast3.anycast.anytun.org:2342 ---------------------------------------------------------------------------------------- +------------------------------------------------------------------------------------------------- On the host with unicast hostname unicast2.anycast.anytun.org and anycast hostname anycast.anytun.org: ---------------------------------------------------------------------------------------- -# anytun -i anycast.anytun.org -d anytun0 -t tun -n 192.0.2.1/30 -a null -c null -w 0 \ +------------------------------------------------------------------------------------------------- +# anytun -i anycast.anytun.org -d anytun0 -t tun -n 192.0.2.1/30 -a null -c null -w 0 -e server \ -S 2342 -M unicast1.anycast.anytun.org:2342,unicast3.anycast.anytun.org:2342 ---------------------------------------------------------------------------------------- +------------------------------------------------------------------------------------------------- On the host with unicast hostname unicast3.anycast.anytun.org and anycast hostname anycast.anytun.org: ---------------------------------------------------------------------------------------- -# anytun -i anycast.anytun.org -d anytun0 -t tun -n 192.0.2.1/30 -a null -c null -w 0 \ +------------------------------------------------------------------------------------------------- +# anytun -i anycast.anytun.org -d anytun0 -t tun -n 192.0.2.1/30 -a null -c null -w 0 -e server \ -S 2342 -M unicast1.anycast.anytun.org:2342,unicast2.anycast.anytun.org:2342 ---------------------------------------------------------------------------------------- +------------------------------------------------------------------------------------------------- For more sophisticated examples (like multiple unicast endpoints to one anycast tunnel endpoint) please consult the man page of anytun-config(8). diff --git a/src/options.cpp b/src/options.cpp index b3e37db..e58278a 100644 --- a/src/options.cpp +++ b/src/options.cpp @@ -187,7 +187,7 @@ Options::Options() : key_(u_int32_t(0)), salt_(u_int32_t(0)) auth_algo_ = "null"; kd_prf_ = "null"; #endif - ld_kdr_ = 0; + role_ = ROLE_LEFT; anytun02_compat_ = false; } @@ -327,7 +327,7 @@ bool Options::parse(int argc, char* argv[]) progname_ = argv[0]; argc--; bool ipv4_only = false, ipv6_only = false; - int32_t ld_kdr_tmp = ld_kdr_; + std::string role = ""; for(int i=1; argc > 0; ++i) { std::string str(argv[i]); @@ -397,7 +397,7 @@ bool Options::parse(int argc, char* argv[]) #ifndef NO_CRYPT PARSE_SCALAR_PARAM("-k","--kd-prf", kd_prf_) -// PARSE_SIGNED_INT_PARAM("-l","--ld-kdr", ld_kdr_tmp) + PARSE_SCALAR_PARAM("-e","--role", role) PARSE_BOOL_PARAM("-O","--anytun02-compat", anytun02_compat_) #ifndef NO_PASSPHRASE PARSE_PHRASE_PARAM_SEC("-E","--passphrase", passphrase_) @@ -425,7 +425,14 @@ bool Options::parse(int argc, char* argv[]) if(ipv6_only) resolv_addr_type_ = IPV6_ONLY; - ld_kdr_ = static_cast<int8_t>(ld_kdr_tmp); + if(role != "") { + if(role == "alice" || role == "server" || role == "left") + role_ = ROLE_LEFT; + else if(role == "bob" || role == "client" || role == "right") + role_ = ROLE_RIGHT; + else + throw syntax_error("unknown role name: " + role, -1); + } return true; } @@ -520,7 +527,7 @@ void Options::printUsage() #ifndef NO_CRYPT std::cout << " [-k|--kd-prf] <kd-prf type> key derivation pseudo random function" << std::endl; -// std::cout << " [-l|--ld-kdr] <ld-kdr> log2 of key derivation rate" << std::endl; + std::cout << " [-e|--role] <role> left (alice) or right (bob)" << std::endl; std::cout << " [-O|--anytun02-compat] enable compatiblity mode for anytun 0.2.x and prior" << std::endl; #ifndef NO_PASSPHRASE std::cout << " [-E|--passphrase] <pass phrase> a passprhase to generate master key and salt from" << std::endl; @@ -596,7 +603,12 @@ void Options::printOptions() std::cout << "cipher = '" << cipher_ << "'" << std::endl; std::cout << "auth_algo = '" << auth_algo_ << "'" << std::endl; std::cout << "kd_prf = '" << kd_prf_ << "'" << std::endl; - std::cout << "ld_kdr = " << static_cast<int32_t>(ld_kdr_) << std::endl; + std::cout << "role = "; + switch(role_) { + case ROLE_LEFT: std::cout << "left" << std::endl; break; + case ROLE_RIGHT: std::cout << "right" << std::endl; break; + default: std::cout << "??" << std::endl; break; + } std::cout << "anytun02_compat = " << anytun02_compat_ << std::endl; std::cout << "passphrase = '" << passphrase_ << "'" << std::endl; std::cout << "key = " << key_.getHexDumpOneLine() << std::endl; @@ -972,16 +984,16 @@ Options& Options::setKdPrf(std::string k) return *this; } -int8_t Options::getLdKdr() +role_t Options::getRole() { ReadersLock lock(mutex); - return ld_kdr_; + return role_; } -Options& Options::setLdKdr(int8_t l) +Options& Options::setRole(role_t r) { WritersLock lock(mutex); - ld_kdr_ = l; + role_ = r; return *this; } diff --git a/src/options.h b/src/options.h index 122f3f0..480d1c7 100644 --- a/src/options.h +++ b/src/options.h @@ -77,6 +77,8 @@ std::istream& operator>>(std::istream& stream, OptionNetwork& network); typedef std::list<std::string> StringList; +typedef enum { ROLE_LEFT, ROLE_RIGHT } role_t; + class Options { public: @@ -149,8 +151,8 @@ public: Options& setAuthAlgo(std::string a); std::string getKdPrf(); Options& setKdPrf(std::string k); - int8_t getLdKdr(); - Options& setLdKdr(int8_t l); + role_t getRole(); + Options& setRole(role_t r); bool getAnytun02Compat(); Options& setAnytun02Compat(bool a); std::string getPassphrase(); @@ -211,7 +213,7 @@ private: std::string cipher_; std::string auth_algo_; std::string kd_prf_; - int8_t ld_kdr_; + role_t role_; bool anytun02_compat_; std::string passphrase_; Buffer key_; |