mobile-subscriber 0.0.1.alpha5 → 0.0.1.beta1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 0f3d86284c8cd6a42a0fdab25eba82cb6c1ba05b
4
- data.tar.gz: fbcf9b5f54072d1a6f9580da21bc6afbd4314d51
3
+ metadata.gz: b57bb989e630712c7b4a06d051a7038006b426c1
4
+ data.tar.gz: 00d70b45ea77d7e0ebeae56c47c3fb19960c5ebc
5
5
  SHA512:
6
- metadata.gz: 0acdb66c244b26c2360958eeaf0a392b3786d59e73946348e5abfc1f249ea47e978576711b76e3a2f4a960c60e1ad4ca546e879c085a2821be8223c8ad2317ab
7
- data.tar.gz: d7f91b0655d285b3f9ce75993ee7702088b35e17887590c77cd54df922703fd421000a49e08ddf6d1dc45b9e6c3d630039c8b0652048d4f0a60a527e60b98a7c
6
+ metadata.gz: df5e3a68907f3c6a33350a16be66e20ed2d385d133ee2547e1848613ae179a5231c8a145ccf4ed46ae1a2f41c785c2c816c612c4c62a50381ba4140a8b4fface
7
+ data.tar.gz: 2e4a5f0151692218c8cf90d20de3288f31aa91ebaba3533dbb67607176272acc940caee34ca243c617af9697c70168aeccd5f0438cd8eb5a54e267d0ae392989
data/README.md CHANGED
@@ -1,6 +1,16 @@
1
1
  # MobileSubscriber Gem
2
2
 
3
- TODO: Write a gem description
3
+ It's a fact that the Mobile network providers (carriers, operators & such) share
4
+ subscriber identity data to approved 3rd parties when users navigate via Web to
5
+ the 3rd parties' websites.
6
+
7
+ The problem is that generally the algorythms used by these 3rd parties offer
8
+ no security against forged HTTP requests.
9
+
10
+ The goals of this project are basically to detect the user's identity for the
11
+ 3rd parties, in the most secure and reliably as possible:
12
+ - Validate the mobile user's identity by checking the originating IP address
13
+ - Validate the request hopping between relaying proxies
4
14
 
5
15
  ## Installation
6
16
 
@@ -34,3 +44,5 @@ TODO: Write usage instructions here
34
44
  ## References
