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