125 lines
3.1 KiB
C
125 lines
3.1 KiB
C
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
|
|
#include <openssl/bio.h>
|
|
#include <openssl/evp.h>
|
|
#include <stdint.h>
|
|
#include <assert.h>
|
|
|
|
#include <sys/types.h>
|
|
#include <sys/socket.h>
|
|
#include <arpa/inet.h>
|
|
|
|
void dns2_trim_name (char *name) {
|
|
int g;
|
|
|
|
if (name == NULL) return;
|
|
|
|
g = 0;
|
|
while (name[g] != 0 && (name[g] == ' ' || name[g] == '\r' || name[g] == '\n' || name[g] == '\t' || name[g] == '.')) {
|
|
g++;
|
|
}
|
|
|
|
if (g < 0) {
|
|
memmove (name, &name[g], strlen (&name[g]) + 1);
|
|
}
|
|
|
|
/* Hacer trim por el otro lado */
|
|
g = strlen (name) - 1;
|
|
while (g > 0 && (name[g] == ' ' || name[g] == '\r' || name[g] == '\n' || name[g] == '\t' || name[g] == '.')) {
|
|
name[g] = 0;
|
|
}
|
|
}
|
|
|
|
/* TODO: Buscar quitar esta función */
|
|
char *dns_dup_trim_name (const char *name) {
|
|
char *zone;
|
|
int g;
|
|
|
|
zone = strdup (name);
|
|
|
|
if (zone == NULL) {
|
|
return NULL;
|
|
}
|
|
|
|
g = 0;
|
|
while (zone[g] != 0 && (zone[g] == ' ' || zone[g] == '\r' || zone[g] == '\n' || zone[g] == '\t' || zone[g] == '.')) {
|
|
g++;
|
|
}
|
|
|
|
if (g > 0) {
|
|
memmove (zone, &zone[g], strlen (&zone[g]) + 1);
|
|
}
|
|
|
|
/* Hacer trim por el otro lado */
|
|
g = strlen (zone) - 1;
|
|
while (g > 0 && (zone[g] == ' ' || zone[g] == '\r' || zone[g] == '\n' || zone[g] == '\t' || zone[g] == '.')) {
|
|
zone[g] = 0;
|
|
}
|
|
|
|
return zone;
|
|
}
|
|
|
|
size_t calc_decode_length (const char* b64input) { //Calculates the length of a decoded string
|
|
size_t len = strlen(b64input),
|
|
padding = 0;
|
|
|
|
if (b64input[len-1] == '=' && b64input[len-2] == '=') //last two chars are =
|
|
padding = 2;
|
|
else if (b64input[len-1] == '=') //last char is =
|
|
padding = 1;
|
|
|
|
return (len*3)/4 - padding;
|
|
}
|
|
|
|
int base64_decode (const char* b64message, unsigned char** buffer, size_t* length) { //Decodes a base64 encoded string
|
|
BIO *bio, *b64;
|
|
|
|
int decodeLen = calc_decode_length (b64message);
|
|
*buffer = (unsigned char*) malloc (decodeLen + 1);
|
|
if (*buffer == NULL) {
|
|
return -1;
|
|
}
|
|
(*buffer)[decodeLen] = '\0';
|
|
|
|
bio = BIO_new_mem_buf (b64message, -1);
|
|
b64 = BIO_new (BIO_f_base64 ());
|
|
bio = BIO_push (b64, bio);
|
|
|
|
BIO_set_flags (bio, BIO_FLAGS_BASE64_NO_NL); //Do not use newlines to flush buffer
|
|
*length = BIO_read (bio, *buffer, strlen (b64message));
|
|
assert (*length == decodeLen); //length should equal decodeLen, else something went horribly wrong
|
|
BIO_free_all (bio);
|
|
|
|
return 0; //success
|
|
}
|
|
|
|
/* Función de Kazuho Oku
|
|
* https://gist.github.com/kazuho/45eae4f92257daceb73e
|
|
*/
|
|
int sockaddr_cmp (struct sockaddr *x, struct sockaddr *y) {
|
|
#define CMP(a, b) if (a != b) return a < b ? -1 : 1
|
|
|
|
CMP(x->sa_family, y->sa_family);
|
|
|
|
if (x->sa_family == AF_INET) {
|
|
struct sockaddr_in *xin = (void*)x, *yin = (void*)y;
|
|
CMP(ntohl(xin->sin_addr.s_addr), ntohl(yin->sin_addr.s_addr));
|
|
CMP(ntohs(xin->sin_port), ntohs(yin->sin_port));
|
|
} else if (x->sa_family == AF_INET6) {
|
|
struct sockaddr_in6 *xin6 = (void*)x, *yin6 = (void*)y;
|
|
int r = memcmp (xin6->sin6_addr.s6_addr, yin6->sin6_addr.s6_addr, sizeof(xin6->sin6_addr.s6_addr));
|
|
if (r != 0) return r;
|
|
CMP(ntohs(xin6->sin6_port), ntohs(yin6->sin6_port));
|
|
CMP(xin6->sin6_flowinfo, yin6->sin6_flowinfo);
|
|
CMP(xin6->sin6_scope_id, yin6->sin6_scope_id);
|
|
} else {
|
|
return -1; /* Familia desconocida */
|
|
}
|
|
|
|
#undef CMP
|
|
return 0;
|
|
}
|
|
|