1 | /*************************************** 2 | $Revision: 1.15 $ 3 | 4 | Authentication utilities 5 | 6 | Status: NOT REVIEWED, 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 | 65 | 66 | /* simply compares auth_pgpkeyID & mesg_pgpkeyID and 67 | returns 1 if they are the same. */ 68 | int au_check_PGPkey(char * auth_pgpkeyID, /*char * mesg_pgpkeyID*/GSList * mesg_pgpkeyIDs){ 69 | 70 | GSList * next = NULL; 71 | 72 | for(next = mesg_pgpkeyIDs; next != NULL; next = g_slist_next(next)){ 73 | /* if auth_pgpkeyID & mesg_pgpkeyID are the same, return 1 */ 74 | if(strcmp(auth_pgpkeyID, (char *)next->data) == 0){ 75 | return(1); 76 | } 77 | } 78 | /* If we reached here, we couldn't find a matching keyID, so return 0 */ 79 | return(0); 80 | } 81 | 82 | 83 | 84 | /* Compares the 'From' address of the message to the regular 85 | expression in the 'auth' attribute of the maintainer*/ 86 | int au_check_from_address(char * regexp, char * from_address){ 87 | 88 | int status; 89 | regex_t re; 90 | 91 | if(from_address == NULL){ 92 | return(0); 93 | } 94 | if (regcomp(&re, regexp, REG_EXTENDED|REG_NOSUB|REG_ICASE) != 0) { 95 | //printf("DEBUG: au_check_from_address returns 0 (couldn't compile)\n"); 96 | return(0); /* couldn't compile the regexp, return false */ 97 | } 98 | 99 | status = regexec(&re, from_address, (size_t) 0, NULL, 0); 100 | regfree(&re); 101 | if (status != 0) { 102 | //printf("DEBUG: au_check_from_address returns 0 (regexp doesn't match)\n\t[regexp:%s][from:%s]\n", 103 | // regexp, from_address); 104 | return(0); /* failed */ 105 | } 106 | /* OK, the regexp matches */ 107 | //printf("DEBUG: au_check_from_address returns 1\n"); 108 | return(1); 109 | } 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | /* Gets a auth_vector, and credentials_struct (which is extracted 119 | from the update message) and returns 0 if all of the auth 120 | methods fail, and returns the index of the succeeding auth_struct in the auth_vector 121 | if any one of them succeeds. */ 122 | int AU_authorise(GSList * auth_vector, credentials_struct credentials){ 123 | 124 | GSList * next = NULL; 125 | auth_struct * temp = NULL; 126 | int result = 0; 127 | 128 | /* if the linked list contains no members, then return 1*/ 129 | if(g_slist_length(auth_vector) == 0){ 130 | return(1); 131 | } 132 | 133 | for(next = auth_vector; next != NULL; next = g_slist_next(next)){ 134 | temp = (auth_struct *)next->data; 135 | if( temp != NULL ){ 136 | switch (temp->type){ 137 | case AU_NONE: return temp->index; /* NONE, immediately returns true */ 138 | case AU_MAIL_FROM: if(au_check_from_address(temp->auth, credentials.from)){ 139 | result = temp->index; 140 | } 141 | break; 142 | case AU_CRYPT_PW: if(au_check_password(temp->auth, credentials.password_list)){ 143 | result = temp->index; 144 | } 145 | break; 146 | case AU_PGP: //printf("DEBUG: AU_authorise: will call au_check_PGPkey\n"); 147 | //printf("DEBUG: AU_authorise: with temp->auth=[%s]\n", temp->auth); 148 | //printf("DEBUG: AU_authorise: and credentials.pgp_struct=[%s]\n", credentials.pgp_struct); 149 | if(au_check_PGPkey(temp->auth, credentials.pgp_key_list)){ 150 | result = temp->index; 151 | } 152 | break; 153 | default: ;/* this mustn't happen */ 154 | } 155 | if(result > 0){ 156 | return(result); 157 | } 158 | } 159 | } 160 | /* we couldn't find any credential which passes, so returning 0 */ 161 | return 0; 162 | 163 | }