00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 #include "stdinc.h"
00026 #include "handlers.h"
00027 #include "client.h"
00028 #include "ircd.h"
00029 #include "irc_string.h"
00030 #include "numeric.h"
00031 #include "fdlist.h"
00032 #include "s_bsd.h"
00033 #include "s_conf.h"
00034 #include "s_log.h"
00035 #include "s_serv.h"
00036 #include "send.h"
00037 #include "msg.h"
00038 #include "parse.h"
00039 #include "hash.h"
00040 #include "modules.h"
00041
00042 static void mo_connect(struct Client *, struct Client *, int, char **);
00043 static void ms_connect(struct Client *, struct Client *, int, char **);
00044
00045 struct Message connect_msgtab = {
00046 "CONNECT", 0, 0, 2, 0, MFLG_SLOW, 0,
00047 {m_unregistered, m_not_oper, ms_connect, m_ignore, mo_connect, m_ignore}
00048 };
00049
00050 #ifndef STATIC_MODULES
00051 void
00052 _modinit(void)
00053 {
00054 mod_add_cmd(&connect_msgtab);
00055 }
00056
00057 void
00058 _moddeinit(void)
00059 {
00060 mod_del_cmd(&connect_msgtab);
00061 }
00062
00063 const char *_version = "$Revision: 33 $";
00064 #endif
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077 static void
00078 mo_connect(struct Client* client_p, struct Client* source_p,
00079 int parc, char* parv[])
00080 {
00081 int port;
00082 int tmpport;
00083 struct ConfItem *conf = NULL;
00084 struct AccessItem *aconf = NULL;
00085 struct Client *target_p;
00086
00087
00088 if (MyConnect(source_p) && !IsOperRemote(source_p) && parc > 3)
00089 {
00090 sendto_one(source_p, form_str(ERR_NOPRIVS),
00091 me.name, source_p->name, "connect");
00092 return;
00093 }
00094
00095 if (hunt_server(client_p, source_p,
00096 ":%s CONNECT %s %s :%s", 3, parc, parv) != HUNTED_ISME)
00097 return;
00098
00099 if (*parv[1] == '\0')
00100 {
00101 sendto_one(source_p, form_str(ERR_NEEDMOREPARAMS),
00102 me.name, source_p->name, "CONNECT");
00103 return;
00104 }
00105
00106 if ((target_p = find_server(parv[1])))
00107 {
00108 sendto_one(source_p,
00109 ":%s NOTICE %s :Connect: Server %s already exists from %s.",
00110 me.name, source_p->name, parv[1], target_p->from->name);
00111 return;
00112 }
00113
00114
00115
00116
00117 if ((conf = find_matching_name_conf(SERVER_TYPE,
00118 parv[1], NULL, NULL, 0)) != NULL)
00119 aconf = (struct AccessItem *)map_to_conf(conf);
00120 else if ((conf = find_matching_name_conf(SERVER_TYPE,
00121 NULL, NULL, parv[1], 0)) != NULL)
00122 aconf = (struct AccessItem *)map_to_conf(conf);
00123
00124 if (conf == NULL)
00125 {
00126 sendto_one(source_p,
00127 ":%s NOTICE %s :Connect: Host %s not listed in ircd.conf",
00128 me.name, source_p->name, parv[1]);
00129 return;
00130 }
00131
00132
00133
00134
00135
00136 tmpport = port = aconf->port;
00137
00138 if (parc > 2 && !EmptyString(parv[2]))
00139 {
00140 if ((port = atoi(parv[2])) <= 0)
00141 {
00142 sendto_one(source_p, ":%s NOTICE %s :Connect: Illegal port number",
00143 me.name, source_p->name);
00144 return;
00145 }
00146 }
00147 else if (port <= 0 && (port = PORTNUM) <= 0)
00148 {
00149 sendto_one(source_p, ":%s NOTICE %s :Connect: missing port number",
00150 me.name, source_p->name);
00151 return;
00152 }
00153
00154 if (find_servconn_in_progress(conf->name))
00155 {
00156 sendto_one(source_p, ":%s NOTICE %s :Connect: a connection to %s "
00157 "is already in progress.", me.name, source_p->name, conf->name);
00158 return;
00159 }
00160
00161
00162
00163
00164 ilog(L_TRACE, "CONNECT From %s : %s %s",
00165 source_p->name, parv[1], parv[2] ? parv[2] : "");
00166
00167 aconf->port = port;
00168
00169
00170
00171
00172 if (serv_connect(aconf, source_p))
00173 {
00174 if (!ConfigServerHide.hide_server_ips && IsAdmin(source_p))
00175 sendto_one(source_p, ":%s NOTICE %s :*** Connecting to %s[%s].%d",
00176 me.name, source_p->name, aconf->host,
00177 conf->name, aconf->port);
00178 else
00179 sendto_one(source_p, ":%s NOTICE %s :*** Connecting to %s.%d",
00180 me.name, source_p->name, conf->name, aconf->port);
00181 }
00182 else
00183 {
00184 sendto_one(source_p, ":%s NOTICE %s :*** Couldn't connect to %s.%d",
00185 me.name, source_p->name, conf->name, aconf->port);
00186 }
00187
00188
00189
00190
00191 aconf->port = tmpport;
00192 }
00193
00194
00195
00196
00197
00198
00199
00200
00201
00202
00203
00204
00205 static void
00206 ms_connect(struct Client *client_p, struct Client *source_p,
00207 int parc, char *parv[])
00208 {
00209 int port;
00210 int tmpport;
00211 struct ConfItem *conf = NULL;
00212 struct AccessItem *aconf = NULL;
00213 struct Client *target_p;
00214
00215 if (hunt_server(client_p, source_p,
00216 ":%s CONNECT %s %s :%s", 3, parc, parv) != HUNTED_ISME)
00217 return;
00218
00219 if (*parv[1] == '\0')
00220 {
00221 sendto_one(source_p, form_str(ERR_NEEDMOREPARAMS),
00222 me.name, source_p->name, "CONNECT");
00223 return;
00224 }
00225
00226 if ((target_p = find_server(parv[1])))
00227 {
00228 sendto_one(source_p,
00229 ":%s NOTICE %s :Connect: Server %s already exists from %s.",
00230 me.name, source_p->name, parv[1], target_p->from->name);
00231 return;
00232 }
00233
00234
00235
00236
00237 if ((conf = find_matching_name_conf(SERVER_TYPE,
00238 parv[1], NULL, NULL, 0)) != NULL)
00239 aconf = (struct AccessItem *)map_to_conf(conf);
00240 else if ((conf = find_matching_name_conf(SERVER_TYPE,
00241 NULL, NULL, parv[1], 0)) != NULL)
00242 aconf = (struct AccessItem *)map_to_conf(conf);
00243
00244 if (aconf == NULL)
00245 {
00246 sendto_one(source_p,
00247 ":%s NOTICE %s :Connect: Host %s not listed in ircd.conf",
00248 me.name, source_p->name, parv[1]);
00249 return;
00250 }
00251
00252 assert(aconf != NULL);
00253
00254
00255
00256
00257
00258 tmpport = port = aconf->port;
00259
00260 if (parc > 2 && !EmptyString(parv[2]))
00261 {
00262 port = atoi(parv[2]);
00263
00264
00265 if (port == 0 && aconf->port)
00266 port = aconf->port;
00267 else if (port <= 0)
00268 {
00269 sendto_one(source_p, ":%s NOTICE %s :Connect: Illegal port number",
00270 me.name, source_p->name);
00271 return;
00272 }
00273 }
00274 else if (port <= 0 && (port = PORTNUM) <= 0)
00275 {
00276 sendto_one(source_p, ":%s NOTICE %s :Connect: missing port number",
00277 me.name, source_p->name);
00278 return;
00279 }
00280
00281 if (find_servconn_in_progress(conf->name))
00282 {
00283 sendto_one(source_p, ":%s NOTICE %s :Connect: a connection to %s "
00284 "is already in progress.", me.name, source_p->name, conf->name);
00285 return;
00286 }
00287
00288
00289
00290
00291 sendto_wallops_flags(UMODE_WALLOP, &me, "Remote CONNECT %s %d from %s",
00292 parv[1], port, source_p->name);
00293 sendto_server(NULL, NULL, NULL, NOCAPS, NOCAPS, NOFLAGS,
00294 ":%s WALLOPS :Remote CONNECT %s %d from %s",
00295 me.name, parv[1], port, source_p->name);
00296
00297 ilog(L_TRACE, "CONNECT From %s : %s %d",
00298 source_p->name, parv[1], port);
00299
00300 aconf->port = port;
00301
00302
00303
00304
00305 if (serv_connect(aconf, source_p))
00306 sendto_one(source_p, ":%s NOTICE %s :*** Connecting to %s.%d",
00307 me.name, source_p->name, conf->name, aconf->port);
00308 else
00309 sendto_one(source_p, ":%s NOTICE %s :*** Couldn't connect to %s.%d",
00310 me.name, source_p->name, conf->name, aconf->port);
00311
00312
00313
00314 aconf->port = tmpport;
00315 }
00316