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

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