/*
 * Update the visible key list.
 */
void keylist_update(void)
{
    struct RSAKey *rkey;
    struct ssh2_userkey *skey;
    int i;

    if (keylist) {
	SendDlgItemMessage(keylist, 100, LB_RESETCONTENT, 0, 0);
	for (i = 0; NULL != (rkey = pageant_nth_ssh1_key(i)); i++) {
	    char listentry[512], *p;
	    /*
	     * Replace two spaces in the fingerprint with tabs, for
	     * nice alignment in the box.
	     */
	    strcpy(listentry, "ssh1\t");
	    p = listentry + strlen(listentry);
	    rsa_fingerprint(p, sizeof(listentry) - (p - listentry), rkey);
	    p = strchr(listentry, ' ');
	    if (p)
		*p = '\t';
	    p = strchr(listentry, ' ');
	    if (p)
		*p = '\t';
	    SendDlgItemMessage(keylist, 100, LB_ADDSTRING,
			       0, (LPARAM) listentry);
	}
	for (i = 0; NULL != (skey = pageant_nth_ssh2_key(i)); i++) {
	    char *listentry, *p;
	    int pos;
	    /*
	     * Replace spaces with tabs in the fingerprint prefix, for
	     * nice alignment in the list box, until we encounter a :
	     * meaning we're into the fingerprint proper.
	     */
	    p = ssh2_fingerprint(skey->alg, skey->data);
            listentry = dupprintf("%s\t%s", p, skey->comment);
            sfree(p);

            pos = 0;
            while (1) {
                pos += strcspn(listentry + pos, " :");
                if (listentry[pos] == ':' || !listentry[pos])
                    break;
                listentry[pos++] = '\t';
            }

	    SendDlgItemMessage(keylist, 100, LB_ADDSTRING, 0,
			       (LPARAM) listentry);
            sfree(listentry);
	}
	SendDlgItemMessage(keylist, 100, LB_SETCURSEL, (WPARAM) - 1, 0);
    }
}
Beispiel #2
0
/*
 * Dialog-box function for the key list box.
 */
