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 | }