PostgreSQL e C++ (libpq) André Restivo Faculdade de Engenharia da Universidade do Porto April 5, 2013 André Restivo (FEUP) PostgreSQL e C++ (libpq) April 5, 2013 1 / 18
Sumário 1 Introdução 2 Ligação 3 Manipulação 4 Perguntas 5 SQL Injection André Restivo (FEUP) PostgreSQL e C++ (libpq) April 5, 2013 2 / 18
Outline Introdução 1 Introdução 2 Ligação 3 Manipulação 4 Perguntas 5 SQL Injection André Restivo (FEUP) PostgreSQL e C++ (libpq) April 5, 2013 3 / 18
libpq Introdução A libpq é uma biblioteca que permite a uma aplicação escrita em C ou C++ usar uma base de dados PostgreSQL. Documentação: http://www.postgresql.org/docs/8.3/static/libpq.html Para compilar um programa que usa a libpq é necessário fazer include de um ficheiro header: #i n c l u d e <p o s t g r e s q l / l i b p q f e. h> E linkar com a biblioteca quando se compila: g++ l i b p q. cpp o l i b p q l p q André Restivo (FEUP) PostgreSQL e C++ (libpq) April 5, 2013 4 / 18
Outline Ligação 1 Introdução 2 Ligação 3 Manipulação 4 Perguntas 5 SQL Injection André Restivo (FEUP) PostgreSQL e C++ (libpq) April 5, 2013 5 / 18
Ligação Ligação Para nos ligarmos à base de dados, usamos o comando PQconnectdb. Este comando recebe como parâmetro uma connection string que contém entre outras as variáveis: host, username e password. O resultado deste comando, no caso de ser bem sucedido, é um apontador para uma variável do tipo PGconn que representa uma ligação à base de dados. PGconn PQconnectdb ( const char c o n n i n f o ) ; PGconn conn = PQconnectdb ( " h o s t = vdbm. f e. up. pt u s e r = exemplo password = exemplo " ) ; André Restivo (FEUP) PostgreSQL e C++ (libpq) April 5, 2013 6 / 18
Ligação Ligação Devemos sempre verificar se a ligação foi bem sucedida. Primeiro devemos verificar se o comando PQconnectdb retornou null Depois se a ligação está ok. O comando PQStatus retorna o estado da ligação. i f (! conn ) { cout << " F a i l e d to connect to Database " << e n d l ; e x i t ( 1); } i f ( PQstatus ( conn )!= CONNECTION_OK) { cout << " F a i l e d to connect to Database " << e n d l ; e x i t ( 1); } André Restivo (FEUP) PostgreSQL e C++ (libpq) April 5, 2013 7 / 18
Ligação Ligação Quando já não precisarmos da ligação à base de dados, devemos sempre libertá-la. P Q f i n i s h ( conn ) ; André Restivo (FEUP) PostgreSQL e C++ (libpq) April 5, 2013 8 / 18
Outline Manipulação 1 Introdução 2 Ligação 3 Manipulação 4 Perguntas 5 SQL Injection André Restivo (FEUP) PostgreSQL e C++ (libpq) April 5, 2013 9 / 18
Manipulação Manipulação Para executar uma query que não retorna resultados, usamos a função PQexec. Este comando retorna um apontador para uma variável do tipo PGresult. P G r e s u l t PQexec ( PGconn conn, const char command ) ; PGresult r es = PQexec ( conn, "DELETE FROM empregado WHERE id = " + emp_id ) ; André Restivo (FEUP) PostgreSQL e C++ (libpq) April 5, 2013 10 / 18
Manipulação Manipulação Devemos sempre testar se o comando executou corretamente usando a função PQresultStatus. i f ( P Q r e s u l t S t a t u s ( r e s )!= PGRES_COMMAND_OK) { cout << " F a i l e d to e x e c u t e q u e r y " << << P Q r e s u l t S t a t u s ( r e s ) << e n d l ; e x i t ( 1); } André Restivo (FEUP) PostgreSQL e C++ (libpq) April 5, 2013 11 / 18
Outline Perguntas 1 Introdução 2 Ligação 3 Manipulação 4 Perguntas 5 SQL Injection André Restivo (FEUP) PostgreSQL e C++ (libpq) April 5, 2013 12 / 18
Perguntas Perguntas Para fazer uma pergunta à base de dados também se usa o comando PQexec. A única diferença está na forma como se verifica se o comando executou corretamete. E no fato da variável retornada conter a resposta à pergunta. P G r e s u l t r e s = PQexec ( p s q l, " s e l e c t emp_id, emp_nome from empregado " ) ; i f ( P Q r e s u l t S t a t u s ( r e s )!= PGRES_TUPLES_OK) { cout << " F a i l e d to e x e c u t e q u e r y " << << P Q r e s u l t S t a t u s ( r e s ) << e n d l ; e x i t ( 1); } André Restivo (FEUP) PostgreSQL e C++ (libpq) April 5, 2013 13 / 18
Perguntas Perguntas Para sabermos quantos resultados foram retornados usamos a função PQntuples(res). Para obtermos um valor do resultados usamos a função PQgetvalue que nos permite obter o valor uma célula representada pelo número da linha e da coluna. f o r ( i n t row = 0 ; row < PQntuples ( r e s ) ; row++) { cout << PQgetvalue ( res, row, 0) << << PQgetvalue ( res, row, 1) << endl ; } André Restivo (FEUP) PostgreSQL e C++ (libpq) April 5, 2013 14 / 18
Outline SQL Injection 1 Introdução 2 Ligação 3 Manipulação 4 Perguntas 5 SQL Injection André Restivo (FEUP) PostgreSQL e C++ (libpq) April 5, 2013 15 / 18
SQL Injection SQL Injection Um ataque informático muito comum é o chamado SQL Injection. Se os parâmetros de uma query não forem tratados devidamente, principalmente se vierem de uma fonte não confiável, corremos o risco de executar comandos que não desejávamos. Por exemplo: Imaginemos uma query que lista os empregados na base de dados com um determinado nome: PQexec ( psql, "SELECT emp_id, emp_nome FROM empregado WHERE emp_nome = " + emp_nome + " " ) ; O que acontece se o utilizador introduzir o nome: ;DELETE FROM empregado;- - André Restivo (FEUP) PostgreSQL e C++ (libpq) April 5, 2013 16 / 18
SQL Injection SQL Injection Uma forma de nos protegermos contra este tipo de ataques é usarmos funções que tratam as strings antes de as usarmos numa query. Outra é usarmos prepared statements. PGresult PQexecParams ( PGconn conn, c o n s t char command, i n t nparams, c o n s t Oid paramtypes, c o n s t char c o n s t paramvalues, const i n t paramlengths, const i n t paramformats, i n t r e s u l t F o r m a t ) ; André Restivo (FEUP) PostgreSQL e C++ (libpq) April 5, 2013 17 / 18
SQL Injection SQL Injection http://xkcd.com/327/ http://alicebobandmallory.com/articles/2010/09/23/ did-little-bobby-tables-migrate-to-sweden http://gizmodo.com/5498412/ sql-injection-license-plate-hopes-to-foil-euro-traffic-cameras André Restivo (FEUP) PostgreSQL e C++ (libpq) April 5, 2013 18 / 18