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

Last change on this file since 2580 was 2580, checked in by bsittler, 13 years ago

OS X compilation fixes

File size: 5.5 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#if defined(__APPLE__)
28#   include <pam/pam_appl.h>
29#   include <pam/pam_misc.h>
30#else
31#   include <security/pam_appl.h>
32#   include <security/pam_misc.h>
33#endif
34#   include <pwd.h>
35#endif
36
37#include "neercs.h"
38
39#if defined USE_LOCK
40static int convpam(int num_msg, const struct pam_message **msg,
41                   struct pam_response **resp, void *appdata_ptr);
42#endif
43
44int update_lock(int c, struct screen_list *screen_list)
45{
46    int refresh = 0;
47
48#if defined USE_LOCK
49    if(!screen_list->locked) return 0;
50
51    if(c==0x08)      // BACKSPACE
52    {
53        if(screen_list->lock_offset)
54        {
55            screen_list->lockpass[screen_list->lock_offset-1] = 0;
56            screen_list->lock_offset--;
57        }
58    }
59    else if(c==0x0d) // RETURN
60    {
61        memset(screen_list->lockmsg, 0, 1024);
62        if(validate_lock(screen_list, getenv("USER"), screen_list->lockpass))
63        {
64            memset(screen_list->lockpass, 0, 1024);
65            screen_list->locked = 0;
66            screen_list->lock_offset = 0;
67            refresh = 1;
68        }
69        else
70        {
71            memset(screen_list->lockpass, 0, 1024);
72            screen_list->lock_offset = 0;
73            refresh = 1;
74        }
75    }
76    else
77    {
78        if(screen_list->lock_offset < 1023)
79        {
80            screen_list->lockpass[screen_list->lock_offset++] = c;
81            screen_list->lockpass[screen_list->lock_offset]   = 0;
82        }
83    }
84#endif
85
86    return refresh;
87}
88
89void draw_lock(struct screen_list *screen_list)
90{
91#if defined USE_LOCK
92    unsigned int i;
93    char buffer[1024];
94    cucul_canvas_t *cv = screen_list->cv;
95
96    gethostname(buffer, sizeof(buffer)-1);
97
98    int w = 65, h = 20;
99    int x = (cucul_get_canvas_width(cv) - w) / 2;
100    int y = (cucul_get_canvas_height(cv) - h) / 2;
101
102
103    cucul_set_color_ansi(cv, CUCUL_BLUE, CUCUL_BLUE);
104    cucul_fill_box(cv,
105                   x, y,
106                   w, h, '#');
107    cucul_set_color_ansi(cv, CUCUL_DEFAULT, CUCUL_BLUE);
108    cucul_draw_cp437_box(cv,
109                         x, y,
110                         w, h);
111
112    x+=2;
113    y++;
114    cucul_printf(cv,
115                 (cucul_get_canvas_width(cv) - strlen(PACKAGE_STRING " locked")) / 2,
116                 y-1,
117                 PACKAGE_STRING " locked");
118
119    cucul_printf(cv, x, y++, "Please type in your password for %s@%s :", getenv("USER"), buffer);
120    y+=2;
121
122    x = (cucul_get_canvas_width(cv)/2) - ((strlen(screen_list->lockpass) / 2) + strlen("Password : "));
123    cucul_printf(cv, x, y, "Password : ");
124    x+=strlen("Password : ");
125    for(i=0; i<strlen(screen_list->lockpass); i++)
126    {
127        cucul_put_str(cv, x, y, "*");
128        x++;
129    }
130
131
132    if(strlen(screen_list->lockmsg))
133    {
134        x = ((cucul_get_canvas_width(cv) - w) / 2) + (strlen(screen_list->lockmsg));
135        y+=2;
136        cucul_set_color_ansi(cv, CUCUL_RED, CUCUL_BLUE);
137        cucul_printf(cv, x, y, "Error : %s", screen_list->lockmsg);
138    }
139#endif
140}
141
142
143#if defined USE_LOCK
144
145/* FIXME, handle this without assuming this is a password auth */
146static int convpam(int num_msg, const struct pam_message **msg,
147                   struct pam_response **resp, void *appdata_ptr)
148{
149
150    struct pam_response *aresp;
151    int i;
152    aresp = calloc(num_msg, sizeof(*aresp));
153
154    for (i = 0; i < num_msg; ++i)
155    {
156        switch(msg[i]->msg_style)
157        {
158        case PAM_PROMPT_ECHO_ON:
159        case PAM_PROMPT_ECHO_OFF:
160            aresp[i].resp = strdup(appdata_ptr);
161            aresp[i].resp_retcode = 0;
162            break;
163        case PAM_ERROR_MSG:
164            break;
165        default :
166            printf("Unknow message type from PAM\n");
167            break;
168        }
169    }
170
171    *resp = aresp;
172    return (PAM_SUCCESS);
173}
174#endif
175
176int validate_lock(struct screen_list *screen_list, char *user, char *pass)
177{
178#if USE_LOCK
179    int ret;
180    pam_handle_t *pamh=NULL;
181    char buffer[100];
182    const char *service="neercs";
183    struct pam_conv conv = {
184        convpam,
185        pass,
186    };
187
188    ret = pam_start(service, user, &conv, &pamh);
189    if(ret!=PAM_SUCCESS)
190        return 0;
191    pam_set_item(pamh, PAM_RUSER, user);
192
193    ret = gethostname(buffer, sizeof(buffer)-1);
194    if (ret)
195    {
196        perror("failed to look up hostname");
197        ret = pam_end(pamh, PAM_ABORT);
198        sprintf(screen_list->lockmsg, "Can't get hostname");
199        pam_end(pamh, PAM_SUCCESS);
200        return 0;
201    }
202
203    ret = pam_set_item(pamh, PAM_RHOST, buffer);
204    if(ret!=PAM_SUCCESS)
205    {
206        sprintf(screen_list->lockmsg, "Can't set hostname");
207        pam_end(pamh, PAM_SUCCESS);
208        return 0;
209    }
210
211    ret = pam_authenticate(pamh, 0);
212    if(ret!=PAM_SUCCESS)
213    {
214        sprintf(screen_list->lockmsg, "Can't authenticate");
215        pam_end(pamh, PAM_SUCCESS);
216        return 0;
217    }
218
219    ret = pam_end(pamh, PAM_SUCCESS);
220#endif
221
222    return 1;
223}
224
Note: See TracBrowser for help on using the repository browser.