Showing posts with label Shortcuts. Show all posts
Showing posts with label Shortcuts. Show all posts

Wednesday, May 20, 2015

KeePass2 and Gmail

It's been a while since I posted, but with a good cause: We just had our second child a few weeks ago!

The other day, Google decided to change Gmail's login screen to be in three parts (two for those without two-step authentication): 1. Username 2. Password 3. Two-Step Authentication. This is annoying because I use KeePass2 with auto-type, and the new pages interfere with the auto-typing mechanism.

Today I decided to solve that issue, and I'm posting it here to share with anyone else who may also have the same problem. Here are the steps:

  1. Open up the Gmail or Google Apps email account you want to change ("Edit/View Entry" on the context menu, or hit Enter when the entry is selected).
  2. Go to the Auto-Type tab.
  3. Select "Override default sequence" option.
  4. The field should initial have (without quotes):

    "{USERNAME}{TAB}{PASSWORD}{ENTER}"

    Replace that with (without quotes):

    "{USERNAME}{TAB}{ENTER}{DELAY 2000}{PASSWORD}{TAB}{ENTER}"

  5. Test in your favorite browser. Adjust the "{DELAY mmmm}" parameter by replacing "mmmm" with a different numeric value. This is in milliseconds, so a value of 1000 is 1 second.

The "{DELAY 2000}" parameter is the key to fixing the issue. Since there is a new page in between the username and password, we need a delay to let the page load before typing the password.

For more information on the auto-type feature and the parameters that can be used, see the KeePass documentation here:

http://keepass.info/help/base/autotype.html

Don't forget to tag your Gmail account as an OpenSSL account (add "OpenSSL" to the description) while you're at it!

Friday, April 11, 2014

How I Reacted to Heartbleed



Recently a bug was revealed in OpenSSL, called Heartbleed. One of the very unfortunate aspects of this bug was the potential for all passwords and cryptographic keys on a server could have been dumped to any hacker who knew about the flaw. As users, we can't control the cryptographic keys; however, we can control our passwords.

I was able to quickly identify my key accounts at risk in order to reset each password. How? With a password management database, KeePass. I also had help from the well-documented Mashable article.

I have all of my passwords stored in a KeePass database. Each account is categorized into groups like Banking, Email, Investments, etc. (see screenshot above). Using the Mashable article, I edited the each description by adding "OpenSSL" for each account that used OpenSSL. I also ran a few online searches to determine the status of other accounts I wasn't sure about.

Once I finished that, I search through the entire database (over 240 passwords!!) for "OpenSSL" to list all the entries together. Starting with my financial accounts in Banking, Investments, and other categories, I changed each password, one-by-one.

It took about an hour, but who out there without a password management database can say they reset all their key accounts so quickly?

Now I'm not going to stop there. I'll be reseting some passwords once a week until I hear this issue is cleared up. (Thus entering "OpenSSL" permanently in each account description.) It's going to take time to re-issue those cryptographic keys and for all the certificate authorities to synchronize. For these important accounts, I don't want to risk losing control.

In the end, if you are a user of web services like me, start using a password management database right now. (I would not use LastPass since it is online. However, according to their documentation, they use forward secrecy, which is currently the best way to do these things and would prevent any true information leak.)

Start by entering your most important accounts and change the passwords to random passwords. Gradually add those you don't use as frequently or are not as important. Then set a schedule for each important password to expire on a regular basis: every 2 months, 6 months, or whatever you think is best for the account. My financial accounts are reset every 3-6 months.

Hopefully webmasters, server admins, cryptographers, and anyone else involved in this ecosystem starts to realize that we have a broken internet. Encryption technologies are failing and need a serious upgrade. In some places, we don't even have encryption, and it's harming trust. It's up to the gatekeepers to keep us safe and to promote trust - we users can only do so much.

Wednesday, January 29, 2014

Bad SQL Writing Put to Good Use

There's a certain style of writing SQL that I really don't like. Here's an example that pulls names and addresses for people in Wisconsin and Illinois:

select p.name, a.address
from person p, person_address pa, address a
where p.person_id = pa.person_id
and pa.address_id = a.address_id
and a.state in ('WI', 'IL')
;


Basically, the author has stacked all the tables into the FROM statement, and specified how they join on the WHERE statement. This creates confusion about how the tables are intended to be joined as well as mixing actual filter criteria with the join conditions. However, it works, since the code results in inner joins between all tables, and that was okay.

