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

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