Page MenuHomeDevCentral
Paste P331

SASL-plain.c
ActivePublic

Authored by dereckson on May 14 2023, 12:37.
Tags
Referenced Files
F2217666: SASL-plain.c
May 14 2023, 12:43
F2217664: SASL-plain.c
May 14 2023, 12:37
Subscribers
None
/* -------------------------------------------------------------
Test SASL PLAIN authentication
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Project: Nasqueron
Description: Test SASL plain authentication to solve T1739
License: BSD-2-Clause
------------------------------------------------------------- */
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <openssl/bio.h>
#include <openssl/evp.h>
#include <openssl/buffer.h>
/* -------------------------------------------------------------
SASL plain authentication
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
/**
* Build a SASL PLAIN string, encoded in Base64
* @identity: The identity you want to authenticate as
* @username: The username
* @password: The password, in plain
* Returns: Allocated buffer of out_len bytes of encoded data,
* or %NULL on failure
*
* If the specification isn't clear what to use as identity, generally
* you can pass again the username. If not, pass an empty string.
*
* Caller is responsible for freeing the returned buffer. Returned buffer is
* nul terminated to make it easier to use as a C string.
*/
char* build_sasl_plain_string(char* identity, char* username, char* password) {
// Authentication string: concatenate the fields, with 2 NUL separator
// A lot of string.h functions stop at NUL character, so memcpy is safer.
// For example, with sprintf, only identity is copied to sasl_plain_string.
int identity_len = strlen(identity);
int username_len = strlen(username);
int password_len = strlen(password);
int sasl_plain_string_len = identity_len + username_len + password_len + 2;
char* sasl_plain_string = (char*) malloc(sasl_plain_string_len);
char* buffer = sasl_plain_string;
memcpy(buffer, identity, identity_len);
buffer += identity_len;
*buffer++ = '\0';
memcpy(buffer, username, username_len);
buffer += username_len;
*buffer++ = '\0';
memcpy(buffer, password, password_len);
buffer += password_len;
*buffer++ = '\0';
// Base64 encode
int base64_len = 0;
int sasl_plain_string_len_with_padding = sasl_plain_string_len + 2; // Add 2 for padding bytes
char* base64_string = (char*)malloc(EVP_ENCODE_LENGTH(sasl_plain_string_len_with_padding));
EVP_EncodeBlock((unsigned char*)base64_string, (const unsigned char*)sasl_plain_string, sasl_plain_string_len_with_padding);
base64_len = strlen(base64_string);
char* result = (char*)malloc(base64_len + 1);
memcpy(result, base64_string, base64_len);
result[base64_len] = '\0';
free(base64_string);
free(sasl_plain_string);
return result;
}
/* -------------------------------------------------------------
Program entry point
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
int main(int argc, char **argv) {
char *username;
char *password;
if (argc != 3) {
fprintf(stderr, "Usage: %s <username> <password>\n", argv[0]);
return 1;
}
username = argv[1];
password = argv[2];
char* payload = build_sasl_plain_string(username, username, password);
printf("%s\n", payload);
free(payload);
return 0;
}