source: trunk/tools/neercs/old/lock.c @ 1656

Last change on this file since 1656 was 1656, checked in by sam, 7 years ago

neercs: start porting the old code to Windows; this breaks the Visual Studio
build until further fixes are made.

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