]>
Commit | Line | Data |
---|---|---|
0862875d EK |
1 | /* |
2 | * Copyright (C) 2020 Ed Kellett | |
3 | * | |
4 | * This program is free software; you can redistribute it and/or modify | |
5 | * it under the terms of the GNU General Public License as published by | |
6 | * the Free Software Foundation; either version 2 of the License, or | |
7 | * (at your option) any later version. | |
8 | * | |
9 | * This program is distributed in the hope that it will be useful, | |
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
12 | * GNU General Public License for more details. | |
13 | * | |
14 | * You should have received a copy of the GNU General Public License | |
15 | * along with this program; if not, write to the Free Software | |
16 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 | |
17 | * USA | |
18 | */ | |
19 | ||
20 | #include <stdinc.h> | |
21 | #include <modules.h> | |
22 | #include <capability.h> | |
23 | #include <s_serv.h> | |
24 | #include <s_newconf.h> | |
25 | #include <client.h> | |
26 | #include <msgbuf.h> | |
27 | ||
28 | static char cap_realhost_desc[] = "Provides the solanum.chat/realhost oper-only capability"; | |
29 | ||
3b473195 | 30 | static bool cap_oper_realhost_visible(struct Client *); |
0862875d EK |
31 | static void cap_realhost_outbound_msgbuf(void *); |
32 | static void cap_realhost_umode_changed(void *); | |
3b473195 | 33 | static void cap_realhost_cap_change(void *); |
0862875d EK |
34 | |
35 | static unsigned CLICAP_REALHOST; | |
3b473195 | 36 | static unsigned CLICAP_OPER_REALHOST; |
0862875d | 37 | |
3b473195 EK |
38 | static struct ClientCapability capdata_oper_realhost = { |
39 | .visible = cap_oper_realhost_visible, | |
0862875d EK |
40 | }; |
41 | ||
42 | mapi_cap_list_av2 cap_realhost_caps[] = { | |
3b473195 EK |
43 | { MAPI_CAP_CLIENT, "solanum.chat/realhost", NULL, &CLICAP_REALHOST }, |
44 | { MAPI_CAP_CLIENT, "?oper_realhost", &capdata_oper_realhost, &CLICAP_OPER_REALHOST }, | |
0862875d EK |
45 | { 0, NULL, NULL, NULL }, |
46 | }; | |
47 | ||
48 | mapi_hfn_list_av1 cap_realhost_hfnlist[] = { | |
49 | { "outbound_msgbuf", cap_realhost_outbound_msgbuf, HOOK_NORMAL }, | |
50 | { "umode_changed", cap_realhost_umode_changed, HOOK_MONITOR }, | |
3b473195 | 51 | { "cap_change", cap_realhost_cap_change, HOOK_MONITOR }, |
0862875d EK |
52 | { NULL, NULL, 0 }, |
53 | }; | |
54 | ||
55 | static bool | |
3b473195 | 56 | cap_oper_realhost_visible(struct Client *client) |
0862875d | 57 | { |
3b473195 | 58 | return false; |
0862875d EK |
59 | } |
60 | ||
61 | static void | |
62 | cap_realhost_outbound_msgbuf(void *data_) | |
63 | { | |
64 | hook_data *data = data_; | |
65 | struct MsgBuf *msgbuf = data->arg1; | |
66 | ||
3b473195 | 67 | if (data->client == NULL || !IsPerson(data->client)) |
0862875d EK |
68 | return; |
69 | ||
70 | if (!IsIPSpoof(data->client) && !EmptyString(data->client->sockhost) && strcmp(data->client->sockhost, "0")) | |
3b473195 | 71 | { |
8a776ce6 EK |
72 | msgbuf_append_tag(msgbuf, "solanum.chat/ip", data->client->sockhost, |
73 | IsDynSpoof(data->client) ? CLICAP_OPER_REALHOST : CLICAP_REALHOST); | |
3b473195 | 74 | } |
0862875d EK |
75 | |
76 | if (!EmptyString(data->client->orighost)) | |
272e4a7d | 77 | msgbuf_append_tag(msgbuf, "solanum.chat/realhost", data->client->orighost, CLICAP_OPER_REALHOST); |
3b473195 EK |
78 | } |
79 | ||
80 | static inline void | |
81 | update_clicap_oper_realhost(struct Client *client) | |
82 | { | |
83 | client->localClient->caps &= ~CLICAP_OPER_REALHOST; | |
84 | if (client->localClient->caps & CLICAP_REALHOST && HasPrivilege(client, "auspex:hostname")) | |
85 | { | |
86 | client->localClient->caps |= CLICAP_OPER_REALHOST; | |
87 | } | |
0862875d EK |
88 | } |
89 | ||
90 | static void | |
91 | cap_realhost_umode_changed(void *data_) | |
92 | { | |
93 | hook_data_umode_changed *data = data_; | |
94 | ||
95 | if (!MyClient(data->client)) | |
96 | return; | |
97 | ||
3b473195 EK |
98 | update_clicap_oper_realhost(data->client); |
99 | } | |
100 | ||
101 | static void | |
102 | cap_realhost_cap_change(void *data_) | |
103 | { | |
104 | hook_data_cap_change *data = data_; | |
105 | ||
106 | update_clicap_oper_realhost(data->client); | |
107 | } | |
108 | ||
109 | static int | |
110 | modinit(void) | |
111 | { | |
112 | rb_dlink_node *ptr; | |
113 | ||
114 | RB_DLINK_FOREACH(ptr, lclient_list.head) | |
115 | { | |
116 | struct Client *client = ptr->data; | |
117 | ||
118 | update_clicap_oper_realhost(client); | |
119 | } | |
120 | ||
121 | return 0; | |
0862875d EK |
122 | } |
123 | ||
3b473195 | 124 | DECLARE_MODULE_AV2(cap_realhost, modinit, NULL, NULL, NULL, cap_realhost_hfnlist, cap_realhost_caps, NULL, cap_realhost_desc); |