Changeset 9e26562


Ignore:
Timestamp:
06/16/14 21:12:49 (4 years ago)
Author:
Erik Ekman <erik@…>
Children:
d10319
Parents:
859b01
git-author:
Erik Ekman <erik@…> (06/16/14 21:12:49)
git-committer:
Erik Ekman <erik@…> (06/17/14 18:59:06)
Message:

Fix authentication bypass bug

The client could bypass the password check by continuing after getting error
from the server and guessing the network parameters. The server would still
accept the rest of the setup and also network traffic.

Add checks for normal and raw mode that user has authenticated before allowing
any other communication.

Problem found by Oscar Reparaz.

Backported to iodine 0.6 branch.

Files:
5 edited

Legend:

Unmodified
Added
Removed
  • CHANGELOG

    r859b01 r9e26562  
    66CHANGES: 
    77 
    8 2010-02-13: 0.6.0-rc1 "Hotspotify" 
     82014-06-17: 0.6.0 
     9        - Fix authentication bypass vulnerability; found by Oscar Reparaz. 
     10 
     112010-02-06: 0.6.0-rc1 "Hotspotify" 
    912        - Fixed tunnel not working on Windows. 
    1013        - Any device name is now supported on Windows, fixes #47. 
  • src/iodined.c

    r859b01 r9e26562  
    117117#endif 
    118118 
     119/* This will not check that user has passed login challenge */ 
    119120static int 
    120121check_user_and_ip(int userid, struct query *q) 
     
    141142        tempin = (struct sockaddr_in *) &(q->from); 
    142143        return memcmp(&(users[userid].host), &(tempin->sin_addr), sizeof(struct in_addr)); 
     144} 
     145 
     146/* This checks that user has passed normal (non-raw) login challenge */ 
     147static int 
     148check_authenticated_user_and_ip(int userid, struct query *q) 
     149{ 
     150        int res = check_user_and_ip(userid, q); 
     151        if (res) 
     152                return res; 
     153 
     154        if (!users[userid].authenticated) 
     155                return 1; 
     156 
     157        return 0; 
    143158} 
    144159 
     
    781796 
    782797                        if (read >= 18 && (memcmp(logindata, unpacked+1, 16) == 0)) { 
    783                                 /* Login ok, send ip/mtu/netmask info */ 
    784  
     798                                /* Store login ok */ 
     799                                users[userid].authenticated = 1; 
     800 
     801                                /* Send ip/mtu/netmask info */ 
    785802                                tempip.s_addr = my_ip; 
    786803                                tmp[0] = strdup(inet_ntoa(tempip)); 
     
    811828                 
    812829                userid = b32_8to5(in[1]); 
    813                 if (check_user_and_ip(userid, q) != 0) { 
     830                if (check_authenticated_user_and_ip(userid, q) != 0) { 
    814831                        write_dns(dns_fd, q, "BADIP", 5, 'T'); 
    815832                        return; /* illegal id */ 
     
    847864 
    848865                userid = b32_8to5(in[1]); 
    849                  
    850                 if (check_user_and_ip(userid, q) != 0) { 
     866 
     867                if (check_authenticated_user_and_ip(userid, q) != 0) { 
    851868                        write_dns(dns_fd, q, "BADIP", 5, 'T'); 
    852869                        return; /* illegal id */ 
     
    889906                userid = b32_8to5(in[1]); 
    890907 
    891                 if (check_user_and_ip(userid, q) != 0) { 
     908                if (check_authenticated_user_and_ip(userid, q) != 0) { 
    892909                        write_dns(dns_fd, q, "BADIP", 5, 'T'); 
    893910                        return; /* illegal id */ 
     
    10171034                /* Downstream fragsize probe packet */ 
    10181035                userid = (b32_8to5(in[1]) >> 1) & 15; 
    1019                 if (check_user_and_ip(userid, q) != 0) { 
     1036                if (check_authenticated_user_and_ip(userid, q) != 0) { 
    10201037                        write_dns(dns_fd, q, "BADIP", 5, 'T'); 
    10211038                        return; /* illegal id */ 
     
    10521069                /* Downstream fragsize packet */ 
    10531070                userid = unpacked[0]; 
    1054                 if (check_user_and_ip(userid, q) != 0) { 
     1071                if (check_authenticated_user_and_ip(userid, q) != 0) { 
    10551072                        write_dns(dns_fd, q, "BADIP", 5, 'T'); 
    10561073                        return; /* illegal id */ 
     
    10851102                /* Ping packet, store userid */ 
    10861103                userid = unpacked[0]; 
    1087                 if (check_user_and_ip(userid, q) != 0) { 
     1104                if (check_authenticated_user_and_ip(userid, q) != 0) { 
    10881105                        write_dns(dns_fd, q, "BADIP", 5, 'T'); 
    10891106                        return; /* illegal id */ 
     
    12151232                userid = code; 
    12161233                /* Check user and sending ip number */ 
    1217                 if (check_user_and_ip(userid, q) != 0) { 
     1234                if (check_authenticated_user_and_ip(userid, q) != 0) { 
    12181235                        write_dns(dns_fd, q, "BADIP", 5, 'T'); 
    12191236                        return; /* illegal id */ 
     
    17861803        if (len < 16) return; 
    17871804 
    1788         /* can't use check_user_and_ip() since IP address will be different, 
     1805        /* can't use check_authenticated_user_and_ip() since IP address will be different, 
    17891806           so duplicate here except IP address */ 
    17901807        if (userid < 0 || userid >= created_users) return; 
    17911808        if (!users[userid].active || users[userid].disabled) return; 
     1809        if (!users[userid].authenticated) return; 
    17921810        if (users[userid].last_pkt + 60 < time(NULL)) return; 
    17931811 
     
    18141832                login_calculate(myhash, 16, password, users[userid].seed - 1); 
    18151833                send_raw(fd, myhash, 16, userid, RAW_HDR_CMD_LOGIN, q); 
     1834 
     1835                users[userid].authenticated_raw = 1; 
    18161836        } 
    18171837} 
     
    18201840handle_raw_data(char *packet, int len, struct query *q, int dns_fd, int tun_fd, int userid) 
    18211841{ 
    1822         if (check_user_and_ip(userid, q) != 0) { 
     1842        if (check_authenticated_user_and_ip(userid, q) != 0) { 
    18231843                return; 
    18241844        } 
     1845        if (!users[userid].authenticated_raw) return; 
    18251846 
    18261847        /* Update query and time info for user */ 
     
    18441865handle_raw_ping(struct query *q, int dns_fd, int userid) 
    18451866{ 
    1846         if (check_user_and_ip(userid, q) != 0) { 
     1867        if (check_authenticated_user_and_ip(userid, q) != 0) { 
    18471868                return; 
    18481869        } 
     1870        if (!users[userid].authenticated_raw) return; 
    18491871 
    18501872        /* Update query and time info for user */ 
  • src/user.c

    ra4f41b r9e26562  
    7979                        created_users++; 
    8080                } 
     81                users[i].authenticated = 0; 
     82                users[i].authenticated_raw = 0; 
    8183                users[i].active = 0; 
    8284                /* Rest is reset on login ('V' packet) */ 
     
    120122        ret = -1; 
    121123        for (i = 0; i < USERS; i++) { 
    122                 if (users[i].active && !users[i].disabled && 
     124                if (users[i].active && 
     125                        users[i].authenticated && 
     126                        !users[i].disabled && 
    123127                        users[i].last_pkt + 60 > time(NULL) && 
    124128                        ip == users[i].tun_ip) { 
     
    172176                if ((!users[i].active || users[i].last_pkt + 60 < time(NULL)) && !users[i].disabled) { 
    173177                        users[i].active = 1; 
     178                        users[i].authenticated = 0; 
     179                        users[i].authenticated_raw = 0; 
    174180                        users[i].last_pkt = time(NULL); 
    175181                        users[i].fragsize = 4096; 
  • src/user.h

    ra4f41b r9e26562  
    3737        char id; 
    3838        int active; 
     39        int authenticated; 
     40        int authenticated_raw; 
    3941        int disabled; 
    4042        time_t last_pkt; 
  • tests/user.c

    r8692c7 r9e26562  
    9494         
    9595        testip = (unsigned int) inet_addr("127.0.0.2"); 
     96        fail_unless(find_user_by_ip(testip) == -1); 
     97 
     98        users[0].authenticated = 1; 
     99 
     100        testip = (unsigned int) inet_addr("127.0.0.2"); 
    96101        fail_unless(find_user_by_ip(testip) == 0); 
    97102} 
     
    136141 
    137142        for (i = 0; i < USERS; i++) { 
     143                users[i].authenticated = 1; 
     144                users[i].authenticated_raw = 1; 
    138145                fail_unless(find_available_user() == i); 
     146                fail_if(users[i].authenticated); 
     147                fail_if(users[i].authenticated_raw); 
    139148        } 
    140149 
Note: See TracChangeset for help on using the changeset viewer.