basic nick/channel name validation

This commit is contained in:
tali 2024-01-09 20:20:39 -05:00
parent 347d19df59
commit b3ea5e5e10
5 changed files with 36 additions and 13 deletions

View File

@ -3,7 +3,7 @@ open Types
type prefix = type prefix =
| No_prefix | No_prefix
| Server_prefix of string | Server_prefix of string
| User_prefix of nick * userinfo option * string option | User_prefix of name * userinfo option * string option
let pp_userinfo_opt ppf = function let pp_userinfo_opt ppf = function
| None -> () | None -> ()

View File

@ -3,7 +3,7 @@ open Types
type prefix = type prefix =
| No_prefix | No_prefix
| Server_prefix of string | Server_prefix of string
| User_prefix of nick * userinfo option * string option | User_prefix of name * userinfo option * string option
val prefix_string : prefix -> string val prefix_string : prefix -> string

View File

@ -1,2 +1,17 @@
type nick = string type name = string
type userinfo = { username : string; realname : string } type userinfo = { username : string; realname : string }
let name_type s =
let rec valid i =
if i >= String.length s then true
else
match s.[i] with
| ' ' | '@' | '+' | ',' -> false
| _ -> valid (i + 1)
in
if s = "" then `invalid
else
match s.[0] with
| ':' -> `invalid
| '#' -> if valid 1 then `chan else `invalid
| _ -> if valid 0 then `nick else `invalid

View File

@ -51,11 +51,14 @@ let attempt_to_register t =
| _, _ -> `ok | _, _ -> `ok
let on_msg_nick t nick = let on_msg_nick t nick =
(* TODO: validate nick *) if Irc.name_type nick <> `nick then
if User.is_registered t.user then (if nick = "" then `nonicknamegiven else `erroneusnickname nick)
else if User.is_registered t.user then
match User.set_nick t.user nick with match User.set_nick t.user nick with
| `nick_in_use -> `nicknameinuse nick | `nick_in_use -> `nicknameinuse nick
| `nick_set -> `ok | `nick_set ->
((* TODO: relay NICK message *));
`ok
else begin else begin
t.pending_nick <- Some nick; t.pending_nick <- Some nick;
attempt_to_register t attempt_to_register t
@ -141,14 +144,16 @@ let rpl_names t chan_prefix chan users =
rpl t "366" [chan; "End of NAMES list"] rpl t "366" [chan; "End of NAMES list"]
end end
let err_alreadyregistered t = rpl t "462" ["Unauthorized command (already registered)"]
let err_needmoreparams t cmd = rpl t "461" [cmd; "Not enough parameters"]
let err_nicknameinuse t nick = rpl t "433" [nick; "Nickname is already in use"]
let err_norecipient t cmd = rpl t "411" [Fmt.str "No recipient given (%s)" cmd]
let err_nosuchnick t tgt = rpl t "401" [tgt; "No such nick/channel"] let err_nosuchnick t tgt = rpl t "401" [tgt; "No such nick/channel"]
let err_norecipient t cmd = rpl t "411" [Fmt.str "No recipient given (%s)" cmd]
let err_notexttosend t = rpl t "412" ["No text to send"] let err_notexttosend t = rpl t "412" ["No text to send"]
let err_notregistered t = rpl t "451" ["You have not registered"]
let err_unknowncommand t cmd = rpl t "421" [cmd; "Unknown command"] let err_unknowncommand t cmd = rpl t "421" [cmd; "Unknown command"]
let err_nonicknamegiven t = rpl t "431" ["No nickname given"]
let err_erroneousnickname t nick = rpl t "432" [nick; "Erroneus nickname"]
let err_nicknameinuse t nick = rpl t "433" [nick; "Nickname is already in use"]
let err_notregistered t = rpl t "451" ["You have not registered"]
let err_needmoreparams t cmd = rpl t "461" [cmd; "Not enough parameters"]
let err_alreadyregistered t = rpl t "462" ["Unauthorized command (already registered)"]
(* message parsing *) (* message parsing *)
@ -158,6 +163,7 @@ let on_msg t (msg : Irc.Msg.t) : unit =
match msg.command, msg.params with match msg.command, msg.params with
| "NICK", new_nick :: _ -> | "NICK", new_nick :: _ ->
on_msg_nick t new_nick on_msg_nick t new_nick
| "NICK", [] -> `nonicknamegiven
| "USER", username :: modestr :: _host :: realname :: _ -> | "USER", username :: modestr :: _host :: realname :: _ ->
on_msg_user t username modestr realname on_msg_user t username modestr realname
| "QUIT", why -> | "QUIT", why ->
@ -168,7 +174,7 @@ let on_msg t (msg : Irc.Msg.t) : unit =
| "PRIVMSG", [_] -> `notexttosend | "PRIVMSG", [] -> `norecipient | "PRIVMSG", [_] -> `notexttosend | "PRIVMSG", [] -> `norecipient
| "JOIN", tgt :: _ -> | "JOIN", tgt :: _ ->
on_msg_join t tgt on_msg_join t tgt
| "NICK", _ | "USER", _ | "JOIN", _ -> `needmoreparams | "USER", _ | "JOIN", _ -> `needmoreparams
| _, _ -> `unknowncommand | _, _ -> `unknowncommand
in in
match result with match result with
@ -186,3 +192,5 @@ let on_msg t (msg : Irc.Msg.t) : unit =
| `notexttosend -> err_notexttosend t | `notexttosend -> err_notexttosend t
| `notregistered -> err_notregistered t | `notregistered -> err_notregistered t
| `unknowncommand -> err_unknowncommand t msg.command | `unknowncommand -> err_unknowncommand t msg.command
| `nonicknamegiven -> err_nonicknamegiven t
| `erroneusnickname n -> err_erroneousnickname t n

View File

@ -10,7 +10,7 @@ and user = {
hostname : string; hostname : string;
outbox : Outbox.t; outbox : Outbox.t;
mutable key : string_ci; mutable key : string_ci;
mutable nick : Irc.nick; mutable nick : Irc.name;
mutable userinfo : Irc.userinfo option; mutable userinfo : Irc.userinfo option;
mutable mode : Irc.Mode.t; mutable mode : Irc.Mode.t;
} }