]> git.saurik.com Git - apple/ipsec.git/blob - ipsec-tools/racoon/throttle.c
ipsec-34.tar.gz
[apple/ipsec.git] / ipsec-tools / racoon / throttle.c
1 /* $Id: throttle.c,v 1.2 2004/11/30 07:40:13 manubsd Exp $ */
2
3 /*
4 * Copyright (C) 2004 Emmanuel Dreyfus
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the project nor the names of its contributors
16 * may be used to endorse or promote products derived from this software
17 * without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32 #include "config.h"
33
34 #include <stdio.h>
35 #include <stdlib.h>
36 #include <string.h>
37 #if TIME_WITH_SYS_TIME
38 # include <sys/time.h>
39 # include <time.h>
40 #else
41 # if HAVE_SYS_TIME_H
42 # include <sys/time.h>
43 # else
44 # include <time.h>
45 # endif
46 #endif
47 #include <sys/param.h>
48 #include <sys/queue.h>
49 #include <sys/socket.h>
50
51 #include <netinet/in.h>
52
53 #include "vmbuf.h"
54 #include "misc.h"
55 #include "plog.h"
56 #include "throttle.h"
57 #include "sockmisc.h"
58 #include "libpfkey.h"
59 #include "isakmp_var.h"
60 #include "isakmp.h"
61 #include "isakmp_xauth.h"
62 #include "isakmp_cfg.h"
63 #include "gcmalloc.h"
64
65 struct throttle_list throttle_list = TAILQ_HEAD_INITIALIZER(throttle_list);
66
67
68 struct throttle_entry *
69 throttle_add(addr)
70 struct sockaddr *addr;
71 {
72 struct throttle_entry *te;
73 size_t len;
74
75 len = sizeof(*te)
76 - sizeof(struct sockaddr_storage)
77 + sysdep_sa_len(addr);
78
79 if ((te = racoon_malloc(len)) == NULL)
80 return NULL;
81
82 te->penalty = time(NULL) + isakmp_cfg_config.auth_throttle;
83 memcpy(&te->host, addr, sysdep_sa_len(addr));
84 TAILQ_INSERT_HEAD(&throttle_list, te, next);
85
86 return te;
87 }
88
89 int
90 throttle_host(addr, authfail)
91 struct sockaddr *addr;
92 int authfail;
93 {
94 struct throttle_entry *te;
95 int found = 0;
96 time_t now;
97
98 if (isakmp_cfg_config.auth_throttle == 0)
99 return 0;
100
101 now = time(NULL);
102
103 TAILQ_FOREACH_REVERSE(te, &throttle_list, throttle_list, next) {
104 /*
105 * Remove outdated entries
106 */
107 if (te->penalty < now) {
108 TAILQ_REMOVE(&throttle_list, te, next);
109 racoon_free(te);
110 continue;
111 }
112
113 if (cmpsaddrwop(addr, (struct sockaddr *)&te->host) == 0) {
114 found = 1;
115 break;
116 }
117 }
118
119 /*
120 * No match, if auth failed, allocate a new throttle entry
121 * give no penalty even on error: this is the first time
122 * and we are indulgent.
123 */
124 if (!found) {
125 if (authfail) {
126 if ((te = throttle_add(addr)) == NULL) {
127 plog(LLV_ERROR, LOCATION, NULL,
128 "Throttle insertion failed\n");
129 return (time(NULL)
130 + isakmp_cfg_config.auth_throttle);
131 }
132 }
133 return 0;
134 } else {
135 /*
136 * We had a match and auth failed, increase penalty.
137 */
138 if (authfail) {
139 time_t remaining;
140 time_t new;
141
142 remaining = te->penalty - now;
143 new = remaining + isakmp_cfg_config.auth_throttle;
144
145 if (new > THROTTLE_PENALTY_MAX)
146 new = THROTTLE_PENALTY_MAX;
147
148 te->penalty = now + new;
149 }
150 }
151
152 return te->penalty;
153 }
154