1 | /*************************************** 2 | $Revision: 1.8 $ 3 | 4 | Authentication utilities 5 | 6 | Status: NOT REVIEWED, NOT TESTED 7 | 8 | Author(s): Engin Gunduz 9 | 10 | ******************/ /****************** 11 | Modification History: 12 | engin (05/04/2000) Created. 13 | ******************/ /****************** 14 | Copyright (c) 2000 RIPE NCC 15 | 16 | All Rights Reserved 17 | 18 | Permission to use, copy, modify, and distribute this software and its 19 | documentation for any purpose and without fee is hereby granted, 20 | provided that the above copyright notice appear in all copies and that 21 | both that copyright notice and this permission notice appear in 22 | supporting documentation, and that the name of the author not be 23 | used in advertising or publicity pertaining to distribution of the 24 | software without specific, written prior permission. 25 | 26 | THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING 27 | ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS; IN NO EVENT SHALL 28 | AUTHOR BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY 29 | DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN 30 | AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 31 | OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 32 | ***************************************/ 33 | 34 | #include "AU_util.h" 35 | 36 | /* AU_crypt is a wrapper around crypt(3) */ 37 | char * AU_crypt(const char *key, const char *setting){ 38 | 39 | return crypt(key, setting); 40 | 41 | } 42 | 43 | /* takes a list of passwords and a crypted password. If any 44 | of the passwords in the list is the plaintext of crypted 45 | text, then it immediately returns 1. Otherwise, it returns 46 | 0 */ 47 | int au_check_password(char * crypted_password, GSList * password_list){ 48 | 49 | GSList * next = NULL; 50 | 51 | for(next = password_list; next != NULL; next = g_slist_next(next)){ 52 | /* if the password is correct, return 1 */ 53 | if(strcmp(crypt((char *)next->data, crypted_password), crypted_password) == 0){ 54 | printf("DEBUG: au_check_password returning 1\n"); 55 | return(1); 56 | } 57 | } 58 | /* we couldn't find any correct password. So, return 0 */ 59 | printf("DEBUG: au_check_password returning 0\n"); 60 | return(0); 61 | } 62 | 63 | 64 | /* Compares the 'From' address of the message to the regular 65 | expression in the 'auth' attribute of the maintainer*/ 66 | int au_check_from_address(char * regexp, char * from_address){ 67 | 68 | int status; 69 | regex_t re; 70 | 71 | if(from_address == NULL){ 72 | return(0); 73 | } 74 | if (regcomp(&re, regexp, REG_EXTENDED|REG_NOSUB) != 0) { 75 | printf("DEBUG: au_check_from_address returns 0 (couldn't compile)\n"); 76 | return(0); /* couldn't compile the regexp, return false */ 77 | } 78 | 79 | status = regexec(&re, from_address, (size_t) 0, NULL, 0); 80 | regfree(&re); 81 | if (status != 0) { 82 | printf("DEBUG: au_check_from_address returns 0 (regexp doesn't match)\n\t[regexp:%s][from:%s]\n", 83 | regexp, from_address); 84 | return(0); /* failed */ 85 | } 86 | /* OK, the regexp matches */ 87 | printf("DEBUG: au_check_from_address returns 1\n"); 88 | return(1); 89 | } 90 | 91 | /* Gets a auth_vector, and credentials_struct (which is extracted 92 | from the update message) and returns 0 if all of the auth 93 | methods fail, and returns the index of the succeeding auth_struct in the auth_vector 94 | if any one of them succeeds. */ 95 | int AU_authorise(GSList * auth_vector, credentials_struct credentials){ 96 | 97 | GSList * next = NULL; 98 | auth_struct * temp = NULL; 99 | int result = 0; 100 | 101 | /* if the linked list contains no members, then return 1*/ 102 | if(g_slist_length(auth_vector) == 0){ 103 | return(1); 104 | } 105 | 106 | for(next = auth_vector; next != NULL; next = g_slist_next(next)){ 107 | temp = (auth_struct *)next->data; 108 | if( temp != NULL ){ 109 | printf("au_authorise: %s\n", (char *)temp->mntner_name); 110 | switch (temp->type){ 111 | case AU_NONE: return temp->index; /* NONE, immediately returns true */ 112 | case AU_MAIL_FROM: if(au_check_from_address(temp->auth, credentials.from)){ 113 | result = temp->index; 114 | } 115 | break; 116 | case AU_CRYPT_PW: if(au_check_password(temp->auth, credentials.password_list)){ 117 | result = temp->index; 118 | } 119 | break; 120 | case AU_PGP: result = 0; /* not yet implemented */ 121 | break; 122 | default: ;/* this mustn't happen */ 123 | } 124 | if(result > 0){ 125 | return(result); 126 | } 127 | } 128 | } 129 | /* we couldn't find any credential which passes, so returning 0 */ 130 | return 0; 131 | 132 | }