summaryrefslogtreecommitdiffstats
path: root/src/sss_client/pam_message.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/sss_client/pam_message.c')
-rw-r--r--src/sss_client/pam_message.c194
1 files changed, 194 insertions, 0 deletions
diff --git a/src/sss_client/pam_message.c b/src/sss_client/pam_message.c
new file mode 100644
index 0000000..e3a09f5
--- /dev/null
+++ b/src/sss_client/pam_message.c
@@ -0,0 +1,194 @@
+/*
+ Authors:
+ Sumit Bose <sbose@redhat.com>
+
+ PAM client - create message blob
+
+ Copyright (C) 2015 Red Hat
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Lesser General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include <stdlib.h>
+#include <security/pam_modules.h>
+
+#include "sss_pam_compat.h"
+#include "sss_pam_macros.h"
+
+#include "pam_message.h"
+
+#include "sss_cli.h"
+
+static size_t add_authtok_item(enum pam_item_type type,
+ enum sss_authtok_type authtok_type,
+ const char *tok, const size_t size,
+ uint8_t *buf)
+{
+ size_t rp = 0;
+ uint32_t c;
+
+ if (tok == NULL) return 0;
+
+ c = type;
+ memcpy(&buf[rp], &c, sizeof(uint32_t));
+ rp += sizeof(uint32_t);
+
+ c = size + sizeof(uint32_t);
+ memcpy(&buf[rp], &c, sizeof(uint32_t));
+ rp += sizeof(uint32_t);
+
+ c = authtok_type;
+ memcpy(&buf[rp], &c, sizeof(uint32_t));
+ rp += sizeof(uint32_t);
+
+ memcpy(&buf[rp], tok, size);
+ rp += size;
+
+ return rp;
+}
+
+static size_t add_uint32_t_item(enum pam_item_type type, const uint32_t val,
+ uint8_t *buf)
+{
+ size_t rp = 0;
+ uint32_t c;
+
+ c = type;
+ memcpy(&buf[rp], &c, sizeof(uint32_t));
+ rp += sizeof(uint32_t);
+
+ c = sizeof(uint32_t);
+ memcpy(&buf[rp], &c, sizeof(uint32_t));
+ rp += sizeof(uint32_t);
+
+ c = val;
+ memcpy(&buf[rp], &c, sizeof(uint32_t));
+ rp += sizeof(uint32_t);
+
+ return rp;
+}
+
+static size_t add_string_item(enum pam_item_type type, const char *str,
+ const size_t size, uint8_t *buf)
+{
+ size_t rp = 0;
+ uint32_t c;
+
+ if (str == NULL || *str == '\0') return 0;
+
+ c = type;
+ memcpy(&buf[rp], &c, sizeof(uint32_t));
+ rp += sizeof(uint32_t);
+
+ c = size;
+ memcpy(&buf[rp], &c, sizeof(uint32_t));
+ rp += sizeof(uint32_t);
+
+ memcpy(&buf[rp], str, size);
+ rp += size;
+
+ return rp;
+}
+
+int pack_message_v3(struct pam_items *pi, size_t *size, uint8_t **buffer)
+{
+ int len;
+ uint8_t *buf;
+ size_t rp;
+
+ len = sizeof(uint32_t) + sizeof(uint32_t);
+
+ len += *pi->pam_user != '\0' ?
+ 2*sizeof(uint32_t) + pi->pam_user_size : 0;
+ len += *pi->pam_service != '\0' ?
+ 2*sizeof(uint32_t) + pi->pam_service_size : 0;
+ len += *pi->pam_tty != '\0' ?
+ 2*sizeof(uint32_t) + pi->pam_tty_size : 0;
+ len += *pi->pam_ruser != '\0' ?
+ 2*sizeof(uint32_t) + pi->pam_ruser_size : 0;
+ len += *pi->pam_rhost != '\0' ?
+ 2*sizeof(uint32_t) + pi->pam_rhost_size : 0;
+ len += pi->pam_authtok != NULL ?
+ 3*sizeof(uint32_t) + pi->pam_authtok_size : 0;
+ len += pi->pam_newauthtok != NULL ?
+ 3*sizeof(uint32_t) + pi->pam_newauthtok_size : 0;
+ len += 3*sizeof(uint32_t); /* cli_pid */
+
+ len += *pi->requested_domains != '\0' ?
+ 2*sizeof(uint32_t) + pi->requested_domains_size : 0;
+ len += 3*sizeof(uint32_t); /* flags */
+
+ /* optional child_pid */
+ if(pi->child_pid > 0) {
+ len += 3*sizeof(uint32_t);
+ }
+
+ buf = malloc(len);
+ if (buf == NULL) {
+ D(("malloc failed."));
+ return PAM_BUF_ERR;
+ }
+
+ rp = 0;
+ SAFEALIGN_SETMEM_UINT32(buf, SSS_START_OF_PAM_REQUEST, &rp);
+
+ rp += add_string_item(SSS_PAM_ITEM_USER, pi->pam_user, pi->pam_user_size,
+ &buf[rp]);
+
+ rp += add_string_item(SSS_PAM_ITEM_SERVICE, pi->pam_service,
+ pi->pam_service_size, &buf[rp]);
+
+ rp += add_string_item(SSS_PAM_ITEM_TTY, pi->pam_tty, pi->pam_tty_size,
+ &buf[rp]);
+
+ rp += add_string_item(SSS_PAM_ITEM_RUSER, pi->pam_ruser, pi->pam_ruser_size,
+ &buf[rp]);
+
+ rp += add_string_item(SSS_PAM_ITEM_RHOST, pi->pam_rhost, pi->pam_rhost_size,
+ &buf[rp]);
+
+ rp += add_string_item(SSS_PAM_ITEM_REQUESTED_DOMAINS, pi->requested_domains, pi->requested_domains_size,
+ &buf[rp]);
+
+ rp += add_uint32_t_item(SSS_PAM_ITEM_CLI_PID, (uint32_t) pi->cli_pid,
+ &buf[rp]);
+
+ if (pi->child_pid > 0) {
+ rp += add_uint32_t_item(SSS_PAM_ITEM_CHILD_PID,
+ (uint32_t) pi->child_pid, &buf[rp]);
+ }
+
+ rp += add_authtok_item(SSS_PAM_ITEM_AUTHTOK, pi->pam_authtok_type,
+ pi->pam_authtok, pi->pam_authtok_size, &buf[rp]);
+
+ rp += add_authtok_item(SSS_PAM_ITEM_NEWAUTHTOK, pi->pam_newauthtok_type,
+ pi->pam_newauthtok, pi->pam_newauthtok_size,
+ &buf[rp]);
+
+ rp += add_uint32_t_item(SSS_PAM_ITEM_FLAGS, (uint32_t) pi->flags,
+ &buf[rp]);
+
+ SAFEALIGN_SETMEM_UINT32(buf + rp, SSS_END_OF_PAM_REQUEST, &rp);
+
+ if (rp != len) {
+ D(("error during packet creation."));
+ free(buf);
+ return PAM_BUF_ERR;
+ }
+
+ *size = len;
+ *buffer = buf;
+
+ return 0;
+}