2 * Copyright (c) 2004 Kungliga Tekniska Högskolan
3 * (Royal Institute of Technology, Stockholm, Sweden).
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
17 * 3. Neither the name of the Institute nor the names of its contributors
18 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission.
21 * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
38 __RCSID("$Heimdal: pop_auth.c 14046 2004-07-14 09:11:52Z joda $"
54 while(fgets(buf
+ strlen(buf
), size
- strlen(buf
), p
->input
) != NULL
) {
56 if((p
= strchr(buf
, '\n')) != NULL
) {
57 while(p
> buf
&& p
[-1] == '\r')
62 /* just assume we ran out of buffer space, we'll catch eof
65 p
= realloc(buf
, size
);
74 static char auth_msg
[128];
76 pop_auth_set_error(const char *message
)
78 strlcpy(auth_msg
, message
, sizeof(auth_msg
));
81 static struct auth_mech
*methods
[] = {
92 auth_execute(POP
*p
, struct auth_mech
*m
, void *state
, const char *line
)
95 size_t input_length
, output_length
;
102 input
= strdup(line
);
104 pop_auth_set_error("out of memory");
105 return POP_AUTH_FAILURE
;
107 input_length
= base64_decode(line
, input
);
108 if(input_length
== (size_t)-1) {
109 pop_auth_set_error("base64 decode error");
110 return POP_AUTH_FAILURE
;
113 output
= NULL
; output_length
= 0;
114 status
= (*m
->loop
)(p
, state
, input
, input_length
, &output
, &output_length
);
115 if(output_length
> 0) {
117 base64_encode(output
, output_length
, &s
);
118 fprintf(p
->output
, "+ %s\r\n", s
);
127 auth_loop(POP
*p
, struct auth_mech
*m
)
133 status
= (*m
->init
)(p
, &state
);
135 status
= auth_execute(p
, m
, state
, p
->pop_parm
[2]);
137 while(status
== POP_AUTH_CONTINUE
) {
140 (*m
->cleanup
)(p
, state
);
141 return pop_msg(p
, POP_FAILURE
, "error reading data");
143 if(strcmp(line
, "*") == 0) {
144 (*m
->cleanup
)(p
, state
);
145 return pop_msg(p
, POP_FAILURE
, "terminated by client");
147 status
= auth_execute(p
, m
, state
, line
);
152 (*m
->cleanup
)(p
, state
);
153 if(status
== POP_AUTH_FAILURE
)
154 return pop_msg(p
, POP_FAILURE
, "%s", auth_msg
);
156 status
= login_user(p
);
157 if(status
!= POP_SUCCESS
)
159 return pop_msg(p
, POP_SUCCESS
, "authentication complete");
167 for (i
= 0; methods
[i
] != NULL
; ++i
)
168 if (strcasecmp(p
->pop_parm
[1], methods
[i
]->name
) == 0)
169 return auth_loop(p
, methods
[i
]);
170 return pop_msg(p
, POP_FAILURE
,
171 "Authentication method %s unknown", p
->pop_parm
[1]);
175 pop_capa_sasl(POP
*p
)
179 if(methods
[0] == NULL
)
182 fprintf(p
->output
, "SASL");
183 for (i
= 0; methods
[i
] != NULL
; ++i
)
184 fprintf(p
->output
, " %s", methods
[i
]->name
);
185 fprintf(p
->output
, "\r\n");