1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106
|
#include <sys/types.h>
#include <ctype.h>
#include <errno.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <msg/msg.h>
#include <str/str.h>
#include "auth-lib.h"
#include "ucspi-proxy.h"
extern const char* local_name;
str username = {0,0,0};
static bool saw_auth_login = 0;
static bool saw_auth_plain = 0;
static str tmpstr;
void make_username(const char* start, ssize_t len, const char* msgprefix)
{
str_copyb(&username, start, len);
if (local_name && str_findfirst(&username, AT) < 0) {
str_catc(&username, AT);
str_cats(&username, local_name);
}
msg2(msgprefix, username.s);
}
static const char* skipspace(const char* ptr)
{
while (*ptr == ' ')
++ptr;
return ptr;
}
static int iseol(char ch)
{
return ch == CR || ch == LF;
}
static void handle_auth_login_response(str* line, ssize_t offset)
{
saw_auth_login = 0;
if (!base64decode(line->s + offset, line->len + offset, &tmpstr))
username.len = 0;
else {
make_username(tmpstr.s, tmpstr.len, "AUTH LOGIN ");
line->len = offset;
base64encode(username.s, username.len, line);
str_catb(line, CRLF, 2);
}
}
static void handle_auth_plain_response(str* line, ssize_t offset)
{
int start;
int end;
saw_auth_plain = 0;
if (base64decode(line->s + offset, line->len - offset, &tmpstr)) {
/* tmpstr should now contain "AUTHORIZATION\0AUTHENTICATION\0PASSWORD" */
if ((start = str_findfirst(&tmpstr, NUL)) >= 0
&& (end = str_findnext(&tmpstr, NUL, ++start)) > start) {
make_username(tmpstr.s + start, end - start, "AUTH PLAIN ");
str_splice(&tmpstr, start, end - start, &username);
line->len = offset;
base64encode(tmpstr.s, tmpstr.len, line);
str_catb(line, CRLF, 2);
}
}
}
int handle_auth_response(str* line, ssize_t offset)
{
if (saw_auth_login)
handle_auth_login_response(line, offset);
else if (saw_auth_plain)
handle_auth_plain_response(line, offset);
else
return 0;
return 1;
}
int handle_auth_parameter(str* line, ssize_t offset)
{
const char* ptr;
ptr = skipspace(line->s + offset);
/* No parameter, so just pass it through. */
if (iseol(*ptr))
return 0;
if (strncasecmp(ptr, "LOGIN", 5) == 0) {
if (ptr[5] == ' ' && !iseol(*(ptr = skipspace(ptr + 5))))
handle_auth_login_response(line, ptr - line->s);
else
saw_auth_login = 1;
}
else if (strncasecmp(ptr, "PLAIN", 5) == 0) {
if (ptr[5] == ' ' && !iseol(*(ptr = skipspace(ptr + 5))))
handle_auth_plain_response(line, ptr - line->s);
else
saw_auth_plain = 1;
}
return 1;
}
|