static INT_PTR CALLBACK KeyListProc(HWND hwnd,
                                    UINT msg,
                                    WPARAM wParam,
                                    LPARAM lParam)
{
  struct RSAKey *rkey;
  struct ssh2_userkey *skey;

  switch (msg) {
  case WM_INITDIALOG:
    /*
     * Centre the window.
     */
    { /* centre the window */
      RECT rs, rd;
      HWND hw;

      hw = GetDesktopWindow();
      if (GetWindowRect(hw, &rs) && GetWindowRect(hwnd, &rd))
        MoveWindow(hwnd,
                   (rs.right + rs.left + rd.left - rd.right) / 2,
                   (rs.bottom + rs.top + rd.top - rd.bottom) / 2,
                   rd.right - rd.left,
                   rd.bottom - rd.top,
                   TRUE);
    }

    if (has_help())
      SetWindowLongPtr(hwnd,
                       GWL_EXSTYLE,
                       GetWindowLongPtr(hwnd, GWL_EXSTYLE) | WS_EX_CONTEXTHELP);
    else {
      HWND item = GetDlgItem(hwnd, 103); /* the Help button */
      if (item)
        DestroyWindow(item);
    }

    keylist = hwnd;
    {
      static int tabs[] = {35, 75, 250};
      SendDlgItemMessage(hwnd,
                         100,
                         LB_SETTABSTOPS,
                         sizeof(tabs) / sizeof(*tabs),
                         (LPARAM)tabs);
    }
    keylist_update();
    return 0;
  case WM_COMMAND:
    switch (LOWORD(wParam)) {
    case IDOK:
    case IDCANCEL:
      keylist = NULL;
      DestroyWindow(hwnd);
      return 0;
    case 101: /* add key */
      if (HIWORD(wParam) == BN_CLICKED || HIWORD(wParam) == BN_DOUBLECLICKED) {
        if (passphrase_box) {
          MessageBeep(MB_ICONERROR);
          SetForegroundWindow(passphrase_box);
          break;
        }
        prompt_add_keyfile();
      }
      return 0;
    case 102: /* remove key */
      if (HIWORD(wParam) == BN_CLICKED || HIWORD(wParam) == BN_DOUBLECLICKED) {
        int i;
        int rCount, sCount;
        int *selectedArray;

        /* our counter within the array of selected items */
        int itemNum;

        /* get the number of items selected in the list */
        int numSelected = SendDlgItemMessage(hwnd, 100, LB_GETSELCOUNT, 0, 0);

        /* none selected? that was silly */
        if (numSelected == 0) {
          MessageBeep(0);
          break;
        }

        /* get item indices in an array */
        selectedArray = snewn(numSelected, int);
        SendDlgItemMessage(
            hwnd, 100, LB_GETSELITEMS, numSelected, (WPARAM)selectedArray);

        itemNum = numSelected - 1;
        rCount = pageant_count_ssh1_keys();
        sCount = pageant_count_ssh2_keys();

        /* go through the non-rsakeys until we've covered them all,
         * and/or we're out of selected items to check. note that
         * we go *backwards*, to avoid complications from deleting
         * things hence altering the offset of subsequent items
         */
        for (i = sCount - 1; (itemNum >= 0) && (i >= 0); i--) {
          skey = pageant_nth_ssh2_key(i);

          if (selectedArray[itemNum] == rCount + i) {
            pageant_delete_ssh2_key(skey);
            skey->alg->freekey(skey->data);
            sfree(skey);
            itemNum--;
          }
        }

        /* do the same for the rsa keys */
        for (i = rCount - 1; (itemNum >= 0) && (i >= 0); i--) {
          rkey = pageant_nth_ssh1_key(i);

          if (selectedArray[itemNum] == i) {
            pageant_delete_ssh1_key(rkey);
            freersakey(rkey);
            sfree(rkey);
            itemNum--;
          }
        }

        sfree(selectedArray);
        keylist_update();
      }
      return 0;
    case 103: /* help */
      if (HIWORD(wParam) == BN_CLICKED || HIWORD(wParam) == BN_DOUBLECLICKED) {
        launch_help(hwnd, WINHELP_CTX_pageant_general);
      }
      return 0;
    }
    return 0;
  case WM_HELP: {
    int id = ((LPHELPINFO)lParam)->iCtrlId;
    const char *topic = NULL;
    switch (id) {
    case 100:
      topic = WINHELP_CTX_pageant_keylist;
      break;
    case 101:
      topic = WINHELP_CTX_pageant_addkey;
      break;
    case 102:
      topic = WINHELP_CTX_pageant_remkey;
      break;
    }
    if (topic) {
      launch_help(hwnd, topic);
    } else {
      MessageBeep(0);
    }
  } break;
  case WM_CLOSE:
    keylist = NULL;
    DestroyWindow(hwnd);
    return 0;
  }
Beispiel #3
0
/*
 * Update the visible key list.
 */
void keylist_update(void)
{
  struct RSAKey *rkey;
  struct ssh2_userkey *skey;
  int i;

  if (keylist) {
    SendDlgItemMessage(keylist, 100, LB_RESETCONTENT, 0, 0);
    for (i = 0; NULL != (rkey = pageant_nth_ssh1_key(i)); i++) {
      char listentry[512], *p;
      /*
       * Replace two spaces in the fingerprint with tabs, for
       * nice alignment in the box.
       */
      strcpy(listentry, "ssh1\t");
      p = listentry + strlen(listentry);
      rsa_fingerprint(p, sizeof(listentry) - (p - listentry), rkey);
      p = strchr(listentry, ' ');
      if (p)
        *p = '\t';
      p = strchr(listentry, ' ');
      if (p)
        *p = '\t';
      SendDlgItemMessage(keylist, 100, LB_ADDSTRING, 0, (LPARAM)listentry);
    }
    for (i = 0; NULL != (skey = pageant_nth_ssh2_key(i)); i++) {
      char *listentry, *p;
      int pos;

      /*
       * For nice alignment in the list box, we would ideally
       * want every entry to align to the tab stop settings, and
       * have a column for algorithm name, one for bit count,
       * one for hex fingerprint, and one for key comment.
       *
       * Unfortunately, some of the algorithm names are so long
       * that they overflow into the bit-count field.
       * Fortunately, at the moment, those are _precisely_ the
       * algorithm names that don't need a bit count displayed
       * anyway (because for NIST-style ECDSA the bit count is
       * mentioned in the algorithm name, and for ssh-ed25519
       * there is only one possible value anyway). So we fudge
       * this by simply omitting the bit count field in that
       * situation.
       *
       * This is fragile not only in the face of further key
       * types that don't follow this pattern, but also in the
       * face of font metrics changes - the Windows semantics
       * for list box tab stops is that \t aligns to the next
       * one you haven't already exceeded, so I have to guess
       * when the key type will overflow past the bit-count tab
       * stop and leave out a tab character. Urgh.
       */

      p = ssh2_fingerprint(skey->alg, skey->data);
      listentry = dupprintf("%s\t%s", p, skey->comment);
      sfree(p);

      pos = 0;
      while (1) {
        pos += strcspn(listentry + pos, " :");
        if (listentry[pos] == ':' || !listentry[pos])
          break;
        listentry[pos++] = '\t';
      }
      if (skey->alg != &ssh_dss && skey->alg != &ssh_rsa) {
        /*
         * Remove the bit-count field, which is between the
         * first and second \t.
         */
        int outpos;
        pos = 0;
        while (listentry[pos] && listentry[pos] != '\t')
          pos++;
        outpos = pos;
        pos++;
        while (listentry[pos] && listentry[pos] != '\t')
          pos++;
        while (1) {
          if ((listentry[outpos] = listentry[pos]) == '\0')
            break;
          outpos++;
          pos++;
        }
      }

      SendDlgItemMessage(keylist, 100, LB_ADDSTRING, 0, (LPARAM)listentry);
      sfree(listentry);
    }
    SendDlgItemMessage(keylist, 100, LB_SETCURSEL, (WPARAM)-1, 0);
  }
}