diff options
author | Kozlov Dmitry <xeb@mail.ru> | 2013-01-24 23:58:56 +0400 |
---|---|---|
committer | Kozlov Dmitry <xeb@mail.ru> | 2013-01-24 23:58:56 +0400 |
commit | cf3de06a3346854d770ba147f081e3b22e93c1bc (patch) | |
tree | 0c1a138d292c140c2547361615bf556ff2b98f9f /accel-pppd/extra | |
parent | 35b55103979145284d63bc1db4ebd6e9d6666b34 (diff) | |
download | accel-ppp-cf3de06a3346854d770ba147f081e3b22e93c1bc.tar.gz accel-ppp-cf3de06a3346854d770ba147f081e3b22e93c1bc.zip |
backport 1.7
* l2tp: Fix allocation checking when adding octets AVP
* cli, tcp: Fix non-NULL terminated string reception
* Fix va_end() missing calls
* chap-secrets: implemented encryption
* auth_pap: make messages like other auth modules
* cli: check xmit_buf is not null at enter to write function
* pppoe: implemented regular expression support
* chap-secrets: implemented encryption
* ippool: fixed initialization order
* optional shaper compiling
* ppp: dns/wins code cleanup
Diffstat (limited to 'accel-pppd/extra')
-rw-r--r-- | accel-pppd/extra/chap-secrets.c | 475 | ||||
-rw-r--r-- | accel-pppd/extra/ippool.c | 134 |
2 files changed, 490 insertions, 119 deletions
diff --git a/accel-pppd/extra/chap-secrets.c b/accel-pppd/extra/chap-secrets.c index c0e620b1..47d59830 100644 --- a/accel-pppd/extra/chap-secrets.c +++ b/accel-pppd/extra/chap-secrets.c @@ -2,12 +2,19 @@ #include <stdlib.h> #include <errno.h> #include <string.h> +#include <byteswap.h> #include <netinet/in.h> #include <arpa/inet.h> +#ifdef CRYPTO_OPENSSL +#include "openssl/evp.h" +#include "crypto.h" +#endif + #include "pwdb.h" #include "ipdb.h" #include "ppp.h" +#include "ppp_auth.h" #include "events.h" #include "triton.h" #include "log.h" @@ -16,11 +23,18 @@ static char *def_chap_secrets = "/etc/ppp/chap-secrets"; static char *conf_chap_secrets; +static int conf_encrypted; static in_addr_t conf_gw_ip_address = 0; static void *pd_key; static struct ipdb_t ipdb; +struct hash_chain +{ + struct list_head entry; + const EVP_MD *md; +}; + struct cs_pd_t { struct ap_private pd; @@ -29,6 +43,8 @@ struct cs_pd_t char *rate; }; +static LIST_HEAD(hash_chain); + static char *skip_word(char *ptr) { char quote = 0; @@ -53,15 +69,19 @@ static char *skip_word(char *ptr) } else if (*ptr == ' ' || *ptr == '\t' || *ptr == '\n') break; } + return ptr; } + static char *skip_space(char *ptr) { for(; *ptr; ptr++) if (*ptr != ' ' && *ptr != '\t') break; + return ptr; } + static int split(char *buf, char **ptr) { int i; @@ -98,12 +118,37 @@ static struct cs_pd_t *create_pd(struct ap_session *ses, const char *username) FILE *f; char *buf; char *ptr[5]; - int n; + int n, i; struct cs_pd_t *pd; +#ifdef CRYPTO_OPENSSL + char username_hash[EVP_MAX_MD_SIZE * 2 + 1]; + uint8_t hash[EVP_MAX_MD_SIZE]; + struct hash_chain *hc; + EVP_MD_CTX md_ctx; + char c; +#endif if (!conf_chap_secrets) return NULL; +#ifdef CRYPTO_OPENSSL + if (conf_encrypted && !list_empty(&hash_chain)) { + unsigned int size = 0; + list_for_each_entry(hc, &hash_chain, entry) { + EVP_MD_CTX_init(&md_ctx); + EVP_DigestInit_ex(&md_ctx, hc->md, NULL); + EVP_DigestUpdate(&md_ctx, size == 0 ? (void *)username : (void *)hash, size == 0 ? strlen(username) : size); + EVP_DigestFinal_ex(&md_ctx, hash, &size); + EVP_MD_CTX_cleanup(&md_ctx); + } + + for (n = 0; n < size; n++) + sprintf(username_hash + n*2, "%02x", hash[n]); + + username = username_hash; + } +#endif + f = fopen(conf_chap_secrets, "r"); if (!f) { log_error("chap-secrets: open '%s': %s\n", conf_chap_secrets, strerror(errno)); @@ -138,6 +183,11 @@ out: return NULL; found: +#ifdef CRYPTO_OPENSSL + if (conf_encrypted && strlen(ptr[1]) != 32) + goto out; +#endif + pd = _malloc(sizeof(*pd)); if (!pd) { log_emerg("chap-secrets: out of memory\n"); @@ -146,11 +196,30 @@ found: memset(pd, 0, sizeof(*pd)); pd->pd.key = &pd_key; - pd->passwd = _strdup(ptr[1]); - if (!pd->passwd) { - log_emerg("chap-secrets: out of memory\n"); - _free(pd); - goto out; +#ifdef CRYPTO_OPENSSL + if (conf_encrypted) { + pd->passwd = _malloc(16); + if (!pd->passwd) { + log_emerg("chap-secrets: out of memory\n"); + _free(pd); + goto out; + } + + for (i = 0; i < 16; i++) { + c = ptr[1][i*2 + 2]; + ptr[1][i*2 + 2] = 0; + pd->passwd[i] = strtol(ptr[1] + i*2, NULL, 16); + ptr[1][i*2 + 2] = c; + } + } else +#endif + { + pd->passwd = _strdup(ptr[1]); + if (!pd->passwd) { + log_emerg("chap-secrets: out of memory\n"); + _free(pd); + goto out; + } } pd->ip.addr = conf_gw_ip_address; @@ -234,6 +303,11 @@ static char* get_passwd(struct pwdb_t *pwdb, struct ap_session *ses, const char { struct cs_pd_t *pd = find_pd(ses); +#ifdef CRYPTO_OPENSSL + if (conf_encrypted) + return NULL; +#endif + if (!pd) pd = create_pd(ses, username); @@ -243,14 +317,390 @@ static char* get_passwd(struct pwdb_t *pwdb, struct ap_session *ses, const char return _strdup(pd->passwd); } +#ifdef CRYPTO_OPENSSL +static void des_encrypt(const uint8_t *input, const uint8_t *key, uint8_t *output) +{ + int i, j, parity; + union + { + uint64_t u64; + uint8_t buf[8]; + } p_key; + DES_cblock cb; + DES_cblock res; + DES_key_schedule ks; + + memcpy(p_key.buf, key, 7); + p_key.u64 = bswap_64(p_key.u64); + + for (i = 0; i < 8; i++) { + cb[i] = (((p_key.u64 << (7 * i)) >> 56) & 0xfe); + for( j = 0, parity = 0; j < 7; j++) + if ((cb[i] >> (j + 1)) & 1) + parity++; + cb[i] |= (~parity) & 1; + } + + DES_set_key_checked(&cb, &ks); + memcpy(cb, input, 8); + DES_ecb_encrypt(&cb, &res, &ks, DES_ENCRYPT); + memcpy(output, res, 8); +} + +static int auth_pap(struct cs_pd_t *pd, const char *username, va_list args) +{ + const char *passwd = va_arg(args, const char *); + MD4_CTX md4_ctx; + unsigned char z_hash[21]; + char *u_passwd; + int i, len = strlen(passwd); + + u_passwd = _malloc(len * 2); + for (i = 0; i< len; i++) { + u_passwd[i * 2] = passwd[i]; + u_passwd[i * 2 + 1] = 0; + } + + memset(z_hash, 0, sizeof(z_hash)); + MD4_Init(&md4_ctx); + MD4_Update(&md4_ctx, u_passwd, len * 2); + MD4_Final(z_hash, &md4_ctx); + + _free(u_passwd); + + /*des_encrypt(ad->val, z_hash, nt_hash); + des_encrypt(ad->val, z_hash + 7, nt_hash + 8); + des_encrypt(ad->val, z_hash + 14, nt_hash + 16);*/ + + if (memcmp(z_hash, pd->passwd, 16)) + return PWDB_DENIED; + + return PWDB_SUCCESS; +} + +static int auth_chap_md5(struct cs_pd_t *pd, const char *username, va_list args) +{ + /*int id = va_arg(args, int); + uint8_t *challenge = va_arg(args, uint8_t *); + int challenge_len = va_arg(args, int); + uint8_t *response = va_arg(args, uint8_t *);*/ + + return PWDB_NO_IMPL; +} + +static void derive_mppe_keys_mschap_v1(struct ap_session *ses, const uint8_t *z_hash, const uint8_t *challenge, int challenge_len) +{ + MD4_CTX md4_ctx; + SHA_CTX sha_ctx; + uint8_t digest[20]; + struct ppp_t *ppp = container_of(ses, typeof(*ppp), ses); + + struct ev_mppe_keys_t ev_mppe = { + .ppp = ppp, + .policy = -1, + .recv_key = digest, + .send_key = digest, + }; + + //NtPasswordHashHash + MD4_Init(&md4_ctx); + MD4_Update(&md4_ctx, z_hash, 16); + MD4_Final(digest, &md4_ctx); + + //Get_Start_Key + SHA1_Init(&sha_ctx); + SHA1_Update(&sha_ctx, digest, 16); + SHA1_Update(&sha_ctx, digest, 16); + SHA1_Update(&sha_ctx, challenge, challenge_len); + SHA1_Final(digest, &sha_ctx); + + triton_event_fire(EV_MPPE_KEYS, &ev_mppe); +} + +int auth_mschap_v1(struct ap_session *ses, struct cs_pd_t *pd, const char *username, va_list args) +{ + int id __unused = va_arg(args, int); + const uint8_t *challenge = va_arg(args, const uint8_t *); + int challenge_len = va_arg(args, int); + const uint8_t *lm_response __unused = va_arg(args, const uint8_t *); + const uint8_t *nt_response = va_arg(args, const uint8_t *); + int flags __unused = va_arg(args, int); + uint8_t z_hash[21]; + uint8_t nt_hash[24]; + + memcpy(z_hash, pd->passwd, 16); + memset(z_hash + 16, 0, sizeof(z_hash) - 16); + + des_encrypt(challenge, z_hash, nt_hash); + des_encrypt(challenge, z_hash + 7, nt_hash + 8); + des_encrypt(challenge, z_hash + 14, nt_hash + 16); + + if (memcmp(nt_hash, nt_response, 24)) + return PWDB_DENIED; + + if (ses->ctrl->ppp) + derive_mppe_keys_mschap_v1(ses, z_hash, challenge, challenge_len); + + return PWDB_SUCCESS; +} + +static void generate_mschap_response(const uint8_t *nt_response, const uint8_t *c_hash, const uint8_t *z_hash, char *authenticator) +{ + MD4_CTX md4_ctx; + SHA_CTX sha_ctx; + uint8_t pw_hash[MD4_DIGEST_LENGTH]; + uint8_t response[SHA_DIGEST_LENGTH]; + int i; + + uint8_t magic1[39] = + {0x4D, 0x61, 0x67, 0x69, 0x63, 0x20, 0x73, 0x65, 0x72, 0x76, + 0x65, 0x72, 0x20, 0x74, 0x6F, 0x20, 0x63, 0x6C, 0x69, 0x65, + 0x6E, 0x74, 0x20, 0x73, 0x69, 0x67, 0x6E, 0x69, 0x6E, 0x67, + 0x20, 0x63, 0x6F, 0x6E, 0x73, 0x74, 0x61, 0x6E, 0x74}; + uint8_t magic2[41] = + {0x50, 0x61, 0x64, 0x20, 0x74, 0x6F, 0x20, 0x6D, 0x61, 0x6B, + 0x65, 0x20, 0x69, 0x74, 0x20, 0x64, 0x6F, 0x20, 0x6D, 0x6F, + 0x72, 0x65, 0x20, 0x74, 0x68, 0x61, 0x6E, 0x20, 0x6F, 0x6E, + 0x65, 0x20, 0x69, 0x74, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6F, + 0x6E}; + + + MD4_Init(&md4_ctx); + MD4_Update(&md4_ctx, z_hash, 16); + MD4_Final(pw_hash, &md4_ctx); + + SHA1_Init(&sha_ctx); + SHA1_Update(&sha_ctx, pw_hash, 16); + SHA1_Update(&sha_ctx, nt_response, 24); + SHA1_Update(&sha_ctx, magic1, 39); + SHA1_Final(response, &sha_ctx); + + SHA1_Init(&sha_ctx); + SHA1_Update(&sha_ctx, response, 20); + SHA1_Update(&sha_ctx, c_hash, 8); + SHA1_Update(&sha_ctx, magic2, 41); + SHA1_Final(response, &sha_ctx); + + for (i = 0; i < 20; i++) + sprintf(authenticator + i*2, "%02X", response[i]); +} + +static void derive_mppe_keys_mschap_v2(struct ap_session *ses, const uint8_t *z_hash, const uint8_t *nt_hash) +{ + struct ppp_t *ppp = container_of(ses, typeof(*ppp), ses); + MD4_CTX md4_ctx; + SHA_CTX sha_ctx; + uint8_t digest[20]; + uint8_t send_key[20]; + uint8_t recv_key[20]; + + uint8_t pad1[40] = + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; + + uint8_t pad2[40] = + {0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, + 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, + 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, + 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2}; + + uint8_t magic1[27] = + {0x54, 0x68, 0x69, 0x73, 0x20, 0x69, 0x73, 0x20, 0x74, + 0x68, 0x65, 0x20, 0x4d, 0x50, 0x50, 0x45, 0x20, 0x4d, + 0x61, 0x73, 0x74, 0x65, 0x72, 0x20, 0x4b, 0x65, 0x79}; + + uint8_t magic2[84] = + {0x4f, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x20, 0x63, 0x6c, 0x69, + 0x65, 0x6e, 0x74, 0x20, 0x73, 0x69, 0x64, 0x65, 0x2c, 0x20, + 0x74, 0x68, 0x69, 0x73, 0x20, 0x69, 0x73, 0x20, 0x74, 0x68, + 0x65, 0x20, 0x73, 0x65, 0x6e, 0x64, 0x20, 0x6b, 0x65, 0x79, + 0x3b, 0x20, 0x6f, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x20, 0x73, + 0x65, 0x72, 0x76, 0x65, 0x72, 0x20, 0x73, 0x69, 0x64, 0x65, + 0x2c, 0x20, 0x69, 0x74, 0x20, 0x69, 0x73, 0x20, 0x74, 0x68, + 0x65, 0x20, 0x72, 0x65, 0x63, 0x65, 0x69, 0x76, 0x65, 0x20, + 0x6b, 0x65, 0x79, 0x2e}; + + uint8_t magic3[84] = + {0x4f, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x20, 0x63, 0x6c, 0x69, + 0x65, 0x6e, 0x74, 0x20, 0x73, 0x69, 0x64, 0x65, 0x2c, 0x20, + 0x74, 0x68, 0x69, 0x73, 0x20, 0x69, 0x73, 0x20, 0x74, 0x68, + 0x65, 0x20, 0x72, 0x65, 0x63, 0x65, 0x69, 0x76, 0x65, 0x20, + 0x6b, 0x65, 0x79, 0x3b, 0x20, 0x6f, 0x6e, 0x20, 0x74, 0x68, + 0x65, 0x20, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x20, 0x73, + 0x69, 0x64, 0x65, 0x2c, 0x20, 0x69, 0x74, 0x20, 0x69, 0x73, + 0x20, 0x74, 0x68, 0x65, 0x20, 0x73, 0x65, 0x6e, 0x64, 0x20, + 0x6b, 0x65, 0x79, 0x2e}; + + struct ev_mppe_keys_t ev_mppe = { + .ppp = ppp, + .policy = -1, + .recv_key = recv_key, + .send_key = send_key, + }; + + //NtPasswordHashHash + MD4_Init(&md4_ctx); + MD4_Update(&md4_ctx, z_hash, 16); + MD4_Final(digest, &md4_ctx); + + //GetMasterKey + SHA1_Init(&sha_ctx); + SHA1_Update(&sha_ctx, digest, 16); + SHA1_Update(&sha_ctx, nt_hash, 24); + SHA1_Update(&sha_ctx, magic1, sizeof(magic1)); + SHA1_Final(digest, &sha_ctx); + + //send key + SHA1_Init(&sha_ctx); + SHA1_Update(&sha_ctx, digest, 16); + SHA1_Update(&sha_ctx, pad1, sizeof(pad1)); + SHA1_Update(&sha_ctx, magic3, sizeof(magic2)); + SHA1_Update(&sha_ctx, pad2, sizeof(pad2)); + SHA1_Final(send_key, &sha_ctx); + + //recv key + SHA1_Init(&sha_ctx); + SHA1_Update(&sha_ctx, digest, 16); + SHA1_Update(&sha_ctx, pad1, sizeof(pad1)); + SHA1_Update(&sha_ctx, magic2, sizeof(magic3)); + SHA1_Update(&sha_ctx, pad2, sizeof(pad2)); + SHA1_Final(recv_key, &sha_ctx); + + triton_event_fire(EV_MPPE_KEYS, &ev_mppe); +} + +int auth_mschap_v2(struct ap_session *ses, struct cs_pd_t *pd, const char *username, va_list args) +{ + int id __unused = va_arg(args, int); + const uint8_t *challenge = va_arg(args, const uint8_t *); + const uint8_t *peer_challenge = va_arg(args, const uint8_t *); + const uint8_t *reserved __unused = va_arg(args, const uint8_t *); + const uint8_t *response = va_arg(args, const uint8_t *); + int flags __unused = va_arg(args, int); + char *authenticator = va_arg(args, char *); + uint8_t z_hash[21]; + uint8_t nt_hash[24]; + uint8_t c_hash[SHA_DIGEST_LENGTH]; + SHA_CTX sha_ctx; + + SHA1_Init(&sha_ctx); + SHA1_Update(&sha_ctx, peer_challenge, 16); + SHA1_Update(&sha_ctx, challenge, 16); + SHA1_Update(&sha_ctx, username, strlen(username)); + SHA1_Final(c_hash, &sha_ctx); + + memcpy(z_hash, pd->passwd, 16); + memset(z_hash + 16, 0, sizeof(z_hash) - 16); + + des_encrypt(c_hash, z_hash, nt_hash); + des_encrypt(c_hash, z_hash + 7, nt_hash + 8); + des_encrypt(c_hash, z_hash + 14, nt_hash + 16); + + if (memcmp(nt_hash, response, 24)) + return PWDB_DENIED; + + if (ses->ctrl->ppp) + derive_mppe_keys_mschap_v2(ses, z_hash, response); + + generate_mschap_response(response, c_hash, z_hash, authenticator); + + return PWDB_SUCCESS; +} + +static int check_passwd(struct pwdb_t *pwdb, struct ap_session *ses, const char *username, int type, va_list _args) +{ + va_list args; + int r = PWDB_NO_IMPL; + struct cs_pd_t *pd; + + if (!conf_encrypted) + return PWDB_NO_IMPL; + + pd = find_pd(ses); + + if (!pd) + pd = create_pd(ses, username); + + if (!pd) + return PWDB_NO_IMPL; + + va_copy(args, _args); + + switch (type) { + case PPP_PAP: + r = auth_pap(pd, username, args); + break; + case PPP_CHAP: + type = va_arg(args, int); + switch (type) { + case CHAP_MD5: + r = auth_chap_md5(pd, username, args); + break; + case MSCHAP_V1: + r = auth_mschap_v1(ses, pd, username, args); + break; + case MSCHAP_V2: + r = auth_mschap_v2(ses, pd, username, args); + break; + } + break; + } + + va_end(args); + + return r; +} +#endif + static struct ipdb_t ipdb = { .get_ipv4 = get_ip, }; static struct pwdb_t pwdb = { .get_passwd = get_passwd, +#ifdef CRYPTO_OPENSSL + .check = check_passwd, +#endif }; +#ifdef CRYPTO_OPENSSL +static void clear_hash_chain(void) +{ + struct hash_chain *hc; + + while (!list_empty(&hash_chain)) { + hc = list_entry(hash_chain.next, typeof(*hc), entry); + list_del(&hc->entry); + _free(hc); + } +} + +static void parse_hash_chain(const char *opt) +{ + char *str = _strdup(opt); + char *ptr1 = str, *ptr2; + struct hash_chain *hc; + int f = 0; + + while (!f) { + for (ptr2 = ptr1 + 1; *ptr2 && *ptr2 != ','; ptr2++); + f = *ptr2 == 0; + *ptr2 = 0; + hc = _malloc(sizeof(*hc)); + hc->md = EVP_get_digestbyname(ptr1); + if (!hc->md) { + log_error("chap-secrets: digest '%s' is unavailable\n", ptr1); + _free(hc); + return; + } + list_add_tail(&hc->entry, &hash_chain); + ptr1 = ptr2 + 1; + } +} +#endif + static void load_config(void) { const char *opt; @@ -266,6 +716,19 @@ static void load_config(void) opt = conf_get_opt("chap-secrets", "gw-ip-address"); if (opt) conf_gw_ip_address = inet_addr(opt); + + opt = conf_get_opt("chap-secrets", "encrypted"); + if (opt) + conf_encrypted = atoi(opt); + else + conf_encrypted = 0; + +#ifdef CRYPTO_OPENSSL + clear_hash_chain(); + opt = conf_get_opt("chap-secrets", "username-hash"); + if (opt) + parse_hash_chain(opt); +#endif } static void init(void) diff --git a/accel-pppd/extra/ippool.c b/accel-pppd/extra/ippool.c index 62c56df1..88688073 100644 --- a/accel-pppd/extra/ippool.c +++ b/accel-pppd/extra/ippool.c @@ -6,14 +6,12 @@ #include <arpa/inet.h> #include "events.h" -#include "log.h" +#include "ipdb.h" #include "list.h" #include "spinlock.h" #include "backup.h" #include "ap_session_backup.h" -#include "ipdb.h" - #ifdef RADIUS #include "radius.h" #endif @@ -29,7 +27,6 @@ struct ippool_t struct list_head items; uint32_t startip; uint32_t endip; - void (*generate)(struct ippool_t *); spinlock_t lock; }; @@ -63,7 +60,6 @@ struct ippool_t *create_pool(const char *name) memset(p, 0, sizeof(*p)); if (name) p->name = strdup(name); - INIT_LIST_HEAD(&p->gw_list); INIT_LIST_HEAD(&p->tunnel_list); INIT_LIST_HEAD(&p->items); @@ -151,7 +147,7 @@ static int parse2(const char *str, uint32_t *begin, uint32_t *end) return 0; } -static void add_range(struct ippool_t *p, struct list_head *list, const char *name, void (*generate)(struct ippool_t *)) +static void add_range(struct ippool_t *p, struct list_head *list, const char *name) { uint32_t i,startip, endip; struct ipaddr_t *ip; @@ -172,10 +168,9 @@ static void add_range(struct ippool_t *p, struct list_head *list, const char *na p->startip = startip; p->endip = endip; - p->generate = generate; } -static void generate_pool_p2p(struct ippool_t *p) +static void generate_pool(struct ippool_t *p) { struct ippool_item_t *it; struct ipaddr_t *addr = NULL; @@ -217,53 +212,6 @@ static void generate_pool_p2p(struct ippool_t *p) } } -static void generate_pool_net30(struct ippool_t *p) -{ - struct ippool_item_t *it; - struct ipaddr_t *addr[4]; - int i; - - while (1) { - memset(addr, 0, sizeof(addr)); - - for (i = 0; i < 4; i++) { - if (list_empty(&p->tunnel_list)) - break; - - addr[i] = list_entry(p->tunnel_list.next, typeof(*addr[i]), entry); - list_del(&addr[i]->entry); - } - - if (!addr[2]) - break; - - - it = malloc(sizeof(*it)); - if (!it) { - log_emerg("ippool: out of memory\n"); - break; - } - - it->pool = p; - it->it.owner = &ipdb; - it->it.addr = addr[1]->addr; - it->it.peer_addr = addr[2]->addr; - - list_add_tail(&it->entry, &p->items); - - for (i = 0; i < 4; i++) { - if (addr[i]) - free(addr[i]); - } - } - - for (i = 0; i < 4; i++) { - if (addr[i]) - free(addr[i]); - } -} - - static struct ipv4db_item_t *get_ip(struct ap_session *ses) { struct ippool_item_t *it; @@ -453,38 +401,17 @@ static int parse_vendor_opt(const char *opt) } #endif -static void parse_options(const char *opt, char **pool_name, char **allocator) +static void ippool_init1(void) { - char *ptr1, *ptr2; - int len; - - ptr1 = strstr(opt, "name="); - if (ptr1) { - for (ptr2 = ptr1 + 5; *ptr2 && *ptr2 != ','; ptr2++); - len = ptr2 - (ptr1 + 5); - *pool_name = _malloc(len + 1); - memcpy(*pool_name, ptr1 + 5, len); - (*pool_name)[len] = 0; - } - - ptr1 = strstr(opt, "allocator="); - if (ptr1) { - for (ptr2 = ptr1 + 10; *ptr2 && *ptr2 != ','; ptr2++); - len = ptr2 - (ptr1 + 10); - *allocator = _malloc(len + 1); - memcpy(*allocator, ptr1 + 10, len); - (*allocator)[len] = 0; - } + ipdb_register(&ipdb); } -static void ippool_init(void) +static void ippool_init2(void) { struct conf_sect_t *s = conf_get_section("ip-pool"); struct conf_option_t *opt; struct ippool_t *p; - char *pool_name = NULL; - char *allocator = NULL; - void (*generate)(struct ippool_t *pool); + char *pool_name; if (!s) return; @@ -508,46 +435,26 @@ static void ippool_init(void) if (!strcmp(opt->name, "gw-ip-address")) parse_gw_ip_address(opt->val); else { - pool_name = NULL; - allocator = NULL; - - parse_options(opt->raw, &pool_name, &allocator); - - if (allocator) { - if (strcmp(allocator, "p2p") == 0) - generate = generate_pool_p2p; - else if (strcmp(allocator, "net30") == 0) - generate = generate_pool_net30; - else { - log_error("ipool: '%s': unknown allocator\n", opt->raw); - } - } else - generate = generate_pool_p2p; + if (opt->val) + pool_name = strchr(opt->val, ','); + else + pool_name = strchr(opt->name, ','); - p = pool_name ? find_pool(pool_name, 1) : def_pool; + p = pool_name ? find_pool(pool_name + 1, 1) : def_pool; if (!strcmp(opt->name, "gw")) - add_range(p, &p->gw_list, opt->val, generate); + add_range(p, &p->gw_list, opt->val); else if (!strcmp(opt->name, "tunnel")) - add_range(p, &p->tunnel_list, opt->val, generate); - else if (!opt->val || strchr(opt->name, ',')) - add_range(p, &p->tunnel_list, opt->name, generate); - - if (pool_name) - _free(pool_name); - - if (allocator) - _free(allocator); + add_range(p, &p->tunnel_list, opt->val); + else if (!opt->val) + add_range(p, &p->tunnel_list, opt->name); } } - - if (def_pool->generate) - def_pool->generate(def_pool); - list_for_each_entry(p, &pool_list, entry) - p->generate(p); + generate_pool(def_pool); - ipdb_register(&ipdb); + list_for_each_entry(p, &pool_list, entry) + generate_pool(p); #ifdef USE_BACKUP backup_register_module(&backup_mod); @@ -559,5 +466,6 @@ static void ippool_init(void) #endif } -DEFINE_INIT(51, ippool_init); +DEFINE_INIT(51, ippool_init1); +DEFINE_INIT2(52, ippool_init2); |