Add a few token validation functions
This commit is contained in:
		
							
								
								
									
										87
									
								
								src/kike.c
									
									
									
									
									
								
							
							
						
						
									
										87
									
								
								src/kike.c
									
									
									
									
									
								
							@@ -89,6 +89,93 @@ setup_signal_handlers (void)
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// --- IRC token validation ----------------------------------------------------
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					enum validation_result
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						VALIDATION_OK,
 | 
				
			||||||
 | 
						VALIDATION_ERROR_EMPTY,
 | 
				
			||||||
 | 
						VALIDATION_ERROR_TOO_LONG,
 | 
				
			||||||
 | 
						VALIDATION_ERROR_INVALID
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Everything as per RFC 2812
 | 
				
			||||||
 | 
					#define IRC_NICKNAME_MAX    9
 | 
				
			||||||
 | 
					#define IRC_HOSTNAME_MAX   63
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Anything to keep it as short as possible
 | 
				
			||||||
 | 
					#define SN "[0-9A-Za-z][-0-9A-Za-z]*[0-9A-Za-z]*"
 | 
				
			||||||
 | 
					#define N4 "[0-9]{1,3}"
 | 
				
			||||||
 | 
					#define N6 "[0-9ABCDEFabcdef]{1,}"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define LE "A-Za-z"
 | 
				
			||||||
 | 
					#define SP "\\[\\]\\\\`_^{|}"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static const char *
 | 
				
			||||||
 | 
					irc_validate_to_str (enum validation_result result)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						switch (result)
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
						case VALIDATION_OK:              return "success";
 | 
				
			||||||
 | 
						case VALIDATION_ERROR_EMPTY:     return "the value is empty";
 | 
				
			||||||
 | 
						case VALIDATION_ERROR_INVALID:   return "invalid format";
 | 
				
			||||||
 | 
						case VALIDATION_ERROR_TOO_LONG:  return "the value is too long";
 | 
				
			||||||
 | 
						default:                         abort ();
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// TODO: at least cache the resulting `regex_t' in a `struct str_map'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static enum validation_result
 | 
				
			||||||
 | 
					irc_validate_hostname (const char *hostname)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						if (!*hostname)
 | 
				
			||||||
 | 
							return VALIDATION_ERROR_EMPTY;
 | 
				
			||||||
 | 
						if (!regex_match ("^" SN "(\\." SN ")*$", hostname, NULL))
 | 
				
			||||||
 | 
							return VALIDATION_ERROR_INVALID;
 | 
				
			||||||
 | 
						if (strlen (hostname) > IRC_HOSTNAME_MAX)
 | 
				
			||||||
 | 
							return VALIDATION_ERROR_TOO_LONG;
 | 
				
			||||||
 | 
						return VALIDATION_OK;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static bool
 | 
				
			||||||
 | 
					irc_is_valid_hostaddr (const char *hostaddr)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						if (regex_match ("^" N4 "\\." N4 "\\." N4 "\\." N4 "$", hostaddr, NULL)
 | 
				
			||||||
 | 
						 || regex_match ("^" N6 ":" N6 ":" N6 ":" N6 ":"
 | 
				
			||||||
 | 
							N6 ":" N6 ":" N6 ":" N6 "$", hostaddr, NULL)
 | 
				
			||||||
 | 
						 || regex_match ("^0:0:0:0:0:(0|[Ff]{4}):"
 | 
				
			||||||
 | 
							N4 "\\." N4 "\\." N4 "\\." N4 "$", hostaddr, NULL))
 | 
				
			||||||
 | 
							return true;
 | 
				
			||||||
 | 
						return false;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static bool
 | 
				
			||||||
 | 
					irc_is_valid_host (const char *host)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						return irc_validate_hostname (host) == VALIDATION_OK
 | 
				
			||||||
 | 
							|| irc_is_valid_hostaddr (host);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static bool
 | 
				
			||||||
 | 
					irc_validate_nickname (const char *nickname)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						if (!*nickname)
 | 
				
			||||||
 | 
							return VALIDATION_ERROR_EMPTY;
 | 
				
			||||||
 | 
						if (!regex_match ("^[" LE SP "][-0-9" LE SP "]*$", nickname, NULL))
 | 
				
			||||||
 | 
							return VALIDATION_ERROR_INVALID;
 | 
				
			||||||
 | 
						if (strlen (nickname) > IRC_NICKNAME_MAX)
 | 
				
			||||||
 | 
							return VALIDATION_ERROR_TOO_LONG;
 | 
				
			||||||
 | 
						return VALIDATION_OK;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#undef SN
 | 
				
			||||||
 | 
					#undef N4
 | 
				
			||||||
 | 
					#undef N6
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#undef LE
 | 
				
			||||||
 | 
					#undef SP
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// --- Application data --------------------------------------------------------
 | 
					// --- Application data --------------------------------------------------------
 | 
				
			||||||
 | 
					
 | 
				
			||||||
enum
 | 
					enum
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user