"Fossies" - the Fresh Open Source Software Archive

Member "jpilot-2_0_1/password.c" (3 Apr 2021, 10509 Bytes) of package /linux/privat/jpilot-2_0_1.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "password.c" see the Fossies "Dox" file reference documentation and the latest Fossies "Diffs" side-by-side code changes report: 1.8.2_vs_2_0_1.

    1 /*******************************************************************************
    2  * password.c
    3  * A module of J-Pilot http://jpilot.org
    4  *
    5  * Copyright (C) 1999-2014 by Judd Montgomery
    6  *
    7  * This program is free software; you can redistribute it and/or modify
    8  * it under the terms of the GNU General Public License as published by
    9  * the Free Software Foundation; version 2 of the License.
   10  *
   11  * This program is distributed in the hope that it will be useful,
   12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
   13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   14  * GNU General Public License for more details.
   15  *
   16  * You should have received a copy of the GNU General Public License
   17  * along with this program; if not, write to the Free Software
   18  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
   19  ******************************************************************************/
   20 
   21 /********************************* Includes ***********************************/
   22 #include "config.h"
   23 #include <gtk/gtk.h>
   24 #include <stdio.h>
   25 #include <string.h>
   26 #include <stdlib.h>
   27 #include <ctype.h>
   28 
   29 #include <pi-version.h>
   30 #include <pi-md5.h>
   31 
   32 #include "password.h"
   33 #include "i18n.h"
   34 #include "prefs.h"
   35 
   36 #ifdef ENABLE_PRIVATE
   37 
   38 /********************************* Constants **********************************/
   39 #define DIALOG_SAID_1  454
   40 #define DIALOG_SAID_2  455
   41 
   42 /******************************* Global vars **********************************/
   43 static unsigned char short_salt[]=
   44 {
   45    0x09, 0x02, 0x13, 0x45, 0x07, 0x04, 0x13, 0x44,
   46    0x0C, 0x08, 0x13, 0x5A, 0x32, 0x15, 0x13, 0x5D,
   47    0xD2, 0x17, 0xEA, 0xD3, 0xB5, 0xDF, 0x55, 0x63,
   48    0x22, 0xE9, 0xA1, 0x4A, 0x99, 0x4B, 0x0F, 0x88
   49 };
   50 static unsigned char long_salt[]=
   51 {
   52    0xB1, 0x56, 0x35, 0x1A, 0x9C, 0x98, 0x80, 0x84,
   53    0x37, 0xA7, 0x3D, 0x61, 0x7F, 0x2E, 0xE8, 0x76,
   54    0x2A, 0xF2, 0xA5, 0x84, 0x07, 0xC7, 0xEC, 0x27,
   55    0x6F, 0x7D, 0x04, 0xCD, 0x52, 0x1E, 0xCD, 0x5B,
   56    0xB3, 0x29, 0x76, 0x66, 0xD9, 0x5E, 0x4B, 0xCA,
   57    0x63, 0x72, 0x6F, 0xD2, 0xFD, 0x25, 0xE6, 0x7B,
   58    0xC5, 0x66, 0xB3, 0xD3, 0x45, 0x9A, 0xAF, 0xDA,
   59    0x29, 0x86, 0x22, 0x6E, 0xB8, 0x03, 0x62, 0xBC
   60 };
   61 
   62 /****************************** Prototypes ************************************/
   63 struct dialog_data {
   64    GtkWidget *entry;
   65    int button_hit;
   66    char text[PASSWD_LEN+2];
   67 };
   68 
   69 /****************************** Main Code *************************************/
   70 /* len is the length of the bin str, hex_str must be at least twice as long */
   71 void bin_to_hex_str(unsigned char *bin, char *hex_str, int len)
   72 {
   73    int i;
   74    hex_str[0]='\0';
   75    for (i=0; i<len; i++) {
   76       sprintf(&(hex_str[i*2]), "%02x", bin[i]);
   77    }
   78 }
   79 
   80 /*
   81  * encoded is a pre-allocated buffer at least 34 bytes long
   82  *
   83  * This is the hashing algorithm used in palm OS < 4.0.
   84  * It is not very secure and is reversible.
   85  */
   86 static void palm_encode_hash(unsigned char *ascii, unsigned char *encoded)
   87 {
   88    unsigned char index, shift;
   89    unsigned short temp;
   90    int si, ai, ei; /* salt i, ascii i, encoded i */
   91    int end;
   92    int len;
   93    int m_array[4]={2,16,24,8};
   94    int mi;
   95    int m;
   96 
   97    encoded[0]='\0';
   98    end=0;
   99    if (strlen((char *)ascii)<5) {
  100       si = (ascii[0] + strlen((char*)ascii)) % PASSWD_LEN;
  101       for (ai=ei=0; ei<32; ai++, ei++, si++) {
  102          if (ascii[ai]=='\0') {
  103             end=1;
  104          }
  105          if (end) {
  106             encoded[ei]=short_salt[si%PASSWD_LEN];
  107          } else {
  108             encoded[ei]=ascii[ai] ^ short_salt[si%PASSWD_LEN];
  109          }
  110       }
  111       return;
  112    }
  113 
  114    g_strlcpy((char *)encoded, (char *)ascii, PASSWD_LEN);
  115    len = strlen((char *)encoded);
  116    for (ai=len; ai < PASSWD_LEN; ai++) {
  117       encoded[ai] = encoded[ai-len] + len;
  118    }
  119 
  120    for (mi=0; mi<4; mi++) {
  121       m=m_array[mi];
  122       index = (encoded[m] + encoded[m+1]) & 0x3F;
  123       shift = (encoded[m+2] + encoded[m+3]) & 0x7;
  124       for (ei=0; ei<PASSWD_LEN; ei++) {
  125          temp = long_salt[index%64];
  126          temp <<= 8;
  127          temp |= long_salt[index%64];
  128          temp >>= shift;
  129          encoded[m%32] ^= temp & 0xFF;
  130          m++;
  131          index++;
  132       }
  133    }
  134 }
  135 
  136 /*
  137  * encoded is a pre-allocated buffer at least 16 bytes long
  138  *
  139  * This is the hashing algorithm used in palm OS >= 4.0.
  140  * Its just a plain ole' MD5.
  141  */
  142 static void palm_encode_md5(unsigned char *ascii, unsigned char *encoded)
  143 {
  144    struct MD5Context m;
  145    unsigned char digest[20];
  146 
  147    MD5Init(&m);
  148    MD5Update(&m, ascii, strlen((char *)ascii));
  149    MD5Final(digest, &m);
  150 
  151    memcpy(encoded, digest, 16);
  152 }
  153 
  154 #endif
  155 
  156 int verify_password(char *password)
  157 {
  158    int i;
  159 #ifdef ENABLE_PRIVATE
  160    unsigned char encoded[34];
  161    unsigned char password_lower[PASSWD_LEN+2];
  162    const char *pref_password;
  163    char hex_str[68];
  164 #endif
  165 
  166 #ifdef ENABLE_PRIVATE
  167    if (!password) {
  168       return FALSE;
  169    }
  170 
  171    /* The Palm OS lower cases the password first */
  172    /* Yes, I have found this documented on Palm's website */
  173    for (i=0; i < PASSWD_LEN; i++) {
  174       password_lower[i] = tolower(password[i]);
  175    }
  176 
  177    /* Check to see that the password matches */
  178    palm_encode_hash(password_lower, encoded);
  179    bin_to_hex_str(encoded, hex_str, PASSWD_LEN);
  180    get_pref(PREF_PASSWORD, NULL, &pref_password);
  181    if (!strcmp(hex_str, pref_password)) {
  182       return TRUE;
  183    }
  184 
  185    /* The Password didn't match.
  186     * It could also be an MD5 password.
  187     * Try that now.  */
  188    palm_encode_md5((unsigned char *)password, encoded);
  189    bin_to_hex_str(encoded, hex_str, PASSWD_LEN);
  190    hex_str[PASSWD_LEN]='\0';
  191    get_pref(PREF_PASSWORD, NULL, &pref_password);
  192    if (!strcmp(hex_str, pref_password)) {
  193       return TRUE;
  194    }
  195    return FALSE;
  196 #else
  197    /* Return TRUE without checking the password */
  198    return TRUE;
  199 #endif
  200 }
  201 
  202 /*
  203  * hide passed HIDE_PRIVATES, SHOW_PRIVATES or MASK_PRIVATES will set the flag.
  204  * hide passed GET_PRIVATES will return the current hide flag.
  205  * hide flag is always returned.
  206  */
  207 int show_privates(int hide)
  208 {
  209 #ifdef ENABLE_PRIVATE
  210    static int hidden=HIDE_PRIVATES;
  211 #else
  212    static int hidden=SHOW_PRIVATES;
  213 #endif
  214 
  215    if (hide != GET_PRIVATES)
  216       hidden = hide;
  217 
  218    return hidden;
  219 }
  220 
  221 #ifdef ENABLE_PRIVATE
  222 /*
  223  * PASSWORD GUI
  224  */
  225 /* Start of Dialog window code */
  226 static void cb_dialog_button(GtkWidget *widget,
  227                                gpointer   data)
  228 {
  229    struct dialog_data *Pdata;
  230    GtkWidget *w;
  231 
  232    w = gtk_widget_get_toplevel(widget);
  233 
  234    Pdata =  g_object_get_data(G_OBJECT(w), "dialog_data");
  235    if (Pdata) {
  236       Pdata->button_hit = GPOINTER_TO_INT(data);
  237    }
  238    gtk_widget_destroy(GTK_WIDGET(w));
  239 }
  240 
  241 static gboolean cb_destroy_dialog(GtkWidget *widget)
  242 {
  243    struct dialog_data *Pdata;
  244    const char *entry;
  245 
  246    Pdata =  g_object_get_data(G_OBJECT(widget), "dialog_data");
  247    if (!Pdata) {
  248       return TRUE;
  249    }
  250    entry = gtk_entry_get_text(GTK_ENTRY(Pdata->entry));
  251 
  252    if (entry) {
  253       g_strlcpy(Pdata->text, entry, PASSWD_LEN+1);
  254    }
  255 
  256    gtk_main_quit();
  257 
  258    return TRUE;
  259 }
  260 
  261 /*
  262  * returns 1 if cancel was pressed, 2 if OK was hit
  263  */
  264 int dialog_password(GtkWindow *main_window, char *ascii_password, int retry)
  265 {
  266    GtkWidget *button, *label;
  267    GtkWidget *hbox1, *vbox1;
  268    GtkWidget *dialog;
  269    GtkWidget *entry;
  270    struct dialog_data Pdata;
  271    int ret;
  272 
  273    if (!ascii_password) {
  274       return EXIT_FAILURE;
  275    }
  276    ascii_password[0]='\0';
  277    ret = 2;
  278 
  279    dialog = gtk_widget_new(GTK_TYPE_WINDOW,
  280                            "type", GTK_WINDOW_TOPLEVEL,
  281                            "title", _("Palm Password"),
  282                            NULL);
  283 
  284    gtk_window_set_position(GTK_WINDOW(dialog), GTK_WIN_POS_MOUSE);
  285    gtk_window_set_modal(GTK_WINDOW(dialog), TRUE);
  286    gtk_window_set_transient_for(GTK_WINDOW(dialog), GTK_WINDOW(main_window));
  287 
  288    g_signal_connect(G_OBJECT(dialog), "destroy",
  289                       G_CALLBACK(cb_destroy_dialog), dialog);
  290 
  291    hbox1 = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 2);
  292    gtk_container_add(GTK_CONTAINER(dialog), hbox1);
  293    gtk_box_pack_start(GTK_BOX(hbox1), gtk_image_new_from_icon_name("dialog-password", GTK_ICON_SIZE_DIALOG), FALSE, FALSE, 2);
  294 
  295    vbox1 = gtk_box_new(GTK_ORIENTATION_VERTICAL, 2);
  296    gtk_container_set_border_width(GTK_CONTAINER(vbox1), 5);
  297 
  298    gtk_container_add(GTK_CONTAINER(hbox1), vbox1);
  299 
  300    hbox1 = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 2);
  301    gtk_container_set_border_width(GTK_CONTAINER(hbox1), 5);
  302    gtk_box_pack_start(GTK_BOX(vbox1), hbox1, FALSE, FALSE, 2);
  303 
  304    /* Instruction label */
  305    if (retry) {
  306       label = gtk_label_new(_("Incorrect, Reenter PalmOS Password"));
  307    } else {
  308       label = gtk_label_new(_("Enter PalmOS Password"));
  309    }
  310    gtk_box_pack_start(GTK_BOX(hbox1), label, FALSE, FALSE, 2);
  311 
  312    /* Password entry field */
  313    entry = gtk_entry_new();
  314    gtk_entry_set_max_length(GTK_ENTRY(entry), PASSWD_LEN);
  315    gtk_entry_set_visibility(GTK_ENTRY(entry), FALSE);
  316    g_signal_connect(G_OBJECT(entry), "activate",
  317                       G_CALLBACK(cb_dialog_button),
  318                       GINT_TO_POINTER(DIALOG_SAID_2));
  319    gtk_box_pack_start(GTK_BOX(hbox1), entry, TRUE, TRUE, 1);
  320 
  321    /* Button Box */
  322    hbox1 = gtk_button_box_new(GTK_ORIENTATION_HORIZONTAL);
  323    gtk_button_box_set_layout(GTK_BUTTON_BOX (hbox1), GTK_BUTTONBOX_END);
  324     gtk_box_set_spacing(GTK_BOX(hbox1), 6);
  325    gtk_container_set_border_width(GTK_CONTAINER(hbox1), 5);
  326    gtk_box_pack_start(GTK_BOX(vbox1), hbox1, FALSE, FALSE, 2);
  327 
  328    /* Cancel Button */
  329    button = gtk_button_new_with_label("Cancel");
  330    g_signal_connect(G_OBJECT(button), "clicked",
  331                       G_CALLBACK(cb_dialog_button),
  332                       GINT_TO_POINTER(DIALOG_SAID_1));
  333    gtk_box_pack_start(GTK_BOX(hbox1), button, FALSE, FALSE, 1);
  334 
  335    /* OK Button */
  336    button = gtk_button_new_with_label("OK");
  337    g_signal_connect(G_OBJECT(button), "clicked",
  338                       G_CALLBACK(cb_dialog_button),
  339                       GINT_TO_POINTER(DIALOG_SAID_2));
  340    gtk_box_pack_start(GTK_BOX(hbox1), button, FALSE, FALSE, 1);
  341    gtk_widget_set_can_default(button,TRUE);
  342    gtk_widget_grab_default(button);
  343 
  344    /* Set the default button pressed to CANCEL */
  345    Pdata.button_hit = DIALOG_SAID_1;
  346    Pdata.entry=entry;
  347    Pdata.text[0]='\0';
  348     g_object_set_data(G_OBJECT(dialog), "dialog_data", &Pdata);
  349 
  350    gtk_widget_grab_focus(GTK_WIDGET(entry));
  351 
  352    gtk_widget_show_all(dialog);
  353 
  354    gtk_main();
  355 
  356    if (Pdata.button_hit==DIALOG_SAID_1) {
  357       ret = 1;
  358    }
  359    if (Pdata.button_hit==DIALOG_SAID_2) {
  360       ret = 2;
  361    }
  362    g_strlcpy(ascii_password, Pdata.text, PASSWD_LEN+1);
  363 
  364    return ret;
  365 }
  366 #endif
  367