diff options
-rw-r--r-- | general_network.c | 41 | ||||
-rw-r--r-- | general_network.h | 2 | ||||
-rw-r--r-- | protocols.c | 5 | ||||
-rw-r--r-- | protocols.h | 5 | ||||
-rw-r--r-- | protocols/inspircd2.c | 177 | ||||
-rw-r--r-- | protocols/inspircd2.h | 6 | ||||
-rw-r--r-- | server_network.c | 4 |
7 files changed, 190 insertions, 50 deletions
diff --git a/general_network.c b/general_network.c index 432faa0..ad7016c 100644 --- a/general_network.c +++ b/general_network.c @@ -284,6 +284,34 @@ int add_user(struct string from, struct string attached_to, struct string uid, s return 1; } +int rename_user(struct string from, struct user_info *user, struct string nick, size_t timestamp) { + struct string timestamp_str; + if (unsigned_to_str(timestamp, ×tamp_str) != 0) + return 1; + + void *tmp = malloc(nick.len); + if (!tmp) { + free(timestamp_str.data); + return 1; + } + +#ifdef USE_SERVER +#ifdef USE_HAXIRCD_PROTOCOL + protocols[HAXIRCD_PROTOCOL].propagate_rename_user(from, user, nick, timestamp, timestamp_str); +#endif +#ifdef USE_INSPIRCD2_PROTOCOL + protocols[INSPIRCD2_PROTOCOL].propagate_rename_user(from, user, nick, timestamp, timestamp_str); +#endif +#endif + + free(user->nick.data); + user->nick.data = tmp; + memcpy(user->nick.data, nick.data, nick.len); + user->nick.len = nick.len; + + return 0; +} + void remove_user(struct string from, struct user_info *user, struct string reason, char propagate) { #ifdef USE_SERVER if (propagate) { @@ -318,3 +346,16 @@ void remove_user(struct string from, struct user_info *user, struct string reaso free(user->address.data); free(user); } + +void kill_user(struct string from, struct string source, struct user_info *user, struct string reason) { +#ifdef USE_SERVER +#ifdef USE_HAXIRCD_PROTOCOL + protocols[HAXIRCD_PROTOCOL].propagate_kill_user(from, source, user, reason); +#endif +#ifdef USE_INSPIRCD2_PROTOCOL + protocols[INSPIRCD2_PROTOCOL].propagate_kill_user(from, source, user, reason); +#endif +#endif + + remove_user(from, user, reason, 0); +} diff --git a/general_network.h b/general_network.h index 1413741..34a3d0c 100644 --- a/general_network.h +++ b/general_network.h @@ -96,7 +96,9 @@ int resolve(struct string address, struct string port, struct sockaddr *sockaddr int init_general_network(void); int add_user(struct string from, struct string attached_to, struct string uid, struct string nick, struct string fullname, struct string ident, struct string vhost, struct string host, struct string address, size_t user_ts, size_t nick_ts, void *handle, size_t protocol, size_t net); +int rename_user(struct string from, struct user_info *user, struct string nick, size_t timestamp); void remove_user(struct string from, struct user_info *user, struct string reason, char propagate); +void kill_user(struct string from, struct string source, struct user_info *user, struct string reason); extern char casemap[UCHAR_MAX+1]; #define CASEMAP(x) (casemap[(unsigned char)x]) diff --git a/protocols.c b/protocols.c index 04dd2f9..4b8afc3 100644 --- a/protocols.c +++ b/protocols.c @@ -40,9 +40,12 @@ struct protocol protocols[NUM_PROTOCOLS] = { .update_propagations = inspircd2_protocol_update_propagations, .propagate_new_server = inspircd2_protocol_propagate_new_server, - .propagate_unlink = inspircd2_protocol_propagate_unlink, + .propagate_unlink_server = inspircd2_protocol_propagate_unlink_server, + .propagate_new_user = inspircd2_protocol_propagate_new_user, + .propagate_rename_user = inspircd2_protocol_propagate_rename_user, .propagate_remove_user = inspircd2_protocol_propagate_remove_user, + .propagate_kill_user = inspircd2_protocol_propagate_kill_user, .do_unlink = inspircd2_protocol_do_unlink, }, diff --git a/protocols.h b/protocols.h index 723d971..c9fcc58 100644 --- a/protocols.h +++ b/protocols.h @@ -34,9 +34,12 @@ struct protocol { void (*update_propagations)(void); void (*propagate_new_server)(struct string from, struct string attached_to, struct server_info *info); - void (*propagate_unlink)(struct string from, struct server_info *a, struct server_info *b, size_t protocol); + void (*propagate_unlink_server)(struct string from, struct server_info *a, struct server_info *b, size_t protocol); + void (*propagate_new_user)(struct string from, struct user_info *info); + void (*propagate_rename_user)(struct string from, struct user_info *info, struct string nick, size_t timestamp, struct string timestamp_str); void (*propagate_remove_user)(struct string from, struct user_info *info, struct string reason); + void (*propagate_kill_user)(struct string from, struct string source, struct user_info *info, struct string reason); void (*do_unlink)(struct string from, struct server_info *a, struct server_info *b); }; diff --git a/protocols/inspircd2.c b/protocols/inspircd2.c index 46c9f8b..2d6fe96 100644 --- a/protocols/inspircd2.c +++ b/protocols/inspircd2.c @@ -132,8 +132,9 @@ int init_inspircd2_protocol(void) { set_table_index(&inspircd2_protocol_commands, STRING("RSQUIT"), &inspircd2_protocol_handle_rsquit); set_table_index(&inspircd2_protocol_commands, STRING("UID"), &inspircd2_protocol_handle_uid); + set_table_index(&inspircd2_protocol_commands, STRING("NICK"), &inspircd2_protocol_handle_nick); set_table_index(&inspircd2_protocol_commands, STRING("QUIT"), &inspircd2_protocol_handle_quit); -// set_table_index(&inspircd2_protocol_commands, STRING("KILL"), &inspircd2_protocol_handle_kill); + set_table_index(&inspircd2_protocol_commands, STRING("KILL"), &inspircd2_protocol_handle_kill); return 0; } @@ -505,7 +506,7 @@ void inspircd2_protocol_propagate_new_server(struct string from, struct string a } } -void inspircd2_protocol_propagate_unlink(struct string from, struct server_info *a, struct server_info *b, size_t protocol) { +void inspircd2_protocol_propagate_unlink_server(struct string from, struct server_info *a, struct server_info *b, size_t protocol) { struct server_info *source; struct server_info *target; if (a->distance == 0 && !STRING_EQ(a->sid, SID)) { @@ -567,6 +568,24 @@ void inspircd2_protocol_propagate_new_user(struct string from, struct user_info } } +void inspircd2_protocol_propagate_rename_user(struct string from, struct user_info *user, struct string nick, size_t timestamp, struct string timestamp_str) { + struct server_info *self = get_table_index(server_list, SID); + + for (size_t i = 0; i < self->connected_to.len; i++) { + struct server_info *adjacent = self->connected_to.array[i].ptr; + if (adjacent->protocol != INSPIRCD2_PROTOCOL || STRING_EQ(from, adjacent->sid)) + continue; + + networks[adjacent->net].send(adjacent->handle, STRING(":")); + networks[adjacent->net].send(adjacent->handle, user->uid); + networks[adjacent->net].send(adjacent->handle, STRING(" NICK ")); + networks[adjacent->net].send(adjacent->handle, nick); + networks[adjacent->net].send(adjacent->handle, STRING(" ")); + networks[adjacent->net].send(adjacent->handle, timestamp_str); + networks[adjacent->net].send(adjacent->handle, STRING("\n")); + } +} + void inspircd2_protocol_propagate_remove_user(struct string from, struct user_info *info, struct string reason) { struct server_info *self = get_table_index(server_list, SID); @@ -583,6 +602,24 @@ void inspircd2_protocol_propagate_remove_user(struct string from, struct user_in } } +void inspircd2_protocol_propagate_kill_user(struct string from, struct string source, struct user_info *info, struct string reason) { + struct server_info *self = get_table_index(server_list, SID); + + for (size_t i = 0; i < self->connected_to.len; i++) { + struct server_info *adjacent = self->connected_to.array[i].ptr; + if (adjacent->protocol != INSPIRCD2_PROTOCOL || STRING_EQ(from, adjacent->sid)) + continue; + + networks[adjacent->net].send(adjacent->handle, STRING(":")); + networks[adjacent->net].send(adjacent->handle, source); + networks[adjacent->net].send(adjacent->handle, STRING(" KILL ")); + networks[adjacent->net].send(adjacent->handle, info->uid); + networks[adjacent->net].send(adjacent->handle, STRING(" :")); + networks[adjacent->net].send(adjacent->handle, reason); + networks[adjacent->net].send(adjacent->handle, STRING("\n")); + } +} + void inspircd2_protocol_do_unlink_inner(struct string from, struct server_info *target, struct string reason) { target->distance = 1; // Reusing distance for `have passed`, since its set to 0 bc severed anyways @@ -654,6 +691,30 @@ void inspircd2_protocol_introduce_servers_to(size_t net, void *handle) { } } +void inspircd2_protocol_introduce_user_to(size_t net, void *handle, struct user_info *user) { + networks[net].send(handle, STRING(":")); + networks[net].send(handle, user->server); + networks[net].send(handle, STRING(" UID ")); + networks[net].send(handle, user->uid); + networks[net].send(handle, STRING(" ")); + networks[net].send(handle, user->user_ts_str); + networks[net].send(handle, STRING(" ")); + networks[net].send(handle, user->nick); + networks[net].send(handle, STRING(" ")); + networks[net].send(handle, user->host); + networks[net].send(handle, STRING(" ")); + networks[net].send(handle, user->vhost); + networks[net].send(handle, STRING(" ")); + networks[net].send(handle, user->ident); + networks[net].send(handle, STRING(" ")); + networks[net].send(handle, user->address); + networks[net].send(handle, STRING(" ")); + networks[net].send(handle, user->nick_ts_str); + networks[net].send(handle, STRING(" + :")); + networks[net].send(handle, user->fullname); + networks[net].send(handle, STRING("\n")); +} + // CAPAB <type> [<args> [, ...]] int inspircd2_protocol_init_handle_capab(struct string source, size_t argc, struct string *argv, size_t net, void *handle, struct server_config **config, char is_incoming) { if (argc < 1) { @@ -730,48 +791,8 @@ int inspircd2_protocol_init_handle_server(struct string source, size_t argc, str inspircd2_protocol_introduce_servers_to(net, handle); - for (size_t i = 0; i < user_list.len; i++) { - struct user_info *user = user_list.array[i].ptr; - - networks[net].send(handle, STRING(":")); - networks[net].send(handle, user->server); - networks[net].send(handle, STRING(" UID ")); - networks[net].send(handle, user->uid); - networks[net].send(handle, STRING(" ")); - - struct string timestamp; - char err = unsigned_to_str(user->nick_ts, ×tamp); - - if (err) { - return -1; - } - networks[net].send(handle, timestamp); - free(timestamp.data); - - networks[net].send(handle, STRING(" ")); - networks[net].send(handle, user->nick); - networks[net].send(handle, STRING(" ")); - networks[net].send(handle, user->host); - networks[net].send(handle, STRING(" ")); - networks[net].send(handle, user->vhost); - networks[net].send(handle, STRING(" ")); - networks[net].send(handle, user->ident); - networks[net].send(handle, STRING(" ")); - networks[net].send(handle, user->address); - networks[net].send(handle, STRING(" ")); - - err = unsigned_to_str(user->nick_ts, ×tamp); - - if (err) { - return -1; - } - networks[net].send(handle, timestamp); - free(timestamp.data); - - networks[net].send(handle, STRING(" + :")); - networks[net].send(handle, user->fullname); - networks[net].send(handle, STRING("\n")); - } + for (size_t i = 0; i < user_list.len; i++) + inspircd2_protocol_introduce_user_to(net, handle, user_list.array[i].ptr); networks[net].send(handle, STRING(":")); networks[net].send(handle, SID); @@ -965,7 +986,31 @@ int inspircd2_protocol_handle_uid(struct string source, size_t argc, struct stri return 0; } -// :source QUIT <reason> +// :source NICK <nick> <timestamp> +int inspircd2_protocol_handle_nick(struct string source, size_t argc, struct string *argv, size_t net, void *handle, struct server_config *config, char is_incoming) { + if (argc < 2) { + WRITES(2, STRING("[InspIRCd v2] Invalid NICK recieved! (Missing parameters)\r\n")); + return -1; + } + + char err; + size_t nick_ts = str_to_unsigned(argv[1], &err); + if (err) { + WRITES(2, STRING("[InspIRCd v2] Invalid NICK recieved! (Invalid timestamp)\r\n")); + return -1; + } + + struct user_info *user = get_table_index(user_list, source); + if (!user) + return 0; // KILL timings, etc + + if (rename_user(config->sid, user, argv[0], nick_ts) != 0) + return -1; + + return 0; +} + +// :source QUIT [<reason>?] int inspircd2_protocol_handle_quit(struct string source, size_t argc, struct string *argv, size_t net, void *handle, struct server_config *config, char is_incoming) { struct string reason; if (argc < 1) @@ -986,3 +1031,45 @@ int inspircd2_protocol_handle_quit(struct string source, size_t argc, struct str return 0; } + +// [:source] KILL <target> [<reason>?] +int inspircd2_protocol_handle_kill(struct string source, size_t argc, struct string *argv, size_t net, void *handle, struct server_config *config, char is_incoming) { + if (argc < 1) { + WRITES(2, STRING("[InspIRCd v2] Invalid KILL recieved! (Missing parameters)\r\n")); + return -1; + } + + struct user_info *user = get_table_index(user_list, argv[0]); + if (!user) { + for (size_t i = 0; i < user_list.len; i++) { + struct user_info *tmp = user_list.array[i].ptr; + if (STRING_EQ(tmp->nick, argv[0])) { + user = tmp; + break; + } + } + + if (!user) + return 0; + } + + if (STRING_EQ(user->server, SID)) { + if (config->ignore_local_kills) { + inspircd2_protocol_introduce_user_to(net, handle, user); + } else { + if (argc > 1) + kill_user(config->sid, source, user, argv[1]); + else + kill_user(config->sid, source, user, STRING("")); + } + } else if (config->ignore_remote_kills) { + inspircd2_protocol_introduce_user_to(net, handle, user); + } else { + if (argc > 1) + kill_user(config->sid, source, user, argv[1]); + else + kill_user(config->sid, source, user, STRING("")); + } + + return 0; +} diff --git a/protocols/inspircd2.h b/protocols/inspircd2.h index 03963b6..0a19964 100644 --- a/protocols/inspircd2.h +++ b/protocols/inspircd2.h @@ -42,9 +42,12 @@ void * inspircd2_protocol_autoconnect(void *type); void inspircd2_protocol_update_propagations(void); void inspircd2_protocol_propagate_new_server(struct string from, struct string attached_to, struct server_info *info); -void inspircd2_protocol_propagate_unlink(struct string from, struct server_info *a, struct server_info *b, size_t protocol); +void inspircd2_protocol_propagate_unlink_server(struct string from, struct server_info *a, struct server_info *b, size_t protocol); + void inspircd2_protocol_propagate_new_user(struct string from, struct user_info *info); +void inspircd2_protocol_propagate_rename_user(struct string from, struct user_info *info, struct string nick, size_t timestamp, struct string timestamp_str); void inspircd2_protocol_propagate_remove_user(struct string from, struct user_info *info, struct string reason); +void inspircd2_protocol_propagate_kill_user(struct string from, struct string source, struct user_info *info, struct string reason); void inspircd2_protocol_do_unlink(struct string from, struct server_info *a, struct server_info *b); @@ -61,6 +64,7 @@ int inspircd2_protocol_handle_squit(struct string source, size_t argc, struct st int inspircd2_protocol_handle_rsquit(struct string source, size_t argc, struct string *argv, size_t net, void *handle, struct server_config *config, char is_incoming); int inspircd2_protocol_handle_uid(struct string source, size_t argc, struct string *argv, size_t net, void *handle, struct server_config *config, char is_incoming); +int inspircd2_protocol_handle_nick(struct string source, size_t argc, struct string *argv, size_t net, void *handle, struct server_config *config, char is_incoming); int inspircd2_protocol_handle_quit(struct string source, size_t argc, struct string *argv, size_t net, void *handle, struct server_config *config, char is_incoming); int inspircd2_protocol_handle_kill(struct string source, size_t argc, struct string *argv, size_t net, void *handle, struct server_config *config, char is_incoming); diff --git a/server_network.c b/server_network.c index aeca696..6908a31 100644 --- a/server_network.c +++ b/server_network.c @@ -285,10 +285,10 @@ void unlink_server(struct string from, struct server_info *a, struct server_info protocols[protocol].update_propagations(); #ifdef USE_HAXIRCD_PROTOCOL - protocols[HAXIRCD_PROTOCOL].propagate_unlink(from, a, b, protocol); + protocols[HAXIRCD_PROTOCOL].propagate_unlink_server(from, a, b, protocol); #endif #ifdef USE_INSPIRCD2_PROTOCOL - protocols[INSPIRCD2_PROTOCOL].propagate_unlink(from, a, b, protocol); + protocols[INSPIRCD2_PROTOCOL].propagate_unlink_server(from, a, b, protocol); #endif protocols[protocol].do_unlink(from, a, b); |