My preferred style is like so:

select p.name, a.address
from person p
left join person_address pa
on p.person_id = pa.person_id
inner join address a
on pa.address_id = a.address_id
where a.state in ('WI', 'IL')
;


It's a bit more verbose, but that helps the reader. This style splits out the tables into different statements and results in clearly indicated join types and join fields. It is clear to a reader of the code the intention of joining each table. The filter criteria are located in the WHERE statement without any other statements to confuse them with. There are still cases where the result may not be as expected based on the filter criteria, but it's easier to debug.

Overall, the first example is a confusing style to use, and it can cause trouble if the joins were intended to be outer joins and were not, because the style does not have a way to specify outer joins. (LEFT JOIN is short for LEFT OUTER JOIN, which means, basically, return all records from the first table, and any data that matches in the next without missing any records from the first.)

The other day, though, I encountered a great way to use this potentially error-prone style in a way that is actually very useful.

I wanted to generate a master list of all potential ZIP codes in the US, and then filter out ones that are not in use or are otherwise invalid. I started by creating a small table with 10 rows that consist of 1 column with the numbers 0-9.  With no loop statements available in SQL, I wrote this table like so:

create temporary table num (n int);
insert into num values (0);
insert into num select max(n)+1 from num;
insert into num select max(n)+1 from num;
insert into num select max(n)+1 from num;
insert into num select max(n)+1 from num;
insert into num select max(n)+1 from num;
insert into num select max(n)+1 from num;
insert into num select max(n)+1 from num;
insert into num select max(n)+1 from num;
insert into num select max(n)+1 from num;
insert into num select max(n)+1 from num;
delete from num where n > 9;


That last statement is just in case I ran it too many times. I was even too lazy to write out 1-9, instead just repeating the max+1 code 9 times. It's a bit over-the-top, but it works.

To get my "master" list of ZIP codes, I joined the table to itself 5 times, one for each character in the ZIP code (because they can start with 0s, they should be treated as characters, not numbers!). Here's how:

create table master_zip as
select n1.n||n2.n||n3.n||n4.n||n5.n as zip
from num n1, num n2, num n3, num n4, num n5
order by 1
;


Simple, isn't it? Essentially, this just makes a big Cartesian product of the table with itself times 4. There's no WHERE statement, because there's no need to join on anything. (If a system required it, I would just write "where 1=1".) This generates 100,000 records. That's about 58,000 too many, according the US Postal Service, so we need to delete some of those that are not in use. But that process is for another time.

Using a style that I usually do not recommend or warn against was interesting and useful, but it requires knowing a bit more about how these things work. Had I run this last bit of code on a larger data set, it would have caused a lot of problems, like running out of disk space or RAM. So use this style sparingly and carefully!

Wednesday, April 18, 2012

SAS and Keyboard Shortcuts

Base SAS has an easy way to add keyboard shortcuts that not only do X typical keyboard shortcut task, but also Y SAS program task (e.g., execute a macro). This can be a bit tricky to get to work right, but I've done it with CheckLog, PrintContents, OpenTable, and other interactive macros. However, I can't seem to figure out how to do some of these same things in Enterprise Guide.

Sure, it's easier in Enterprise Guide to open a table that's been run, but what about that library with 10,000 tables where I want to open only 1? It's like searching for a needle in a haystack, not to mention the load time just to see the tables in the library (very slow at 10k tables). It's so much easier to use OpenTable, and it's even easier to use OpenTable via keyboard shortcut. I have another keyboard command to open the properties of the table (a window that is quite severely limited in SAS EG, so perhaps that wouldn't be quite as useful anyway).

