Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

PAM: Add support for more native pam features and initial support for gdm #2

Closed
wants to merge 9 commits into from
10 changes: 10 additions & 0 deletions .github/workflows/qa.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,11 @@ jobs:
name: Code sanity
runs-on: ubuntu-latest
steps:
- name: Install dependencies
uses: awalsh128/cache-apt-pkgs-action@latest
with:
packages: libgdm-dev libpam0g-dev
version: 1.0
- uses: actions/checkout@v3
- name: Go code sanity check
uses: canonical/desktop-engineering/gh-actions/go/code-sanity@main
Expand All @@ -23,6 +28,11 @@ jobs:
name: Tests
runs-on: ubuntu-latest
steps:
- name: Install dependencies
uses: awalsh128/cache-apt-pkgs-action@latest
with:
packages: libgdm-dev libpam0g-dev
version: 1.0
- uses: actions/checkout@v3
- uses: actions/setup-go@v4
with:
Expand Down
1 change: 1 addition & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ require (

require (
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/elliotchance/orderedmap/v2 v2.2.0 // indirect
github.com/fsnotify/fsnotify v1.6.0 // indirect
github.com/golang/protobuf v1.5.3 // indirect
github.com/hashicorp/hcl v1.0.0 // indirect
Expand Down
2 changes: 2 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,8 @@ github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46t
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/elliotchance/orderedmap/v2 v2.2.0 h1:7/2iwO98kYT4XkOjA9mBEIwvi4KpGB4cyHeOFOnj4Vk=
github.com/elliotchance/orderedmap/v2 v2.2.0/go.mod h1:85lZyVbpGaGvHvnKa7Qhx7zncAdBIBq6u56Hb1PRU5Q=
github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98=
Expand Down
121 changes: 121 additions & 0 deletions pam/pam-utils.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
#include "pam-utils.h"

#include <security/pam_appl.h>
#include <assert.h>

char *
argv_string_get (const char **argv, unsigned i)
{
return strdup (argv[i]);
}

char *
get_user (pam_handle_t *pamh, const char *prompt)
{
if (!pamh)
return NULL;
int pam_err = 0;
const char *user;

if ((pam_err = pam_get_user (pamh, &user, prompt)) != PAM_SUCCESS)
return NULL;
return strdup (user);
}

const char *
get_module_name (pam_handle_t *pamh)
{
const char *module_name;

if (pam_get_item (pamh, PAM_SERVICE, (const void **) &module_name) != PAM_SUCCESS)
return NULL;

return module_name;
}

static struct pam_response *
send_msg_generic (pam_handle_t *pamh, const struct pam_message *pam_msg)
{
const struct pam_conv *pc;
struct pam_response *resp;

if (pam_get_item (pamh, PAM_CONV, (const void **) &pc) != PAM_SUCCESS)
return NULL;

if (!pc || !pc->conv)
return NULL;

if (pc->conv (1, (const struct pam_message *[]){ pam_msg }, &resp,
pc->appdata_ptr) != PAM_SUCCESS)
return NULL;

return resp;
}

struct pam_response *
send_msg (pam_handle_t *pamh, const char *msg, int style)
{
const struct pam_message pam_msg = {
.msg_style = style,
.msg = msg,
};

return send_msg_generic (pamh, &pam_msg);
}

GdmPamExtensionChoiceListRequest *
gdm_choices_request_create (const char *title,
size_t num)
{
GdmPamExtensionChoiceListRequest *request;

request = calloc (1, GDM_PAM_EXTENSION_CHOICE_LIST_REQUEST_SIZE (num));
GDM_PAM_EXTENSION_CHOICE_LIST_REQUEST_INIT (request, (char *) title, num);

return request;
}

void
gdm_choices_request_set (GdmPamExtensionChoiceListRequest *request, size_t i,
const char *key, const char *text)
{
assert (request != NULL && i < request->list.number_of_items);

request->list.items[i].key = strdup (key);
request->list.items[i].text = strdup (text);
}

void
gdm_choices_request_free (GdmPamExtensionChoiceListRequest *request)
{
assert (request != NULL);

for (size_t i = 0; i < request->list.number_of_items; ++i)
{
free ((char *) request->list.items[i].key);
free ((char *) request->list.items[i].text);
}

free (request);
}

char *
gdm_choices_request_ask (pam_handle_t *pamh, GdmPamExtensionChoiceListRequest *request)
{
GdmPamExtensionChoiceListResponse *response;
struct pam_message prompt_message;
struct pam_response *reply;
char *ret_key;

GDM_PAM_EXTENSION_MESSAGE_TO_BINARY_PROMPT_MESSAGE (request, &prompt_message);
reply = send_msg_generic (pamh, &prompt_message);

if (!reply)
return NULL;

response = GDM_PAM_EXTENSION_REPLY_TO_CHOICE_LIST_RESPONSE (reply);
ret_key = strdup (response->key);
free (response);

return ret_key;
}
37 changes: 37 additions & 0 deletions pam/pam-utils.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>
#include <unistd.h>
#include <gdm/gdm-pam-extensions.h>
#include <security/pam_modules.h>

char *argv_string_get (const char **argv,
unsigned i);

char *get_user (pam_handle_t *pamh,
const char *prompt);

const char *get_module_name (pam_handle_t *pamh);

struct pam_response *send_msg (pam_handle_t *pamh,
const char *msg,
int style);

inline bool
gdm_choices_list_supported (void)
{
return GDM_PAM_EXTENSION_SUPPORTED (GDM_PAM_EXTENSION_CHOICE_LIST);
}

GdmPamExtensionChoiceListRequest *gdm_choices_request_create (const char *,
size_t);

void gdm_choices_request_set (GdmPamExtensionChoiceListRequest *,
size_t i,
const char *key,
const char *value);

char * gdm_choices_request_ask (pam_handle_t *pamh,
GdmPamExtensionChoiceListRequest *);

void gdm_choices_request_free (GdmPamExtensionChoiceListRequest *);
Loading
Loading