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

Last change on this file since 2995 was 2995, checked in by Sam Hocevar, 12 years ago

Port neercs to the unified libcaca 0.99.beta15 API.

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