source: neercs/trunk/src/lock.c @ 4794

Last change on this file since 4794 was 4794, checked in by Pascal Terjan, 10 years ago

Test pam_misc.h location instead of checking for OSX

  • Property svn:keywords set to Id
File size: 5.6 KB
Line 
1/*
2 *  neercs        console-based window manager
3 *  Copyright (c) 2006-2010 Sam Hocevar <sam@hocevar.net>
4 *                2008-2010 Jean-Yves Lamoureux <jylam@lnxscene.org>
5 *                All Rights Reserved
6 *
7 *  This program is free software. It comes without any warranty, to
8 *  the extent permitted by applicable law. You can redistribute it
9 *  and/or modify it under the terms of the Do What The Fuck You Want
10 *  To Public License, Version 2, as published by Sam Hocevar. See
11 *  http://sam.zoy.org/wtfpl/COPYING for more details.
12 */
13
14#include "config.h"
15
16#include <stdio.h>
17#include <stdlib.h>
18#include <string.h>
19#include <caca.h>
20#include <time.h>
21#include <sys/wait.h>
22#include <sys/types.h>
23
24#if defined USE_LOCK
25#if defined HAVE_PAM_PAM_MISC_H
26#   include <pam/pam_appl.h>
27#   include <pam/pam_misc.h>
28#else
29#   include <security/pam_appl.h>
30#   include <security/pam_misc.h>
31#endif
32#   include <pwd.h>
33#endif
34
35#include "neercs.h"
36
37#if defined USE_LOCK
38static int convpam(int num_msg, const struct pam_message **msg,
39                   struct pam_response **resp, void *appdata_ptr);
40#endif
41
42int update_lock(int c, struct screen_list *screen_list)
43{
44    int refresh = 0;
45
46#if defined USE_LOCK
47    if (!screen_list->lock.locked)
48        return 0;
49
50    if (c == 0x08)              // BACKSPACE
51    {
52        if (screen_list->lock.lock_offset)
53        {
54            screen_list->lock.lockpass[screen_list->lock.lock_offset - 1] = 0;
55            screen_list->lock.lock_offset--;
56        }
57    }
58    else if (c == 0x0d)         // RETURN
59    {
60        memset(screen_list->lock.lockmsg, 0, 1024);
61        if (validate_lock(screen_list, getenv("USER"), screen_list->lock.lockpass))
62        {
63            memset(screen_list->lock.lockpass, 0, 1024);
64            screen_list->lock.locked = 0;
65            screen_list->lock.lock_offset = 0;
66            refresh = 1;
67        }
68        else
69        {
70            memset(screen_list->lock.lockpass, 0, 1024);
71            screen_list->lock.lock_offset = 0;
72            refresh = 1;
73        }
74    }
75    else
76    {
77        if (screen_list->lock.lock_offset < 1023)
78        {
79            screen_list->lock.lockpass[screen_list->lock.lock_offset++] = c;
80            screen_list->lock.lockpass[screen_list->lock.lock_offset] = 0;
81        }
82    }
83#endif
84
85    return refresh;
86}
87
88void draw_lock(struct screen_list *screen_list)
89{
90#if defined USE_LOCK
91    unsigned int i;
92    char buffer[1024];
93    caca_canvas_t *cv = screen_list->cv;
94
95    gethostname(buffer, sizeof(buffer) - 1);
96
97    int w = 65, h = 20;
98    int x = (caca_get_canvas_width(cv) - w) / 2;
99    int y = (caca_get_canvas_height(cv) - h) / 2;
100
101
102    caca_set_color_ansi(cv, CACA_BLUE, CACA_BLUE);
103    caca_fill_box(cv, x, y, w, h, '#');
104    caca_set_color_ansi(cv, CACA_DEFAULT, CACA_BLUE);
105    caca_draw_cp437_box(cv, x, y, w, h);
106
107    x += 2;
108    y++;
109    caca_printf(cv,
110                (caca_get_canvas_width(cv) -
111                 strlen(PACKAGE_STRING " locked")) / 2, y - 1,
112                PACKAGE_STRING " locked");
113
114    caca_printf(cv, x, y++, "Please type in your password for %s@%s :",
115                getenv("USER"), buffer);
116    y += 2;
117
118    x = (caca_get_canvas_width(cv) / 2) -
119        ((strlen(screen_list->lock.lockpass) / 2) + strlen("Password : "));
120    caca_printf(cv, x, y, "Password : ");
121    x += strlen("Password : ");
122    for (i = 0; i < strlen(screen_list->lock.lockpass); i++)
123    {
124        caca_put_str(cv, x, y, "*");
125        x++;
126    }
127
128
129    if (strlen(screen_list->lock.lockmsg))
130    {
131        x = ((caca_get_canvas_width(cv) - w) / 2) +
132            (strlen(screen_list->lock.lockmsg));
133        y += 2;
134        caca_set_color_ansi(cv, CACA_RED, CACA_BLUE);
135        caca_printf(cv, x, y, "Error : %s", screen_list->lock.lockmsg);
136    }
137#endif
138}
139
140
141#if defined USE_LOCK
142
143/* FIXME, handle this without assuming this is a password auth */
144static int convpam(int num_msg, const struct pam_message **msg,
145                   struct pam_response **resp, void *appdata_ptr)
146{
147
148    struct pam_response *aresp;
149    int i;
150    aresp = calloc(num_msg, sizeof(*aresp));
151
152    for (i = 0; i < num_msg; ++i)
153    {
154        switch (msg[i]->msg_style)
155        {
156        case PAM_PROMPT_ECHO_ON:
157        case PAM_PROMPT_ECHO_OFF:
158            aresp[i].resp = strdup(appdata_ptr);
159            aresp[i].resp_retcode = 0;
160            break;
161        case PAM_ERROR_MSG:
162            break;
163        default:
164            printf("Unknow message type from PAM\n");
165            break;
166        }
167    }
168
169    *resp = aresp;
170    return (PAM_SUCCESS);
171}
172#endif
173
174int validate_lock(struct screen_list *screen_list, char *user, char *pass)
175{
176#if USE_LOCK
177    int ret;
178    pam_handle_t *pamh = NULL;
179    char buffer[100];
180    const char *service = "neercs";
181    struct pam_conv conv = {
182        convpam,
183        pass,
184    };
185
186    ret = pam_start(service, user, &conv, &pamh);
187    if (ret != PAM_SUCCESS)
188        return 0;
189    pam_set_item(pamh, PAM_RUSER, user);
190
191    ret = gethostname(buffer, sizeof(buffer) - 1);
192    if (ret)
193    {
194        perror("failed to look up hostname");
195        ret = pam_end(pamh, PAM_ABORT);
196        sprintf(screen_list->lock.lockmsg, "Can't get hostname");
197        pam_end(pamh, PAM_SUCCESS);
198        return 0;
199    }
200
201    ret = pam_set_item(pamh, PAM_RHOST, buffer);
202    if (ret != PAM_SUCCESS)
203    {
204        sprintf(screen_list->lock.lockmsg, "Can't set hostname");
205        pam_end(pamh, PAM_SUCCESS);
206        return 0;
207    }
208
209    ret = pam_authenticate(pamh, 0);
210    if (ret != PAM_SUCCESS)
211    {
212        sprintf(screen_list->lock.lockmsg, "Can't authenticate");
213        pam_end(pamh, PAM_SUCCESS);
214        return 0;
215    }
216
217    ret = pam_end(pamh, PAM_SUCCESS);
218#endif
219
220    return 1;
221}
Note: See TracBrowser for help on using the repository browser.