And the windowing commands seem to be gone, too. I can't edit a keyboard shortcut to jump from the program to the log: In Base SAS, I use CTRL + L for the log, CTRL + J for the program ("J" only because it's easy to reach and on the same keyboard line as L), and CTRL + K for executing the CheckLog macro ("K" for checK, I guess--again, it's on the same keyboard line as J and L). Just to note: I also have the CAPS key remapped to CTRL, so that's even easier to reach for my lazy efficient hands.

If anyone has experience with doing these things in Enterprise Guide, I'd love to hear feedback on how you get things like this to work - or if you just gave up and went with the new flow. My searches online have been fruitless up to this point, so I wanted to have this post available, at least for a point of contact in case someone else is wondering about the same things I am.

Tuesday, April 3, 2012

SAS Enterprise Guide and the Log

I'm presenting on the CheckLog macro that I developed to review a log (or any file or list of files) for errors, warning, and other messages in SAS related to issues. To make sure everything is ready to go, I've been reviewing it to see if there's anything I can improve, especially in regard to SAS Enterprise Guide, the new(er) platform for using SAS.

I encountered a few issues between the two. First, the display manager statements (DM) no longer work in Enterprise Guide. The fix was easy, although a bit tricky: For Windows users (Enterprise Guide is currently only on Windows), I switched from using the DM POSTMESSAGE statement to a Windows API called MessageBox. The API allows greater flexibility than the POSTMESSAGE statement, e.g., I can set an icon to go along with the message. Now Windows users can tell what happened not only by the message, but the icon, too.

However, the DM statement that attempts to export the current log is still intact. I was unable to find a way to replace this, or much less export the Enterprise Guide log in a simple, programmatic fashion. Essentially, it is not possible to use CheckLog to review the "current log" as defined in the Base SAS sense. However, Enterprise Guide users can still check the "current log", but they have to make it an external log in one of two ways.

The first way is to export the log using PROC PRINTTO before the program executes. The code for this isn't too bad, and it can be easily added to any existing program:

/* Set a directory and filename for the log */
%let log=%sysfunc(pathname(work))\work.log;

/* Print the log to the specified location */
proc printto log="&LOG";
run;

/* Run some SAS code... */
proc sql;
create table test as
select *
from sashelp.vtable
;
quit;

/* Turn off printing to the file */
proc printto;
run;

/* Check the external log */
/* Note: The shadow is set to "N" (No) since it is not necessary to copy the log */
%checklog(&LOG, shadow=N);

This method works fairly well. However, not all users may want to use PROC PRINTTO, or they may be using it in a fashion that would conflict with the above suggestion.

The second option involves the project flow in Enterprise Guide. This solution is quite a bit more convoluted, and I outlined it, along with screenshots, on the CheckLog Enterprise Guide page. Essentially, the user has to export the log as a step in the project flow and run CheckLog in a small program. From there, the user can either programmatically determine what to do or set other steps in Enterprise Guide to run based on conditions, e.g., using the ISSUES macro variable to determine what to do next.

Overall, this is quite a bit more convoluted, and it would be great if there were some programmatic way to export the Enterprise Guide log. If anyone knows of a simple way to do that, please let me know!

Thursday, February 3, 2011

The Powerful SAS Macro

In SAS, there are three main types of code: the DATA step, procedures (PROC), and the macro language. The macro language is incredibly powerful. It allows users to create dynamic programs, either by conditional logic, iterations, or a combination. A macro program can be as simple as running the same exact DATA step the same way every time, or as dynamic as generating custom code based on the input. (See here and here for more information on the macro language. For some examples of general-use macros, see my macro site.)

As a visual demonstration of the power of the SAS macro language, here is a comparison of SAS code and log output, printed on paper with a similar format:


SAS code (33 pages), including project-specific macros (13 pages)
(Courier New font, size 10; 1.5 line spacing; .5" margins)


SAS log from above code (391 pages)
(Courier New font, size 10; original line spacing; .5" margins)

(Note: The SAS log is a record of what SAS has done. When code is run, it documents input and output record counts, issues like warnings and errors, run time, and other information. See this page for more information.)

The code was formatted with 1.5 line spacing, although the line spacing in the log was left as-is. Additionally, the code included general-use macros (macros not specific to this project), which were not included in the printed code, but would have printed log output upon use. For example, the DUPCHECK macro, used for identifying and resolving duplicates, was used often. As one line of code, it generates, in the simplest example, 42 lines of code. (For an example of its use, see code and log.)

Even so, the ability to do so much work with so few lines of code is incredibly powerful and efficient. I am able to save time and energy, make processing more efficient and effective, simplify and standardize code, and share processes with other users. If you are a SAS user and you do not know the macro language, I encourage you to start learning!

Friday, May 7, 2010

Open Last Table in SAS

I've been trying to find a way to open the last table created in SAS by using a keyboard shortcut. It's taken a while and many online searches to find it, but I finally figured out a good way to do it. I created a macro and set the macro to a keyboard shortcut. Here's the entire macro:

%macro OpenTable(table=&syslast) / des="Open a table";

dm "vt %sysfunc(compress(&table))" vt;

%mend OpenTable;

Set the macro to a keyboard shortcut by typing the following code into the keyboard shortcut editor window (F9):

gsubmit '%opentable;'

By default, the macro opens the last table created, and the argument can be modified for any table.

I'm so glad I found a way to do this! This should save a lot of time!

Update:

I added more to the macro code in case the table doesn't exist. Here's the new code:

%macro OpenTable(table=&syslast) / des="Open a table";

/* Check if table exists */
%if %sysfunc(exist(&table))=1 %then %do;

dm "vt %sysfunc(compress(&table))" vt;

%end;

/* Otherwise pop-up a message that it does not exist. */
%else %do;

dm 'postmessage "The specified table does not exist."';

%end;

%mend OpenTable;

Update Update:

I've developed a rather complex macro now that does the same thing:

OpenTable.sas

Saturday, April 4, 2009

Keyboard Shortcuts

I love keyboard shortcuts. There's no better way to do things quickly than by using a keyboard. If you think about it, using all fingers instead of moving your hand/arm and clicking with one finger must be faster. But first you need to know the shortcuts. Here's a list of some good resources for keyboard shortcuts in various programs:
  1. Windows XP
  2. Windows Vista (Remote Desktop)
  3. Firefox
  4. Microsoft Excel (Others)
  5. Microsoft Outlook
  6. SAS
Here are some of my favorite shortcuts--ones that people don't usually know about. These are based in Microsoft Windows XP.
  1. Alt+Tab for switching programs. Ctrl+Tab for switching tabs in Firefox or other tabbed programs. Alt+Page Up or Page Down is incredibly useful on remote desktops for switching between programs just like Alt+Tab.
  2. Ctrl+Shift+Esc brings up Windows Task Manager. Similarly, Windows+Break brings up the System Properties. The usual Windows combinations are good, too, especially Windows+L, which locks the computer, Windows+D, which shows the desktop, and Windows+E, which opens Explorer.
  3. Alt+F4 terminates a program. In some programs Ctrl+F4 terminates a window, submenu, or other child program within a program. I like to use that in SAS quite a bit. Ctrl+Shift+T opens a new tab in Firefox, and Ctrl+W closes tabs in Firefox.
  4. Keyboard shortcuts can be assigned to shortcut icons. At home and work, I use the Ctrl+Alt+Shift combination for typical programs. I usually assign Ctrl+Alt+Shift+W for Microsoft Word, Ctrl+Alt+Shift+X for Excel, Ctrl+Alt+Shift+N for Notepad, and Ctrl+Alt+Shift+C for Calculator.
  5. At work, I use the Ctrl+Alt combination for connecting to various programs that allow me access to something, for example, Ctrl+Alt+S for connecting to SAS, Ctrl+Alt+R for connecting to remote desktops, and Ctrl+Alt+Q for Rapid SQL.
  6. In Excel, Ctrl+; enters the current date and Ctrl+: enters the current time. Ctrl+" copies the cell above to the selected cell and Ctrl+' copies a formula in the same manner. Alt+Enter inserts a line break within a cell, allowing the user to break text across more than one line. Ctrl+Home, Ctrl+End, Ctrl+Page Up, and Ctrl+Page Down are useful navigational keyboard shortcuts in Excel, too. Try them out!
  7. In Microsoft Office, Ctrl+K creates a hyperlink on the selected text.
  8. In Microsoft Outlook, Ctrl+D deletes highlighted or currently viewed mail. Ctrl+Shift+V brings up a menu to move currently highlighted/viewed mail to a folder. Alt+F4, like above, terminates the current open message (I thought Ctrl+F4 would make more sense).
  9. In SAS, the best one to know is F9. Then you can read about all of them! Otherwise, F8 for submitting programs, F6 for viewing the log, F7 for viewing output, and F5 for viewing programs. Keep pressing F5 to toggle between multiple programs.
  10. If the Language Bar toolbar is on in Windows, don't hit Alt+Shift. It switches the language! That one gets me all the time, since my wife uses Chinese on our computer on occasion. And for some reason I bump it quite often.
That's about all I can think of right now. I like learning new keyboard shortcuts, and I know there are a lot more to learn. What are your favorites?