35
45
  - [MSISDN - Wikipedia, the free encyclopedia](http://en.wikipedia.org/wiki/MSISDN)
36
46
  - [Mobile country code - Wikipedia, the free encyclopedia](http://en.wikipedia.org/wiki/Mobile_country_code)
47
+ - [Mobile networks: exploiting HTTP headers and data traffic - DefCamp 2012](http://www.slideshare.net/DefCamp/mobile-networks-exploiting-http-headers-and-data-traffic)
48
+ - [Privacy Leaks in Mobile Phone Internet Access - Collin Mulliner](http://www.mulliner.org/collin/academic/publications/mobile_web_privacy_icin10_mulliner.pdf)
@@ -13,5 +13,7 @@ module MobileSubscriber
13
13
  autoload :FromXUpCallingLineIdHttpRequestHeader
14
14
  autoload :FromXUpChMsisdnHttpRequestHeader
15
15
  autoload :FromXUpSubnoHttpRequestHeader
16
+ autoload :FromXWapSesiones3gMdnHttpRequestHeader
17
+ autoload :HttpRequestInfo
16
18
  end
17
19
  end
@@ -1,137 +1,70 @@
1
1
  require 'mobile_subscriber/dictionaries/dialing_and_country_codes'
2
2
 
3
- module MobileSubscriber
4
- module Detection
3
+ module MobileSubscriber::Detection
5
4
 
6
- # Módulo que provee métodos de detección y validacion para MSISDN por el
7
- # header de HTTP 'Msisdn':
8
- # - Claro Brasil
9
- # - Claro Chile
10
- # - Claro Colombia
11
- # - Claro Costa Rica
12
- # - Claro República Dominicana
13
- # - Claro Ecuador
14
- # - Claro El Salvador
15
- # - Claro Guatemala
16
- # - Claro Nicaragua
17
- # - Claro Panamá
18
- # - Claro Paraguay
19
- module FromMsisdnHttpRequestHeader
5
+ # Módulo que provee métodos de detección y validacion para MSISDN por el
6
+ # header de HTTP 'Msisdn':
7
+ # - Claro Brasil
8
+ # - Claro Chile
9
+ # - Claro Colombia
10
+ # - Claro Costa Rica
11
+ # - Claro República Dominicana
12
+ # - Claro Ecuador
13
+ # - Claro El Salvador
14
+ # - Claro Guatemala
15
+ # - Claro Nicaragua
16
+ # - Claro Panamá
17
+ # - Claro Paraguay
18
+ module FromMsisdnHttpRequestHeader
20
19
 
21
- extend ActiveSupport::Concern
20
+ def extract_from_msisdn_http_request_header(http_request_info)
21
+ if msisdn = http_request_info.headers['Msisdn'] and msisdn.length >= 8
22
22
 
23
- module ClassMethods
24
- def extract_from_msisdn_http_request_header(request)
25
- header_name = 'Msisdn'
26
- header_env_key = "HTTP_#{header_name.gsub('-','_').upcase}"
23
+ country_code = (
24
+ MobileSubscriber::DIALING_COUNTRY_CODES[msisdn[0,2]] ||
25
+ MobileSubscriber::DIALING_COUNTRY_CODES[msisdn[0,3]]
26
+ )
27
27
 
28
- isdn_attributes = nil
29
-
30
- isdn_attributes = if msisdn = request.env[header_env_key] and msisdn.strip.length >= 8
31
- msisdn.strip!
32
- detection_cues = {
33
- remote_ip: request.env["REMOTE_ADDR"],
34
- http_request_headers: { 'Msisdn' => msisdn }
35
- }
36
-
37
- country_code = MobileSubscriber::DIALING_COUNTRY_CODES[msisdn[0,2]] || MobileSubscriber::DIALING_COUNTRY_CODES[msisdn[0,3]]
38
-
39
- # Determinar la procedencia del MSISDN
40
- # TODO: Validar por IP, etc.
41
- case country_code
42
- when 'BR'
43
- # Claro Brasil
44
- # TODO: Determinar correctamente el MNC (05, 38)
45
- {
46
- id: msisdn,
47
- mobile_country_code: "724",
48
- mobile_network_code: "05"
49
- }.merge(detection_cues: detection_cues)
50
- when 'CL'
51
- # Claro Chile
52
- {
53
- id: msisdn,
54
- mobile_country_code: "730",
55
- mobile_network_code: "03"
56
- }.merge(detection_cues: detection_cues)
57
- when 'CO'
58
- # Claro Colombia
59
- {
60
- id: msisdn,
61
- mobile_country_code: "732",
62
- mobile_network_code: "101"
63
- }.merge(detection_cues: detection_cues)
64
- when 'CR'
65
- # Claro Costa Rica
66
- {
67
- id: msisdn,
68
- mobile_country_code: "712",
69
- mobile_network_code: "03"
70
- }.merge(detection_cues: detection_cues)
71
- when 'DO'
72
- # Claro Dominicana:
73
- {
74
- id: msisdn,
75
- mobile_country_code: "370",
76
- mobile_network_code: "02"
77
- }.merge(detection_cues: detection_cues)
78
- when 'EC'
79
- # Claro Ecuador:
80
- {
81
- id: msisdn,
82
- mobile_country_code: "740",
83
- mobile_network_code: "01"
84
- }.merge(detection_cues: detection_cues)
85
- when 'SV'
86
- # Claro El Salvador:
87
- {
88
- id: msisdn,
89
- mobile_country_code: "706",
90
- mobile_network_code: "01"
91
- }.merge(detection_cues: detection_cues)
92
- when 'GT'
93
- # Claro Guatemala:
94
- {
95
- id: msisdn,
96
- mobile_country_code: "704",
97
- mobile_network_code: "01"
98
- }.merge(detection_cues: detection_cues)
99
- when 'HN'
100
- # Claro Honduras:
101
- {
102
- id: msisdn,
103
- mobile_country_code: "708",
104
- mobile_network_code: "001"
105
- }.merge(detection_cues: detection_cues)
106
- when 'NI'
107
- # Claro Nicaragua:
108
- {
109
- id: msisdn,
110
- mobile_country_code: "710",
111
- mobile_network_code: "21"
112
- }.merge(detection_cues: detection_cues)
113
- when 'PA'
114
- # Claro Panamá:
115
- {
116
- id: msisdn,
117
- mobile_country_code: "714",
118
- mobile_network_code: "03"
119
- }.merge(detection_cues: detection_cues)
120
- when 'PY'
121
- # Claro Paraguay:
122
- {
123
- id: msisdn,
124
- mobile_country_code: "744",
125
- mobile_network_code: "02"
126
- }.merge(detection_cues: detection_cues)
127
- end
128
-
129
- end
28
+ # Determine the Network Operator (MCC + MNC tuple):
29
+ # TODO: Validate IP ranges, additional headers, etc.
30
+ network_id_tuple = case country_code
31
+ when 'BR' # Claro Brasil
32
+ # TODO: Determine (if possible) the MNC (05, 38)
33
+ { mcc: "724", mnc: "05" }
34
+ when 'CL' # Claro Chile
35
+ { mcc: "730", mnc: "03" }
36
+ when 'CO' # Claro Colombia
37
+ { mcc: "732", mnc: "101" }
38
+ when 'CR' # Claro Costa Rica
39
+ { mcc: "712", mnc: "03" }
40
+ when 'DO' # Claro Dominicana:
41
+ { mcc: "370", mnc: "02" }
42
+ when 'EC' # Claro Ecuador:
43
+ { mcc: "740", mnc: "01" }
44
+ when 'SV' # Claro El Salvador:
45
+ { mcc: "706", mnc: "01" }
46
+ when 'GT' # Claro Guatemala:
47
+ { mcc: "704", mnc: "01" }
48
+ when 'HN' # Claro Honduras:
49
+ { mcc: "708", mnc: "001" }
50
+ when 'NI' # Claro Nicaragua:
51
+ { mcc: "710", mnc: "21" }
52
+ when 'PA' # Claro Panamá:
53
+ { mcc: "714", mnc: "03" }
54
+ when 'PY' # Claro Paraguay:
55
+ { mcc: "744", mnc: "02" }
56
+ end
130
57
 
131
- isdn_attributes
58
+ # Return only if we identified the network:
59
+ if network_id_tuple.present?
60
+ {
61
+ id: msisdn,
62
+ mobile_country_code: network_id_tuple[:mcc],
63
+ mobile_network_code: network_id_tuple[:mnc],
64
+ http_request_info: http_request_info
65
+ }
132
66
  end
133
67
  end
134
-
135
68
  end
136
69
  end
137
70
  end
@@ -1,53 +1,38 @@
1
1
  require 'mobile_subscriber/dictionaries/dialing_and_country_codes'
2
- module MobileSubscriber
3
- module Detection
2
+ module MobileSubscriber::Detection
4
3
 
5
- # Módulo que provee métodos de deteccion y validacion para MSISDN's de:
6
- # - Telcel México
7
- # - Claro Argentina
8
- module FromXNokiaMsisdnHttpRequestHeader
4
+ # Módulo que provee métodos de deteccion y validacion para MSISDN's de:
5
+ # - Telcel México
6
+ # - Claro Argentina
7
+ module FromXNokiaMsisdnHttpRequestHeader
9
8
 
10
- extend ActiveSupport::Concern
9
+ def extract_from_x_nokia_msisdn_http_request_header(http_request_info)
10
+ if msisdn = http_request_info.headers['X-Nokia-Msisdn'] and msisdn.length >= 8
11
11
 
12
- module ClassMethods
13
- def extract_from_x_nokia_msisdn_http_request_header(request)
12
+ country_code = (
13
+ MobileSubscriber::DIALING_COUNTRY_CODES[msisdn[0,2]] ||
14
+ MobileSubscriber::DIALING_COUNTRY_CODES[msisdn[0,3]]
15
+ )
14
16
 
15
- header_name = 'X-Nokia-Msisdn'
16
- header_env_key = "HTTP_#{header_name.gsub('-','_').upcase}"
17
+ # Determine the Network Operator tuple (MCC + MNC):
18
+ # TODO: Validate IP ranges, additional headers, etc.
19
+ network_id_tuple = case country_code
20
+ when 'MX' # Telcel México:
21
+ { mcc: "334", mnc: "020" }
17
22
 
18
- isdn_attributes = if msisdn = request.env[header_env_key] and msisdn.strip.length >= 8
19
- msisdn.strip!
20
- detection_cues = {
21
- remote_ip: request.env["REMOTE_ADDR"],
22
- http_request_headers: { 'X-Nokia-Msisdn' => msisdn }
23
- }
24
-
25
- country_code = MobileSubscriber::DIALING_COUNTRY_CODES[msisdn[0,2]] || MobileSubscriber::DIALING_COUNTRY_CODES[msisdn[0,3]]
26
-
27
- # Determinar la procedencia del MSISDN
28
- # TODO: Validar por IP, etc.
29
- case country_code
30
- when 'MX'
31
- # Telcel México:
32
- {
33
- id: msisdn,
34
- mobile_country_code: "334",
35
- mobile_network_code: "020"
36
- }.merge(detection_cues: detection_cues)
37
-
38
- # Claro Argentina:
39
- when 'AR'
40
- {
41
- id: msisdn,
42
- mobile_country_code: "722",
43
- mobile_network_code: "330"
44
- }.merge(detection_cues: detection_cues)
45
- end
46
- end
47
-
48
- isdn_attributes
23
+ when 'AR' # Claro Argentina:
24
+ { mcc: "722", mnc: "330" }
49
25
  end
50
26
 
27
+ # Return only if we identified the network:
28
+ if network_id_tuple.present?
29
+ {
30
+ id: msisdn,
31
+ mobile_country_code: network_id_tuple[:mcc],
32
+ mobile_network_code: network_id_tuple[:mnc],
33
+ http_request_info: http_request_info
34
+ }
35
+ end
51
36
  end
52
37
  end
53
38
  end
@@ -1,100 +1,65 @@
1
1
  require 'mobile_subscriber/dictionaries/dialing_and_country_codes'
2
- module MobileSubscriber
3
- module Detection
2
+ module MobileSubscriber::Detection
4
3
 
5
- # Módulo que provee métodos de deteccion y validacion para MSISDN por el
6
- # header de HTTP 'X-Up-Calling-Line-Id':
7
- # - Claro Perú
8
- # - TIM (Telecom Italia Mobile) Brasil
9
- # - OI Brasil
10
- # - Movistar México
11
- # - Movistar Argentina
12
- # - Movistar Ecuador
13
- # - Movistar Perú
14
- module FromXUpCallingLineIdHttpRequestHeader
4
+ # Módulo que provee métodos de deteccion y validacion para MSISDN por el
5
+ # header de HTTP 'X-Up-Calling-Line-Id':
6
+ # - Claro Perú
7
+ # - TIM (Telecom Italia Mobile) Brasil
8
+ # - OI Brasil
9
+ # - Movistar México
10
+ # - Movistar Argentina
11
+ # - Movistar Ecuador
12
+ # - Movistar Perú
13
+ module FromXUpCallingLineIdHttpRequestHeader
15
14
 
16
- extend ActiveSupport::Concern
15
+ def extract_from_x_up_calling_line_id_http_request_header(http_request_info)
16
+ if msisdn = http_request_info.headers['X-Up-Calling-Line-Id'] and msisdn.length >= 8
17
17
 
18
- module ClassMethods
19
- def extract_from_x_up_calling_line_id_http_request_header(request)
20
- header_name = 'X-Up-Calling-Line-Id'
21
- header_env_key = "HTTP_#{header_name.gsub('-','_').upcase}"
18
+ country_code = (
19
+ MobileSubscriber::DIALING_COUNTRY_CODES[msisdn[0,2]] ||
20
+ MobileSubscriber::DIALING_COUNTRY_CODES[msisdn[0,3]]
21
+ )
22
22
 
23
- isdn_attributes = if msisdn = request.env[header_env_key] and msisdn.strip.length >= 8
24
- msisdn.strip!
25
- detection_cues = {
26
- remote_ip: request.env["REMOTE_ADDR"],
27
- http_request_headers: { header_name => msisdn }
28
- }
29
-
30
- country_code = MobileSubscriber::DIALING_COUNTRY_CODES[msisdn[0,2]] || MobileSubscriber::DIALING_COUNTRY_CODES[msisdn[0,3]]
31
-
32
- case country_code
33
- when 'PE'
34
- if (http_request_via_header = request.env["HTTP_VIA"]).present? and http_request_via_header =~ /Comverse/i
35
- # Is Claro Peru subscriber:
36
- detection_cues[:http_request_headers]['Via'] = http_request_via_header
37
- {
38
- id: msisdn,
39
- mobile_country_code: "716",
40
- mobile_network_code: "10"
41
- }.merge(detection_cues: detection_cues)
42
- else
43
- # Is a Movistar Peru subscriber:
44
- {
45
- id: msisdn,
46
- mobile_country_code: "716",
47
- mobile_network_code: "06"
48
- }.merge(detection_cues: detection_cues)
49
- end
50
- when 'BR'
51
- if http_request_x_msp_apn_header = request.env["HTTP_X_MSP_APN"] and http_request_x_msp_apn_header.present?
52
- detection_cues[:http_request_headers]['X-Msp-Apn'] = http_request_x_msp_apn_header
53
- if http_request_x_msp_apn_header =~ /OI/i
54
- # Is a Oi Brazil subscriber:
55
- {
56
- id: msisdn,
57
- mobile_country_code: "724",
58
- mobile_network_code: "30"
59
- }.merge(detection_cues: detection_cues)
60
- else
61
- # Is a TIM Brasil subscriber:
62
- {
63
- id: msisdn,
64
- mobile_country_code: "724",
65
- mobile_network_code: "02"
66
- }.merge(detection_cues: detection_cues)
67
- end
68
- end
69
- when 'MX'
70
- # Is a Movistar Mexico subscriber:
71
- {
72
- id: msisdn,
73
- mobile_country_code: "334",
74
- mobile_network_code: "030"
75
- }.merge(detection_cues: detection_cues)
76
- when 'AR'
77
- # Is a Movistar Argentina subscriber:
78
- # TODO: Detect if MNC is 010 or 070 (Different MHz Bands)
79
- {
80
- id: msisdn,
81
- mobile_country_code: "722",
82
- mobile_network_code: "010"
83
- }.merge(detection_cues: detection_cues)
84
- when 'EC'
85
- # Is a Movistar Ecuador subscriber:
86
- {
87
- id: msisdn,
88
- mobile_country_code: "740",
89
- mobile_network_code: "00"
90
- }.merge(detection_cues: detection_cues)
23
+ # Determine the Network Operator tuple (MCC + MNC):
24
+ # TODO: Validate IP ranges, additional headers, etc.
25
+ network_id_tuple = case country_code
26
+ when 'PE'
27
+ if (via_header = http_request_info.headers['Via']).present? and via_header =~ /Comverse/i
28
+ # Claro Peru:
29
+ { mcc: "716", mnc: "10" }
30
+ else
31
+ # Movistar Peru:
32
+ { mcc: "716", mnc: "06" }
33
+ end
34
+ when 'BR'
35
+ if x_msp_apn_header = request.env["X-Msp-Apn"] and x_msp_apn_header.present?
36
+ if http_request_x_msp_apn_header =~ /OI/i
37
+ # Oi Brazil:
38
+ { mcc: "724", mnc: "30" }
39
+ else
40
+ # TIM Brazil:
41
+ { mcc: "724", mnc: "02" }
91
42
  end
92
43
  end
44
+ when 'MX' # Movistar Mexico:
45
+ { mcc: "334", mnc: "030" }
46
+ when 'AR' # Movistar Argentina:
47
+ # TODO: Determine (if possible) the MNC (010 or 070)
48
+ { mcc: "722", mnc: "010" }
49
+ when 'EC' # Movistar Ecuador:
50
+ { mcc: "740", mnc: "00" }
51
+ end
93
52
 
94
- isdn_attributes
53
+ # Return only if we identified the network:
54
+ if network_id_tuple.present?
55
+ {
56
+ id: msisdn,
57
+ mobile_country_code: network_id_tuple[:mcc],
58
+ mobile_network_code: network_id_tuple[:mnc],
59
+ http_request_info: http_request_info
60
+ }
95
61
  end
96
62
  end
97
-
98
63
  end
99
64
  end
100
65
  end
@@ -1,46 +1,35 @@
1
1
  require 'mobile_subscriber/dictionaries/dialing_and_country_codes'
2
- module MobileSubscriber
3
- module Detection
4
-
5
- # Módulo que provee métodos de deteccion y validacion para MSISDN's de:
6
- # - Vivo Brasil
7
- module FromXUpChMsisdnHttpRequestHeader
8
-
9
- extend ActiveSupport::Concern
10
-
11
- module ClassMethods
12
- def extract_from_x_up_ch_msisdn_http_request_header(request)
13
- header_name = 'X-Up-Ch-Msisdn'
14
- header_env_key = "HTTP_#{header_name.gsub('-','_').upcase}"
15
-
16
- isdn_attributes = if msisdn = request.env[header_env_key] and msisdn.strip.length >= 8
17
- msisdn.strip!
18
- detection_cues = {
19
- remote_ip: request.env["REMOTE_ADDR"],
20
- http_request_headers: { 'X-Up-Ch-Msisdn' => msisdn }
21
- }
22
-
23
- country_code = MobileSubscriber::DIALING_COUNTRY_CODES[msisdn[0,2]] || MobileSubscriber::DIALING_COUNTRY_CODES[msisdn[0,3]]
24
-
25
- # Determinar la procedencia del MSISDN
26
- # TODO: Validar por IP, etc.
27
- case country_code
28
- when 'BR'
29
- # Vivo:
30
- # TODO: Determinar el MNC correcto (06, 10, 11, 23)
31
- {
32
- id: msisdn,
33
- mobile_country_code: "724",
34
- mobile_network_code: "06"
35
- }.merge(detection_cues: detection_cues)
36
- end
37
-
38
- end
39
- isdn_attributes
2
+ module MobileSubscriber::Detection
3
+ # Módulo que provee métodos de deteccion y validacion para MSISDN's de:
4
+ # - Vivo Brasil
5
+ module FromXUpChMsisdnHttpRequestHeader
6
+
7
+ def extract_from_x_up_ch_msisdn_http_request_header(http_request_info)
8
+ if msisdn = http_request_info.headers['X-Up-Ch-Msisdn'] and msisdn.length >= 8
9
+
10
+ country_code = (
11
+ MobileSubscriber::DIALING_COUNTRY_CODES[msisdn[0,2]] ||
12
+ MobileSubscriber::DIALING_COUNTRY_CODES[msisdn[0,3]]
13
+ )
14
+
15
+ # Determine the Network Operator tuple (MCC + MNC):
16
+ # TODO: Validate IP ranges, additional headers, etc.
17
+ network_id_tuple = case country_code
18
+ when 'BR' # Vivo Brazil:
19
+ # TODO: Determine (if possible) the MNC (06, 10, 11, 23)
20
+ { mcc: "724", mnc: "06" }
40
21
  end
41
22
 
23
+ # Return only if we identified the network:
24
+ if network_id_tuple.present?
25
+ {
26
+ id: msisdn,
27
+ mobile_country_code: network_id_tuple[:mcc],
28
+ mobile_network_code: network_id_tuple[:mnc],
29
+ http_request_info: http_request_info
30
+ }
31
+ end
42
32
  end
43
-
44
33
  end
45
34
  end
46
35
  end
@@ -1,48 +1,35 @@
1
1
  require 'mobile_subscriber/dictionaries/dialing_and_country_codes'
2
- module MobileSubscriber
3
- module Detection
4
-
5
- # Módulo que provee métodos de deteccion y validacion para MSISDN por el
6
- # header de HTTP 'Msisdn':
7
- # - Comcel Colombia
8
- module FromXUpSubnoHttpRequestHeader
9
-
10
- extend ActiveSupport::Concern
11
-
12
- module ClassMethods
13
- def extract_from_x_up_subno_http_request_header(request)
14
- header_name = 'X-Up-Subno'
15
- header_env_key = "HTTP_#{header_name.gsub('-','_').upcase}"
16
-
17
- isdn_attributes = nil
18
-
19
- isdn_attributes = if msisdn = request.env[header_env_key] and msisdn.strip.length >= 8
20
- msisdn.strip!
21
- detection_cues = {
22
- remote_ip: request.env["REMOTE_ADDR"],
23
- http_request_headers: { header_name => msisdn }
24
- }
25
-
26
- country_code = MobileSubscriber::DIALING_COUNTRY_CODES[msisdn[0,2]] || MobileSubscriber::DIALING_COUNTRY_CODES[msisdn[0,3]]
27
-
28
- # Determinar la procedencia del MSISDN
29
- # TODO: Validar por IP, etc.
30
- case country_code
31
- when 'CO'
32
- # Comcel Colombia
33
- {
34
- id: msisdn,
35
- mobile_country_code: "732",
36
- mobile_network_code: "101"
37
- }.merge(detection_cues: detection_cues)
38
- end
39
-
40
- end
2
+ module MobileSubscriber::Detection
3
+ # Módulo que provee métodos de deteccion y validacion para MSISDN por el
4
+ # header de HTTP 'Msisdn':
5
+ # - Comcel Colombia
6
+ module FromXUpSubnoHttpRequestHeader
7
+
8
+ def extract_from_x_up_subno_http_request_header(http_request_info)
9
+ if msisdn = http_request_info.headers['X-Up-Subno'] and msisdn.length >= 8
10
+
11
+ country_code = (
12
+ MobileSubscriber::DIALING_COUNTRY_CODES[msisdn[0,2]] ||
13
+ MobileSubscriber::DIALING_COUNTRY_CODES[msisdn[0,3]]
14
+ )
15
+
16
+ # Determine the Network Operator tuple (MCC + MNC):
17
+ # TODO: Validate IP ranges, additional headers, etc.
18
+ network_id_tuple = case country_code
19
+ when 'CO' # Comcel Colombia
20
+ { mcc: "732", mnc: "101" }
21
+ end
41
22
 
42
- isdn_attributes
23
+ # Return only if we identified the network:
24
+ if network_id_tuple.present?
25
+ {
26
+ id: msisdn,
27
+ mobile_country_code: network_id_tuple[:mcc],
28
+ mobile_network_code: network_id_tuple[:mnc],
29
+ http_request_info: http_request_info
30
+ }
43
31
  end
44
32
  end
45
-
46
33
  end
47
34
  end
48
35
  end
@@ -0,0 +1,39 @@
1
+ require 'mobile_subscriber/dictionaries/dialing_and_country_codes'
2
+
3
+ module MobileSubscriber::Detection
4
+ # Módulo que provee métodos de detección y validacion para MSISDN por el
5
+ # header de HTTP 'X-Wap-Sesiones3g-Mdn':
6
+ # - Iusacell
7
+ module FromXWapSesiones3gMdnHttpRequestHeader
8
+
9
+ def extract_from_x_wap_sesiones3g_mdn_http_request_header(http_request_info)
10
+ if msisdn = http_request_info.headers['X-Wap-Sesiones3g-Mdn'] and msisdn.length >= 8
11
+
12
+ country_code = (
13
+ MobileSubscriber::DIALING_COUNTRY_CODES[msisdn[0,2]] ||
14
+ MobileSubscriber::DIALING_COUNTRY_CODES[msisdn[0,3]]
15
+ )
16
+
17
+ # Determine the Network Operator tuple (MCC + MNC):
18
+ # TODO: Validate IP ranges, additional headers, etc.
19
+ network_id_tuple = case country_code
20
+ when 'MX' # Iusacell Mexico:
21
+ # TODO: Determine (if possible) the MNC:
22
+ # - MNC "040": Iusacell/Unefon
23
+ # - MNC "050": Iusacell
24
+ { mcc: "334", mnc: "040" }
25
+ end
26
+
27
+ # Return only if we identified the network:
28
+ if network_id_tuple.present?
29
+ {
30
+ id: msisdn,
31
+ mobile_country_code: network_id_tuple[:mcc],
32
+ mobile_network_code: network_id_tuple[:mnc],
33
+ http_request_info: http_request_info
34
+ }
35
+ end
36
+ end
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,75 @@
1
+ module MobileSubscriber::Detection
2
+ class HttpRequestInfo
3
+ attr_reader :remote_ip, :headers
4
+
5
+ def initialize(env)
6
+
7
+ @remote_ip = env['REMOTE_ADDR']
8
+
9
+ # Reference Links:
10
+ # - http://www.slideshare.net/DefCamp/mobile-networks-exploiting-http-headers-and-data-traffic
11
+ # - http://www.mulliner.org/collin/academic/publications/mobile_web_privacy_icin10_mulliner.pdf
12
+ @headers = [
13
+ # HTTP Headers that contain important request details for validation
14
+ 'Max-Forwards', # Para validar el número de forwards que el cliente permite... muy pobre..
15
+ 'Via',
16
+ 'X-Forwarded-For', # lista de IP's que originaron la petición, en caso de pasar por proxies:
17
+
18
+ # HTTP headers that contain the MSISDN:
19
+ # http://www.mulliner.org/collin/academic/publications/mobile_web_privacy_icin10_mulliner.pdf
20
+ 'Cookie',
21
+ 'Igcli',
22
+ 'Msisdn',
23
+ 'Rapmin',
24
+ 'X-Fh-Msisdn',
25
+ "X-H3-G-Msisdn",
26
+ 'X-Hts-Clid',
27
+ 'X-Jinny-Cid',
28
+ 'X-Msisdn',
29
+ 'X-Msp-Clid',
30
+ 'X-Msp-Msisdn',
31
+ 'X-Network-Info',
32
+ 'X-Nokia-Msisdn',
33
+ 'X-Nx-Clid',
34
+ 'X-Orange-Cli',
35
+ 'X-Up-Calling-Line',
36
+ 'X-Up-Calling-Line-Id', # Not in referenced literature
37
+ 'X-Up-Ch-Msisdn', # Not in referenced literature
38
+ 'X-Up-Lsid',
39
+ 'X-Up-Subno', # Not in referenced literature
40
+ 'X-Wap-Fh-Subscriber-Info',
41
+ 'X-Wap-Msisdn',
42
+ 'X-Wap-Sesiones3g-Mdn', # Not in referenced literature
43
+ 'X-Wsb-Cli',
44
+
45
+ # Headers that contain bearer information:
46
+ # http://www.mulliner.org/collin/academic/publications/mobile_web_privacy_icin10_mulliner.pdf
47
+ 'Bearer',
48
+ 'Bearer-Indication',
49
+ 'New-Bearer-Header',
50
+ 'Nokia-Bearer',
51
+ 'X-Nokia-Bearer',
52
+ 'X-Nokia-Musicshop-Bearer',
53
+ 'X-Up-Bear-Type', # NOT A TYPO
54
+ 'X-Up-Bearer-Type',
55
+ 'X-Bearer-Type',
56
+
57
+ # Headers that contain roaming information:
58
+ # http://www.mulliner.org/collin/academic/publications/mobile_web_privacy_icin10_mulliner.pdf
59
+ 'X-Orange-Roaming',
60
+ 'X-Nokia-Roaming',
61
+ 'X-Roaming',
62
+ 'X-Sdp-Roaming'
63
+ ].inject({}.with_indifferent_access) do |collected_headers, header_name|
64
+ header_env_key = "HTTP_#{header_name.gsub('-','_').upcase}"
65
+
66
+ if env.has_key? header_env_key
67
+ collected_headers[header_name] = env[header_env_key].strip
68
+ end
69
+
70
+ collected_headers
71
+ end
72
+
73
+ end
74
+ end
75
+ end
@@ -6,20 +6,20 @@ module MobileSubscriber
6
6
 
7
7
  class ISDN
8
8
 
9
- attr_reader :id, :mobile_country_code, :mobile_network_code, :detection_cues
9
+ attr_reader :id, :mobile_country_code, :mobile_network_code, :http_request_info
10
10
  alias_method :to_s, :id
11
11
 
12
- include MobileSubscriber::Detection::FromMsisdnHttpRequestHeader
13
- include MobileSubscriber::Detection::FromXNokiaMsisdnHttpRequestHeader
14
- include MobileSubscriber::Detection::FromXUpCallingLineIdHttpRequestHeader
15
- include MobileSubscriber::Detection::FromXUpChMsisdnHttpRequestHeader
16
- include MobileSubscriber::Detection::FromXUpSubnoHttpRequestHeader
12
+ extend MobileSubscriber::Detection::FromMsisdnHttpRequestHeader
13
+ extend MobileSubscriber::Detection::FromXNokiaMsisdnHttpRequestHeader
14
+ extend MobileSubscriber::Detection::FromXUpCallingLineIdHttpRequestHeader
15
+ extend MobileSubscriber::Detection::FromXUpChMsisdnHttpRequestHeader
16
+ extend MobileSubscriber::Detection::FromXUpSubnoHttpRequestHeader
17
17
 
18
18
  def initialize(attributes={})
19
19
  @id = attributes.delete :id
20
20
  @mobile_country_code = attributes.delete :mobile_country_code
21
21
  @mobile_network_code = attributes.delete :mobile_network_code
22
- @detection_cues = attributes.delete :detection_cues
22
+ @http_request_info = attributes.delete :http_request_info
23
23
  end
24
24
 
25
25
  def dialing_code
@@ -47,8 +47,6 @@ module MobileSubscriber
47
47
  end
48
48
  end
49
49
 
50
-
51
-
52
50
  def inspect
53
51
  "<MobileSubscriber::ISDN #{self.id} (#{self.http_validated? ? '' : 'not '}validated by HTTP)>"
54
52
  end
@@ -59,15 +57,19 @@ module MobileSubscriber
59
57
 
60
58
  # Creates a new MobileSubscriber::ISDN from a Rack::Request object
61
59
  def self.new_from_request(request)
62
- detected_attributes = self.methods.select do |x|
60
+ http_request_info = Detection::HttpRequestInfo.new request.env
61
+
62
+ detection_results = self.methods.select do |x|
63
63
  x.to_s =~ /\Aextract_from_(\w+)_http_request_header\z/i
64
- end.sort.reduce(nil) do |attrs, detection_method|
65
- attrs = self.send detection_method, request unless attrs.present?
66
- attrs
67
- end
64
+ end.map do |detection_method|
65
+ self.send detection_method, http_request_info
66
+ end.compact
67
+
68
+ # TODO: Select first from a preference order:
69
+ detection = detection_results.first if detection_results.any?
68
70
 
69
- if detected_attributes.present?
70
- validated_isdn = new(detected_attributes)
71
+ if detection.present?
72
+ validated_isdn = new(detection)
71
73
  validated_isdn.send :http_validated!
72
74
  validated_isdn
73
75
  end
@@ -1,3 +1,3 @@
1
1
  module MobileSubscriber
2
- VERSION = "0.0.1.alpha5"
2
+ VERSION = "0.0.1.beta1"
3
3
  end
@@ -2,16 +2,20 @@ require "spec_helper"
2
2
 
3
3
  describe MobileSubscriber::Detection::FromMsisdnHttpRequestHeader do
4
4
 
5
- include described_class::ClassMethods
5
+ include described_class
6
6
 
7
7
  let :test_request do
8
8
  build :mobile_request_from_claro_brasil
9
9
  end
10
10
 
11
+ let :test_request_info do
12
+ MobileSubscriber::Detection::HttpRequestInfo.new test_request.env
13
+ end
14
+
11
15
  describe "the returned object of self.extract_from_msisdn_http_request_header" do
12
16
 
13
17
  subject do
14
- extract_from_msisdn_http_request_header test_request
18
+ extract_from_msisdn_http_request_header test_request_info
15
19
  end
16
20
 
17
21
  context "when given a request made from Claro Brasil" do
@@ -53,7 +57,7 @@ describe MobileSubscriber::Detection::FromMsisdnHttpRequestHeader do
53
57
  expect(subject[:mobile_network_code]).to eq '01'
54
58
  end
55
59
  end
56
-
60
+
57
61
  end
58
62
 
59
63
  end
@@ -2,12 +2,16 @@ require "spec_helper"
2
2
 
3
3
  describe MobileSubscriber::Detection::FromXNokiaMsisdnHttpRequestHeader do
4
4
 
5
- include described_class::ClassMethods
5
+ include described_class
6
+
7
+ let :test_request_info do
8
+ MobileSubscriber::Detection::HttpRequestInfo.new test_request.env
9
+ end
6
10
 
7
11
  describe "the returned object of self.extract_from_msisdn_http_request_header" do
8
12
 
9
13
  subject do
10
- extract_from_x_nokia_msisdn_http_request_header test_request
14
+ extract_from_x_nokia_msisdn_http_request_header test_request_info
11
15
  end
12
16
 
13
17
  context "when given a request made from Telcel México" do
@@ -2,12 +2,16 @@ require "spec_helper"
2
2
 
3
3
  describe MobileSubscriber::Detection::FromXUpCallingLineIdHttpRequestHeader do
4
4
 
5
- include described_class::ClassMethods
5
+ include described_class
6
+
7
+ let :test_request_info do
8
+ MobileSubscriber::Detection::HttpRequestInfo.new test_request.env
9
+ end
6
10
 
7
11
  describe "the returned object of self.extract_from_msisdn_http_request_header" do
8
12
 
9
13
  subject do
10
- extract_from_x_up_calling_line_id_http_request_header test_request
14
+ extract_from_x_up_calling_line_id_http_request_header test_request_info
11
15
  end
12
16
 
13
17
  context "when given a request made from Claro Perú" do
@@ -0,0 +1,29 @@
1
+ require "spec_helper"
2
+
3
+ describe MobileSubscriber::Detection::FromXWapSesiones3gMdnHttpRequestHeader, focus: true do
4
+
5
+ include described_class
6
+
7
+ let :test_request_info do
8
+ MobileSubscriber::Detection::HttpRequestInfo.new test_request.env
9
+ end
10
+
11
+ describe "the returned object of self.extract_from_msisdn_http_request_header" do
12
+
13
+ subject do
14
+ extract_from_x_wap_sesiones3g_mdn_http_request_header test_request_info
15
+ end
16
+
17
+ context "when given a request made from Iusacell Mexico" do
18
+ let(:test_request) { build :mobile_request_from_iusacell_mexico }
19
+
20
+ include_examples "of detection of msisdn from a valid mexican mobile network http request"
21
+
22
+ it "has a :mobile_network_code value of '040' or '050'" do
23
+ expect(subject[:mobile_network_code]).to match /040|050/i
24
+ end
25
+ end
26
+
27
+ end
28
+
29
+ end
@@ -25,6 +25,15 @@ FactoryGirl.define do
25
25
  )
26
26
  end
27
27
 
28
+ factory :mobile_request_from_iusacell_mexico do
29
+ initialize_with do
30
+ new build(:common_mobile_request_env).merge(
31
+ "REMOTE_ADDR" => "201.144.162.4",
32
+ "HTTP_X_WAP_SESIONES3G_MDN" => "528110000000"
33
+ )
34
+ end
35
+ end
36
+
28
37
  factory :mobile_request_from_telcel_mexico do
29
38
  initialize_with do
30
39
  new build(:common_mobile_request_env).merge(
@@ -38,6 +38,10 @@ describe MobileSubscriber::ISDN do
38
38
  expect(subject).to respond_to :http_validated?
39
39
  end
40
40
 
41
+ it "responds to #http_request_info" do
42
+ expect(subject).to respond_to :http_request_info
43
+ end
44
+
41
45
  describe "detection from request headers" do
42
46
 
43
47
  shared_examples "of detection from a valid request" do
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: mobile-subscriber
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1.alpha5
4
+ version: 0.0.1.beta1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Roberto Quintanilla
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-01-07 00:00:00.000000000 Z
11
+ date: 2015-01-08 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport
@@ -118,6 +118,8 @@ files:
118
118
  - lib/mobile_subscriber/detection/from_x_up_calling_line_id_http_request_header.rb
119
119
  - lib/mobile_subscriber/detection/from_x_up_ch_msisdn_http_request_header.rb
120
120
  - lib/mobile_subscriber/detection/from_x_up_subno_http_request_header.rb
121
+ - lib/mobile_subscriber/detection/from_x_wap_sesiones3g_mdn_http_request_header.rb
122
+ - lib/mobile_subscriber/detection/http_request_info.rb
121
123
  - lib/mobile_subscriber/dictionaries/dialing_and_country_codes.rb
122
124
  - lib/mobile_subscriber/dictionaries/mobile_and_iso_country_codes.rb
123
125
  - lib/mobile_subscriber/dictionaries/operator_data.rb
@@ -128,6 +130,7 @@ files:
128
130
  - spec/detection/from_msisdn_http_request_header_spec.rb
129
131
  - spec/detection/from_x_nokia_msisdn_http_request_header_spec.rb
130
132
  - spec/detection/from_x_up_calling_line_id_http_request_header_spec.rb
133
+ - spec/detection/from_x_wap_sesiones3g_mdn_http_request_header_spec.rb
131
134
  - spec/factories/requests.rb
132
135
  - spec/mobile_subscriber_spec.rb
133
136
  - spec/models/isdn_spec.rb
@@ -163,6 +166,7 @@ test_files:
163
166
  - spec/detection/from_msisdn_http_request_header_spec.rb
164
167
  - spec/detection/from_x_nokia_msisdn_http_request_header_spec.rb
165
168
  - spec/detection/from_x_up_calling_line_id_http_request_header_spec.rb
169
+ - spec/detection/from_x_wap_sesiones3g_mdn_http_request_header_spec.rb
166
170
  - spec/factories/requests.rb
167
171
  - spec/mobile_subscriber_spec.rb
168
172
  - spec/models/isdn_spec.rb