diff --git a/pam/Makefile.am b/pam/Makefile.am index ff8f0ba05b20272a64b05817c8e01f4506ce93d6..dcdaa51625e31c123a225fd34e721c1441441dd5 100644 --- a/pam/Makefile.am +++ b/pam/Makefile.am @@ -10,7 +10,8 @@ noinst_LIBRARIES = libgtest.a libauthclient_la_SOURCES = \ auth_client.c auth_client.h \ - cbuf.c cbuf.h + cbuf.c cbuf.h \ + quote.c quote.h libauthclient_la_includedir = $(includedir)/authclient libauthclient_la_include_HEADERS = auth_client.h diff --git a/pam/auth_client.c b/pam/auth_client.c index 98789be6782576b9a68563b57f9f0560d8c82dcd..ae538d2e29705f53b5bea129618bbdd3786e550c 100644 --- a/pam/auth_client.c +++ b/pam/auth_client.c @@ -10,6 +10,7 @@ #include <curl/curl.h> #include "auth_client.h" #include "cbuf.h" +#include "quote.h" #define CURL_CHECK(x) { \ int _err = (x); if (_err != CURLE_OK) { return auth_client_err_from_curl(_err); } \ @@ -147,6 +148,7 @@ static char *quote(const char *s) { case '+': case '$': case ',': + case '%': sprintf(optr, "%%%02X", (int)(*s)); optr += 3; break; @@ -167,7 +169,7 @@ static size_t responsebuf_callback(void *contents, size_t size, size_t nmemb, vo } static void post_field_add(struct cbuf *form_data, const char *key, const char *value) { - char *quoted_value = quote(value); + char *quoted_value = auth_client_quote(value); if (form_data->size != 0) { cbuf_append(form_data, "&", 1); } diff --git a/pam/quote.c b/pam/quote.c new file mode 100644 index 0000000000000000000000000000000000000000..da14be4f54aaccea7cb4773ee133ec2f8c1abe39 --- /dev/null +++ b/pam/quote.c @@ -0,0 +1,30 @@ +#include <stdlib.h> +#include "quote.h" + +/* Converts a hex character to its integer value */ +static char from_hex(char ch) { + return isdigit(ch) ? ch - '0' : tolower(ch) - 'a' + 10; +} + +/* Converts an integer value to its hex character*/ +static char to_hex(char code) { + static const char hex[] = "0123456789abcdef"; + return hex[code & 15]; +} + +/* Returns a url-encoded version of str */ +/* IMPORTANT: be sure to free() the returned string after use */ +char *auth_client_quote(const char *str) { + char *pstr = str, *buf = malloc(strlen(str) * 3 + 1), *pbuf = buf; + while (*pstr) { + if (isalnum(*pstr) || *pstr == '-' || *pstr == '_' || *pstr == '.' || *pstr == '~') + *pbuf++ = *pstr; + else if (*pstr == ' ') + *pbuf++ = '+'; + else + *pbuf++ = '%', *pbuf++ = to_hex(*pstr >> 4), *pbuf++ = to_hex(*pstr & 15); + pstr++; + } + *pbuf = '\0'; + return buf; +} diff --git a/pam/quote.h b/pam/quote.h new file mode 100644 index 0000000000000000000000000000000000000000..55923125dbfc0bd426609db9fa04f18bb839d514 --- /dev/null +++ b/pam/quote.h @@ -0,0 +1,6 @@ +#ifndef __libauthclient_quote_h +#define __libauthclient_quote_h 1 + +char *auth_client_quote(const char *); + +#endif