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